Yes, so the problem is when exceptions are go through handler multiple times. This is not often case, but it could be happen. Apparently #on:fork: splits stack only once, and if you throw exception again it will go into exception handler, but no longer will find the sender context (since stack is cut).
So the fix is to check if it can find the context, and if not , just pass an exception to handler > onDoCtx ifNil: [ ^ ex pass ] ]. should be: > onDoCtx ifNil: [ ^ handlerAction cull: ex ] ]. So, a process will be forked only once (upon first exception received), and for next ones, it will simply pass exception to handler block (since you cannot fork anymore). I will add this to issue tracker On 28 June 2011 14:22, Cyrille Delaunay <[email protected]> wrote: > Igor this is the code you proposed: > on: exception fork: handlerAction > "Activate the receiver. In case of exception, fork a new process, which will > handle an error. > An original process will continue running as if receiver evaluation finished > and answered nil, > i.e., an expression like: > [ self error: 'some error'] on: Error fork: [:ex | 123 ] > will always answer nil for original process, not 123. > The context stack , starting from context which sent this message to > receiver and > up to the top of the stack will be transferred to forked process, with > handlerAction on top. > (so when forked process resuming, it will enter the handlerAction) > " > ^ self on: exception do: [:ex | > | copy onDoCtx process handler bottom thisCtx | > onDoCtx := thisContext. > thisCtx := onDoCtx home. > "find the context on stack for which this method's is sender" > [ onDoCtx sender == thisCtx] whileFalse: [ onDoCtx := onDoCtx sender. > onDoCtx ifNil: [ ^ ex pass ] ]. > bottom := [ Processor terminateActive ] asContext. > onDoCtx privSender: bottom. > handler := [ handlerAction cull: ex ] asContext. > handler privSender: thisContext sender. > (Process forContext: handler priority: Processor activePriority) resume. > "cut the stack of current process" > thisContext privSender: thisCtx. > nil > ] > > 2011/6/28 Igor Stasenko <[email protected]> >> >> On 28 June 2011 11:43, Cyrille Delaunay <[email protected]> wrote: >> > Ok, thank you henrik. >> > So I understand well that the announcement delivery handler will recast >> > in >> > new thread. The point I do not get (and maybe its obvious, sorry in >> > advance), is why does it raise an error ? >> > When I look at the debugger, it seems that at one moment in the on:fork: >> > method we got a 'context' that is nil whereas it should not. >> > It is quite to understand what is problem (As I do not have a lot of >> > knowledge around that) >> > >> What VM you using? >> Can you try running using other VM? >> >> > 2011/6/28 Henrik Johansen <[email protected]> >> >> >> >> On Jun 28, 2011, at 10:23 56AM, Cyrille Delaunay wrote: >> >> >> >> I got another issue related to that i think. >> >> In moose , at one moment in a announcement handling code, we are >> >> doing: Notification signal: 'Save successful!'. >> >> That has for consequence that the on:fork: cuts the stack and I end up >> >> with a 'MessageNotUnderstood: receiver of "sender" is nil'. >> >> So I don't know if the problem is that we are signaling a notification? >> >> >> >> Yes, if nothing inside the announcement handling code handles it, it >> >> will >> >> get handled by the announcement delivery handler which recasts it in >> >> new >> >> thread, for the reason Igor mentioned below. >> >> It's not safe to simply pass it on for handling by the code that made >> >> the >> >> announcement, if you want to ensure delivery. >> >> >> >> if yes what should we use to notify something ? >> >> >> >> ... an Announcement? >> >>> >> >>> It was because on:fork: cuts the stack. >> >>> If you signaling exception in your code, you should handle it before >> >>> leaving your #actionSelector method. >> >>> Otherwise you may put the rest recipients of announcement in danger >> >>> and that's why there #on:fork: to prevent that. >> >>> >> >>> >> >>> -- >> >>> Best regards, >> >>> Igor Stasenko AKA sig. >> >>> >> >> >> >> >> >> >> >> Cheers, >> >> Henry >> > >> >> >> >> -- >> Best regards, >> Igor Stasenko AKA sig. >> > > -- Best regards, Igor Stasenko AKA sig.
