Monitor>>critical: implementation

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Monitor>>critical: implementation

Denis Kudriashov
Hello.

Here is Monitor code:

critical: aBlock
   ^[
self enter.
aBlock value]
ensure: [self exit].

Now look at Semaphore comment and implementation:
 
We need to catch eventual interruptions very carefully.
The naive approach of just doing, e.g.,:
self wait.
aBlock ensure: [self signal].
will fail if the active process gets terminated while in the wait.  
However, the equally naive:
[self wait.
aBlock value] ensure: [self signal].
will fail too, since the active process may get interrupted while
entering the ensured block and leave the semaphore signaled twice.

critical: aBlock
| blockValue caught |
caught := false.
[
caught := true.
self wait.
blockValue := mutuallyExcludedBlock value
] ensure: [caught ifTrue: [self signal]].
^blockValue

So Monitor can be corrupted when process which enters critical section will be terminated. "Ensure block" can signal mutex which was not in waiting mode. Which means that next critical call in another Process will be not guarded.

What you think? Is my investigation right?

I look at users of Monitor. Most time it is used like Mutex. Only #critical: method is used. So Monitor can be replaced by Mutex at that places. And possible problem will be fixed.

SharedQueue is classic example for Monitor usage. Interesting is anybody got problems with it?
Reply | Threaded
Open this post in threaded view
|

Re: Monitor>>critical: implementation

Max Leske

On 05 Jan 2016, at 11:17, Denis Kudriashov <[hidden email]> wrote:

Hello.

Here is Monitor code:

critical: aBlock
   ^[
self enter.
aBlock value]
ensure: [self exit].

Now look at Semaphore comment and implementation:
 
We need to catch eventual interruptions very carefully.
The naive approach of just doing, e.g.,:
self wait.
aBlock ensure: [self signal].
will fail if the active process gets terminated while in the wait.  
However, the equally naive:
[self wait.
aBlock value] ensure: [self signal].
will fail too, since the active process may get interrupted while
entering the ensured block and leave the semaphore signaled twice.

critical: aBlock
| blockValue caught |
caught := false.
[
caught := true.
self wait.
blockValue := mutuallyExcludedBlock value
] ensure: [caught ifTrue: [self signal]].
^blockValue

So Monitor can be corrupted when process which enters critical section will be terminated. "Ensure block" can signal mutex which was not in waiting mode. Which means that next critical call in another Process will be not guarded.

What you think? Is my investigation right?

I look at users of Monitor. Most time it is used like Mutex. Only #critical: method is used. So Monitor can be replaced by Mutex at that places. And possible problem will be fixed.

SharedQueue is classic example for Monitor usage. Interesting is anybody got problems with it?


You may have a point there. Although the monitor uses a Semaphore #forMutualExclusion, which is a semaphore with one signal. So the case where the semaphore gets signalled without #wait is less likely I think.

What I don’t quite understand is why Monitor doesn’t use Semaphore>>critical:. If it did that, then there wouldn’t be a problem. The problem only exists because #wait and #signal are explicitly sent by the monitor.

Reply | Threaded
Open this post in threaded view
|

Re: Monitor>>critical: implementation

Denis Kudriashov

2016-01-05 12:59 GMT+01:00 Max Leske <[hidden email]>:
You may have a point there. Although the monitor uses a Semaphore #forMutualExclusion, which is a semaphore with one signal. So the case where the semaphore gets signalled without #wait is less likely I think.

No. It has no relation to incorrect scenarios of semaphore signalling.
#forMutualExclusion just make semaphore free to use. So first caller of #wait will grab lock. And others will wait. 
Two times signalled semaphore will allow two critical sections be performed simultaneously which should not happen

Reply | Threaded
Open this post in threaded view
|

Re: Monitor>>critical: implementation

Max Leske

On 05 Jan 2016, at 13:23, Denis Kudriashov <[hidden email]> wrote:


2016-01-05 12:59 GMT+01:00 Max Leske <[hidden email]>:
You may have a point there. Although the monitor uses a Semaphore #forMutualExclusion, which is a semaphore with one signal. So the case where the semaphore gets signalled without #wait is less likely I think.

No. It has no relation to incorrect scenarios of semaphore signalling.
#forMutualExclusion just make semaphore free to use. So first caller of #wait will grab lock. And others will wait. 
Two times signalled semaphore will allow two critical sections be performed simultaneously which should not happen

True



Reply | Threaded
Open this post in threaded view
|

Re: Monitor>>critical: implementation

Denis Kudriashov
In reply to this post by Max Leske

2016-01-05 12:59 GMT+01:00 Max Leske <[hidden email]>:
What I don’t quite understand is why Monitor doesn’t use Semaphore>>critical:. If it did that, then there wouldn’t be a problem. The problem only exists because #wait and #signal are explicitly sent by the monitor.

Monitor is reentral which means that two recursive critical sections in same process should not be blocked. This logic implemented in #enter and #exit methods

Reply | Threaded
Open this post in threaded view
|

Re: Monitor>>critical: implementation

Max Leske

On 05 Jan 2016, at 13:29, Denis Kudriashov <[hidden email]> wrote:


2016-01-05 12:59 GMT+01:00 Max Leske <[hidden email]>:
What I don’t quite understand is why Monitor doesn’t use Semaphore>>critical:. If it did that, then there wouldn’t be a problem. The problem only exists because #wait and #signal are explicitly sent by the monitor.

Monitor is reentral which means that two recursive critical sections in same process should not be blocked. This logic implemented in #enter and #exit methods


I should start using my head again. This is a new year… :)

Thanks Denis.

Reply | Threaded
Open this post in threaded view
|

Re: Monitor>>critical: implementation

Denis Kudriashov

:)

5 янв. 2016 г. 2:18 PM пользователь "Max Leske" <[hidden email]> написал:

On 05 Jan 2016, at 13:29, Denis Kudriashov <[hidden email]> wrote:


2016-01-05 12:59 GMT+01:00 Max Leske <[hidden email]>:
What I don’t quite understand is why Monitor doesn’t use Semaphore>>critical:. If it did that, then there wouldn’t be a problem. The problem only exists because #wait and #signal are explicitly sent by the monitor.

Monitor is reentral which means that two recursive critical sections in same process should not be blocked. This logic implemented in #enter and #exit methods


I should start using my head again. This is a new year… :)

Thanks Denis.