@@ -23,18 +23,19 @@ enum BufferState {
23
23
* the buffer to this state so that it can use `Atomics.wait()` to be notified
24
24
* when it switches to `MessageSent`.
25
25
*/
26
- AwaitingMessage ,
26
+ AwaitingMessage = 0b00 ,
27
27
/**
28
28
* The state indicating that a message has been sent. Whenever an endpoint
29
29
* sends a message, it'll set the buffer to this state so that the other
30
30
* endpoint's `Atomics.wait()` call terminates.
31
31
*/
32
- MessageSent ,
32
+ MessageSent = 0b01 ,
33
33
/**
34
- * The state indicating that the channel has been closed. This never
35
- * transitions to any other states.
34
+ * The bitmask indicating that the channel has been closed. This is masked on
35
+ * top of AwaitingMessage and MessageSent state. It never transitions to any
36
+ * other states once closed.
36
37
*/
37
- Closed ,
38
+ Closed = 0b10 ,
38
39
}
39
40
40
41
/**
@@ -158,13 +159,16 @@ export class SyncMessagePort extends EventEmitter {
158
159
message = receiveMessageOnPort ( this . port ) ;
159
160
if ( message ) return message . message ;
160
161
161
- assert . equal ( Atomics . load ( this . buffer , 0 ) , BufferState . Closed ) ;
162
+ // Update the state to 0b10 after the last message is consumed.
163
+ const oldState = Atomics . and ( this . buffer , 0 , BufferState . Closed ) ;
164
+ // Assert the old state was either 0b10 or 0b11.
165
+ assert . equal ( oldState & BufferState . Closed , BufferState . Closed ) ;
162
166
throw new Error ( "The SyncMessagePort's channel is closed." ) ;
163
167
}
164
168
165
169
/** See `MessagePort.close()`. */
166
170
close ( ) : void {
167
- Atomics . store ( this . buffer , 0 , BufferState . Closed ) ;
171
+ Atomics . or ( this . buffer , 0 , BufferState . Closed ) ;
168
172
this . port . close ( ) ;
169
173
}
170
174
}
0 commit comments