On 05 Jan 2016, at 5:10 , Denis Kudriashov <dionisiydk@gmail.com> wrote:


2016-01-05 16:54 GMT+01:00 Denis Kudriashov <dionisiydk@gmail.com>:
2016-01-05 16:06 GMT+01:00 Ben Coman <btc@openinworld.com>:
This is really strange!  Why does the copied class Semaphore2 behave
differently to the original class Semaphore? This was in build 50510.

It is so frustrating.
I add tests for your cases which is red now. And one for Semaphore (inside ReadWriteLockTests) which is green

It is really crazy. I just try two experiments:
1) I move semaphore critical: logic to Mutex. Our test with mutex become red.
2) I copy Semaphore>>critical: to #critical2:. And with it Semaphore test become red. 

So somebody definitely know about #critical: selector and it receiver

Yes, check Process >> #terminate, there's special code for skipping a context if the suspended process was waiting for Semaphore.

The way I see it, the purpose of the caught variable in Semaphore is to not execute the ensure: if the process was suspended (and then terminated)*in* the ensure: method, before block ever executes and one starts waiting on the semaphore. 

If one has made it to the wait call, caught is already true, and the ensure block would be executed on termination unwind..
That part is, as I said above, handled directly in Process >> #terminate (near the bottom)
AFAICT, both parts would be need to be reflected for Monitor >> #critical: to work correctly under termination.
At which point, it would seem to me a better idea (if possible) if the terminated  context was culled into the ensure block, instead of muddying up Process >> #terminate further, one could then write a few ugly, but localized:
ensure: [:unwoundContext | (caught and: [unwoundContext isWaitContext notl]) ifTrue: [sem signal]]
instead of  having to keep adding special case handling to Process >> #terminate.

Cheers,
Henry