@@ -107,35 +107,34 @@ Monitor >> critical: aBlock [
107107 in a critical section.
108108 NOTE: All the following synchronization operations are only valid inside the critical section
109109 of the monitor!"
110- | requestingProcess blockValue caught |
110+ | requestingProcess caught |
111111
112112 requestingProcess := Processor activeProcess.
113113 caught := false .
114- [
115- " See Semaphore>>critical: for a description of the structure of the code below."
114+ ^ [ " See Semaphore>>critical: for a description of the structure of the code below."
116115 requestingProcess == ownerProcess ifTrue: [
117116 " Don't move the caught assignment outside the ifTrue:ifFalse, see below"
118117 caught := true .
119118 nestingLevel := nestingLevel + 1 .
120119 ] ifFalse: [
121- " Set caught immediately before the mutex wait to ensure the process isn't interrupted"
120+ " Only one process should be able to enter the critical: section at a time,
121+ however there is obviously a window where terminating a process can allow two
122+ processes in at the same time.
123+ Protect against this by rewaiting if someone else owns the monitor."
124+ [ " Set caught immediately before the mutex wait to ensure both are executed as an atomic operation"
122125 caught := true .
123- mutex wait.
126+ mutex wait] doWhileFalse: [ ownerProcess isNil ] .
124127 ownerProcess := requestingProcess.
125- nestingLevel := 1 .
126- ].
127-
128- " The critical section is only exited if:
129- 1. the ensured block was entered (caught), and
130- 2. the process exiting was the owning process
131- If the process being terminted was waiting on the monitor and there is no
132- current owner, the mutex needs to be signalled to reestablish the excess signal."
133- blockValue := aBlock value ] ensure :
128+ nestingLevel := 1 . ].
129+ aBlock value ] ensure :
130+ " The critical section is only exited if:
131+ 1. the ensured block was entered (caught), and
132+ 2. the process exiting was the owning process
133+ If the process being terminted was waiting on the monitor (caught) and there is no
134+ current owner, the mutex needs to be signalled to reestablish the excess signal."
134135 [ caught ifTrue: [ requestingProcess == ownerProcess
135136 ifTrue: [ self exit ]
136- ifFalse: [ (ownerProcess == nil and : [ nestingLevel = 0 ])
137- ifTrue: [ mutex signal ] ] ] ].
138- ^ blockValue
137+ ifFalse: [ ownerProcess ifNil: [ mutex signal ] ] ] ].
139138]
140139
141140{ #category : ' private' }
0 commit comments