@@ -107,35 +107,34 @@ Monitor >> critical: aBlock [
107
107
in a critical section.
108
108
NOTE: All the following synchronization operations are only valid inside the critical section
109
109
of the monitor!"
110
- | requestingProcess blockValue caught |
110
+ | requestingProcess caught |
111
111
112
112
requestingProcess := Processor activeProcess.
113
113
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."
116
115
requestingProcess == ownerProcess ifTrue: [
117
116
" Don't move the caught assignment outside the ifTrue:ifFalse, see below"
118
117
caught := true .
119
118
nestingLevel := nestingLevel + 1 .
120
119
] 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"
122
125
caught := true .
123
- mutex wait.
126
+ mutex wait] doWhileFalse: [ ownerProcess isNil ] .
124
127
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."
134
135
[ caught ifTrue: [ requestingProcess == ownerProcess
135
136
ifTrue: [ self exit ]
136
- ifFalse: [ (ownerProcess == nil and : [ nestingLevel = 0 ])
137
- ifTrue: [ mutex signal ] ] ] ].
138
- ^ blockValue
137
+ ifFalse: [ ownerProcess ifNil: [ mutex signal ] ] ] ].
139
138
]
140
139
141
140
{ #category : ' private' }
0 commit comments