Just for reference, in my case I can reproduce it only because I trick the simulation into thinking that the process I’m working with is not the active process. Here’s a test case that reproduces the problem (the process context will be in the handler at the end):
testIsTerminatingForcedTermination | process started unwound terminator | process := [ started := true. [ process terminate ] ensure: [ terminator := Processor activeProcess. unwound := true ] ] newProcess. "Because we're simulating, we need to trick the simulation to get into the code for not running processes." [ process suspendedContext selector = #isActiveProcess ] whileFalse: [ process step ]. process popTo: process suspendedContext sender value: false. "Again, trick the simulation into thinking the process is suspended." [ process suspendedContext selector = #popTo: ] whileFalse: [ process step ]. [ process suspendedContext selector = #activeProcess ] whileFalse: [ process step ]. process popTo: process suspendedContext sender value: false. process completeTo: process suspendedContext bottomContext On 23.09.2014, at 19:53, Martin McClure <mar...@hand2mouse.com> wrote: > On 09/23/2014 08:48 AM, Clément Bera wrote: >> The theory I've had for a while for this issue is that ensure blocks are >> sometimes not executed when the process is manipulated / terminated from >> another process (so topContext was not assigned even if in an ensure >> block). I've tried to fix it but I failed. > > VW had a long-standing bug (finally fixed some time ago) that when a > process was terminated, any unwind blocks that had already started would > not finish. This caused us all kinds of grief -- most commonly stuck > semaphores due to #critical: blocks not signaling the semaphore. > > I haven't had time to look into whether Pharo has the same problem, but > in my reading through the Exceptions chapter of "Deep into Pharo" it > looked like that problem was probably in Pharo, too. > > I believe that the "correct" (most desirable) behavior for unwind blocks > when the process is terminated is that > > 1) Any unwind blocks that are on the stack but have not yet started > evaluation should be run, in order, before the process finally terminates. > > 2) Any unwind blocks that are in the process of being evaluated should > be allowed to finish before proceeding with step 1. > > 3) Any unwind block that, at any point in its evaluation, signals an > exception, should have a handler for that exception in some context > within its own evaluation. Any unwind block that signals an exception > which it does not handle has given up the right to its own normal > completion, and process termination is free to skip the rest of that > unwind block. > > Behavior 1) I believe we already do. We probably also do 3), more or > less. I have my doubts about 2). > > Regards, > > -Martin >