Coroutines and exceptions

Daniel Keep daniel.keep.lists at gmail.com
Tue May 2 20:05:27 PDT 2006


Cool; thanks for that.  Guess I'll have some reading to do when I get
home :)

	-- Daniel

mclysenk at mtu.edu wrote:
> In article <e2vh64$2vhe$1 at digitaldaemon.com>, Lars Ivar Igesund says...
>> Daniel Keep wrote:
>>
>>> Hi.
>>>
>>> I've been playing around with an implementation of coroutines in D the
>>> last day or two, and I've got it to the point where it works pretty well
>>> under gdc, and under dmd with a few bugs to track down.  But I've hit a
>>> brick will with exceptions.
>>>
>>> See, I was kinda hoping that D found exception handlers by going back up
>>> the stack frames... although after pouring over the disassembly in gdb,
>>> it looks like D registers the exception handlers as it meets them.
>>>
>>> The problem with this is that the coroutine library allows you to jump
>>> from one part of the code to another, which ends up screwing up the
>>> order of exception handlers.  For example (simplified, mind you):
>>>
>>> void coro_a()
>>> {
>>>     try
>>>     {
>>>     co_call(main); // Jump back into main just after co_call
>>>     }
>>>     except( Exception e )
>>>     {
>>>         writefln("Exception in coro_a: %s", e.toString());
>>>     }
>>> }
>>>
>>> void main()
>>> {
>>>     try
>>>     {
>>>         co_call(coro_a); // Jump into coro_a
>>>         throw new Exception("Oh noes!");
>>>     }
>>>     catch( Exception e )
>>>     {
>>>         writefln("Exception in main: %s", e.toString());
>>>     }
>>> }
>>>
>>> If you run that, you end up getting "Exception in coro_a: Oh noes!"
>>> instead of "Exception in main: Oh noes!" as you would expect.
>> I have been working on getting Mikola Lysenko's StackThread working on
>> Linux, and I just tested the exception handling (which I did not have to do
>> anything with, it just worked the way he had implemented it. Unless this
>> way is not what you want, and your couroutines might not be altogether the
>> same thing as this StackThread (I tried to send you a mail, but don't know
>> if it will reach you...). Anyway, the test code goes like this (in the
>> unittest):
>>
>>
>> try {
>>    void exceptions()
>>    {
>>        writefln("Testing exception handling...");
>>        throw new Exception(std.string.format("Test exception, line %s",
>> __LINE__));
>>        StackThread.yield();
>>    }
>>
>>    StackThread t = new StackThread(&exceptions);
>>    t.resume();
>>    StackThread.run();
>>
>>    assert(false);
>> }
>> catch(Exception e)
>> {
>>    writefln(e);
>> }
>>
>> And the result is this:
>>
>> Testing exception handling...
>> Test exception, line 412
>>
>> The assert is not triggered.
>>
>> I do agree that your result seems somewhat strange, though...
>>
>> -- 
>> Lars Ivar Igesund
>> blog at http://larsivi.net
>> DSource & #D: larsivi
> 
> That is because on windows you need to save the stack top & bottom when you
> change contexts.  They are stored at FS[4] and FS[8].  Also it would be a good
> idea to relink the SEH chain when you create a new coroutine, so the top level
> is tied to the SEH that originally called the coroutine.  As far as I can tell,
> this behaviour is not very well documented, but for more info on structured
> exception handling, you can check out
> http://www.microsoft.com/msj/0197/exception/exception.aspx .
> 
> I'm currently working on extending the StackThread system to support priority
> based scheduling and Linux.  At the moment, I have a specification drawn up,
> along with a basic architecture/implementation.
> 
> -Mikola Lysenko
> 
> 

-- 

v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D
a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP    http://hackerkey.com/



More information about the Digitalmars-d mailing list