Skip to content

Commit 7063dd2

Browse files
committed
Use a separate byte to send exitCode
1 parent 5a1af87 commit 7063dd2

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

lib/src/embedded/compilation_dispatcher.dart

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -408,20 +408,24 @@ final class CompilationDispatcher {
408408
var protobufWriter = CodedBufferWriter();
409409
message.writeToCodedBufferWriter(protobufWriter);
410410

411-
// Add one additional byte to the beginning to indicate whether or not the
412-
// compilation has finished (1) or encountered a fatal error (exitCode), so
413-
// the [IsolateDispatcher] knows whether to treat this isolate as inactive
414-
// or close out entirely.
411+
// Add two bytes to the beginning.
412+
//
413+
// The first byte indicates whether or not the compilation has finished (1)
414+
// or encountered a fatal error (2), so the [WorkerDispatcher] knows
415+
// whether to treat this isolate as inactive or close out entirely.
416+
//
417+
// The second byte is the exitCode when a fatal error occurs.
415418
var packet = Uint8List(
416-
1 + _compilationIdVarint.length + protobufWriter.lengthInBytes,
419+
2 + _compilationIdVarint.length + protobufWriter.lengthInBytes,
417420
);
418421
packet[0] = switch (message.whichMessage()) {
422+
OutboundMessage_Message.error => 2,
419423
OutboundMessage_Message.compileResponse => 1,
420-
OutboundMessage_Message.error => exitCode,
421424
_ => 0
422425
};
423-
packet.setAll(1, _compilationIdVarint);
424-
protobufWriter.writeTo(packet, 1 + _compilationIdVarint.length);
426+
packet[1] = exitCode;
427+
packet.setAll(2, _compilationIdVarint);
428+
protobufWriter.writeTo(packet, 2 + _compilationIdVarint.length);
425429
return packet;
426430
}
427431

lib/src/embedded/worker_dispatcher.dart

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,14 @@ class WorkerDispatcher {
142142
var fullBuffer = message as Uint8List;
143143

144144
// The first byte of messages from workers indicates whether the entire
145-
// compilation is finished (1) or if it encountered an error (exitCode).
145+
// compilation is finished (1) or if it encountered an error (2).
146146
// Sending this as part of the message buffer rather than a separate
147147
// message avoids a race condition where the host might send a new
148148
// compilation request with the same ID as one that just finished before
149149
// the [WorkerDispatcher] receives word that the worker with that ID is
150150
// done. See sass/dart-sass#2004.
151151
var category = fullBuffer[0];
152-
var packet = Uint8List.sublistView(fullBuffer, 1);
152+
var packet = Uint8List.sublistView(fullBuffer, 2);
153153

154154
switch (category) {
155155
case 0:
@@ -160,9 +160,18 @@ class WorkerDispatcher {
160160
_inactiveWorkers.add(worker);
161161
resource.release();
162162
_channel.sink.add(packet);
163-
default:
163+
case 2:
164164
_channel.sink.add(packet);
165-
exitCode = category;
165+
// The second byte of message is the exitCode when fatal error
166+
// occurs. This is needed because in Node.js process.exitCode
167+
// is thread local, so that we need to pass it from the worker
168+
// thread back to main thread. Using onexit event to retrieve
169+
// the exitCode is unrelibale because worker.kill() might get
170+
// triggered from main thread before the worker thread finish
171+
// exit itself, in which case onexit event will recevie an exit
172+
// code 1 regardless of actual process.exitCode value in worker
173+
// thread.
174+
exitCode = fullBuffer[1];
166175
if (_gracefulShutdown) {
167176
_channel.sink.close();
168177
} else {

0 commit comments

Comments
 (0)