@@ -158,19 +158,27 @@ class IsolateDispatcher {
158
158
var receivePort = ReceivePort ();
159
159
isolate.sink.add ((receivePort.sendPort, compilationId));
160
160
161
- var channel = IsolateChannel <Uint8List ?>.connectReceive (receivePort)
162
- .transform (const ExplicitCloseTransformer ());
163
- channel.stream.listen (_channel.sink.add,
161
+ var channel = IsolateChannel <Uint8List >.connectReceive (receivePort);
162
+ channel.stream.listen (
163
+ (message) {
164
+ // The first byte of messages from isolates indicates whether the
165
+ // entire compilation is finished. Sending this as part of the message
166
+ // buffer rather than a separate message avoids a race condition where
167
+ // the host might send a new compilation request with the same ID as
168
+ // one that just finished before the [IsolateDispatcher] receives word
169
+ // that the isolate with that ID is done. See sass/dart-sass#2004.
170
+ if (message[0 ] == 1 ) {
171
+ channel.sink.close ();
172
+ _activeIsolates.remove (compilationId);
173
+ _inactiveIsolates.add (isolate);
174
+ resource.release ();
175
+ }
176
+ _channel.sink.add (Uint8List .sublistView (message, 1 ));
177
+ },
164
178
onError: (Object error, StackTrace stackTrace) =>
165
179
_handleError (error, stackTrace),
166
180
onDone: () {
167
- _activeIsolates.remove (compilationId);
168
- if (_closed) {
169
- isolate.sink.close ();
170
- } else {
171
- _inactiveIsolates.add (isolate);
172
- }
173
- resource.release ();
181
+ if (_closed) isolate.sink.close ();
174
182
});
175
183
_activeIsolates[compilationId] = channel.sink;
176
184
return channel.sink;
@@ -228,8 +236,7 @@ void _isolateMain(SendPort sendPort) {
228
236
channel.stream.listen ((initialMessage) async {
229
237
var (compilationSendPort, compilationId) = initialMessage;
230
238
var compilationChannel =
231
- IsolateChannel <Uint8List ?>.connectSend (compilationSendPort)
232
- .transform (const ExplicitCloseTransformer ());
239
+ IsolateChannel <Uint8List >.connectSend (compilationSendPort);
233
240
var success = await Dispatcher (compilationChannel, compilationId).listen ();
234
241
if (! success) channel.sink.close ();
235
242
});
0 commit comments