I found problem. Look at Process>>terminate. There is special place:

"Figure out if we are terminating the process while waiting in Semaphore>>critical:
In this case, pop the suspendedContext so that we leave the ensure: block inside
Semaphore>>critical: without signaling the semaphore."
(oldList class == Semaphore and: [
self halt.
suspendedContext method == (Semaphore compiledMethodAt: #critical:) ]) ifTrue: [
suspendedContext := suspendedContext home ].

Really crazy. Comment inside #critical: method said that we should signal in any case. But #terminate method said that we should not allow signalling in that case.��
Why it is not implemented inside #critical: method by #ifCurtailed: logic?��


2016-01-05 17:10 GMT+01:00 Denis Kudriashov <dionisiydk@gmail.com>:

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