33// https://opensource.org/licenses/MIT.
44
55import 'dart:async' ;
6- import 'dart:ffi' ;
7- import 'dart:io' ;
8- import 'dart:isolate' ;
96import 'dart:typed_data' ;
107
11- import 'package:native_synchronization/mailbox.dart' ;
128import 'package:pool/pool.dart' ;
139import 'package:protobuf/protobuf.dart' ;
1410import 'package:stream_channel/stream_channel.dart' ;
1511
16- import 'compilation_dispatcher .dart' ;
12+ import 'concurrency.dart' if (dart.library.js) 'js/concurrency .dart' ;
1713import 'embedded_sass.pb.dart' ;
18- import 'reusable_isolate.dart' ;
14+ import 'isolate_main.dart' ;
15+ import 'reusable_isolate.dart' if (dart.library.js) 'js/reusable_isolate.dart' ;
1916import 'util/proto_extensions.dart' ;
2017import 'utils.dart' ;
2118
@@ -25,6 +22,9 @@ class IsolateDispatcher {
2522 /// The channel of encoded protocol buffers, connected to the host.
2623 final StreamChannel <Uint8List > _channel;
2724
25+ /// The callback which is called when fatal error occurs.
26+ final void Function () _onError;
27+
2828 /// All isolates that have been spawned to dispatch to.
2929 ///
3030 /// Only used for cleaning up the process when the underlying channel closes.
@@ -38,16 +38,12 @@ class IsolateDispatcher {
3838
3939 /// A pool controlling how many isolates (and thus concurrent compilations)
4040 /// may be live at once.
41- ///
42- /// More than MaxMutatorThreadCount isolates in the same isolate group
43- /// can deadlock the Dart VM.
44- /// See https://github.com/sass/dart-sass/pull/2019
45- final _isolatePool = Pool (sizeOf <IntPtr >() <= 4 ? 7 : 15 );
41+ final _isolatePool = Pool (concurrencyLimit);
4642
4743 /// Whether [_channel] has been closed or not.
4844 var _closed = false ;
4945
50- IsolateDispatcher (this ._channel);
46+ IsolateDispatcher (this ._channel, this ._onError );
5147
5248 void listen () {
5349 _channel.stream.listen ((packet) async {
@@ -112,7 +108,7 @@ class IsolateDispatcher {
112108 isolate = _inactiveIsolates.first;
113109 _inactiveIsolates.remove (isolate);
114110 } else {
115- var future = ReusableIsolate .spawn (_isolateMain ,
111+ var future = ReusableIsolate .spawn (isolateMain ,
116112 onError: (Object error, StackTrace stackTrace) {
117113 _handleError (error, stackTrace);
118114 });
@@ -144,7 +140,7 @@ class IsolateDispatcher {
144140 _channel.sink.add (packet);
145141 case 2 :
146142 _channel.sink.add (packet);
147- exit (exitCode );
143+ _onError ( );
148144 }
149145 });
150146
@@ -168,7 +164,7 @@ class IsolateDispatcher {
168164 {int ? compilationId, int ? messageId}) {
169165 sendError (compilationId ?? errorId,
170166 handleError (error, stackTrace, messageId: messageId));
171- _channel.sink. close ();
167+ _onError ();
172168 }
173169
174170 /// Sends [message] to the host.
@@ -179,7 +175,3 @@ class IsolateDispatcher {
179175 void sendError (int compilationId, ProtocolError error) =>
180176 _send (compilationId, OutboundMessage ()..error = error);
181177}
182-
183- void _isolateMain (Mailbox mailbox, SendPort sendPort) {
184- CompilationDispatcher (mailbox, sendPort).listen ();
185- }
0 commit comments