| // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| import "dart:isolate"; | |
| import "dart:async"; | |
| import "package:expect/async_helper.dart"; | |
| void isomain(SendPort replyPort) { | |
| RawReceivePort port = new RawReceivePort(); | |
| port.handler = (v) { | |
| if (v == 0) { | |
| // Shut down when receiving the 0 message. | |
| port.close(); | |
| } else { | |
| replyPort.send(v); | |
| } | |
| }; | |
| replyPort.send(port.sendPort); | |
| } | |
| void main() { | |
| testExit(); | |
| testCancelExit(); | |
| testOverrideResponse(); | |
| } | |
| void testExit() { | |
| bool mayComplete = false; | |
| asyncStart(); | |
| var completer = new Completer(); // Completed by first reply from isolate. | |
| RawReceivePort reply = new RawReceivePort(completer.complete); | |
| late RawReceivePort onExitPort; | |
| onExitPort = new RawReceivePort((v) { | |
| if (v != "RESPONSE") throw "WRONG RESPONSE: $v"; | |
| reply.close(); | |
| onExitPort.close(); | |
| if (!mayComplete) throw "COMPLETED EARLY"; | |
| asyncEnd(); | |
| }); | |
| Isolate.spawn(isomain, reply.sendPort) | |
| .then((Isolate isolate) { | |
| isolate.addOnExitListener(onExitPort.sendPort, response: "RESPONSE"); | |
| return completer.future; | |
| }) | |
| .then((echoPort) { | |
| int counter = 4; | |
| reply.handler = (v) { | |
| if (v != counter) throw "WRONG REPLY"; | |
| if (v == 0) throw "REPLY INSTEAD OF SHUTDOWN"; | |
| counter--; | |
| mayComplete = (counter == 0); | |
| echoPort.send(counter); | |
| }; | |
| echoPort.send(counter); | |
| }); | |
| } | |
| void testCancelExit() { | |
| bool mayComplete = false; | |
| asyncStart(); | |
| var completer = new Completer(); // Completed by first reply from isolate. | |
| RawReceivePort reply = new RawReceivePort(completer.complete); | |
| RawReceivePort onExitPort2 = new RawReceivePort((_) { | |
| throw "RECEIVED EXIT MESSAGE"; | |
| }); | |
| late RawReceivePort onExitPort1; | |
| onExitPort1 = new RawReceivePort((_) { | |
| reply.close(); | |
| onExitPort1.close(); | |
| if (!mayComplete) throw "COMPLETED EARLY"; | |
| new Timer(const Duration(milliseconds: 0), () { | |
| onExitPort2.close(); | |
| asyncEnd(); | |
| }); | |
| }); | |
| Isolate.spawn(isomain, reply.sendPort).then((Isolate isolate) { | |
| isolate.addOnExitListener(onExitPort2.sendPort); | |
| isolate.addOnExitListener(onExitPort1.sendPort); | |
| return completer.future.then((echoPort) { | |
| int counter = 4; | |
| reply.handler = (v) { | |
| if (v != counter) throw "WRONG REPLY"; | |
| if (v == 0) throw "REPLY INSTEAD OF SHUTDOWN"; | |
| counter--; | |
| mayComplete = (counter == 0); | |
| if (counter == 1) { | |
| // Remove listener 2, keep listener 1. | |
| isolate.removeOnExitListener(onExitPort2.sendPort); | |
| } | |
| echoPort.send(counter); | |
| }; | |
| echoPort.send(counter); | |
| }); | |
| }); | |
| } | |
| void testOverrideResponse() { | |
| bool mayComplete = false; | |
| asyncStart(); | |
| var completer = new Completer(); // Completed by first reply from isolate. | |
| RawReceivePort reply = new RawReceivePort(completer.complete); | |
| late RawReceivePort onExitPort; | |
| onExitPort = new RawReceivePort((v) { | |
| if (v != "RESPONSE2") throw "WRONG RESPONSE: $v"; | |
| reply.close(); | |
| onExitPort.close(); | |
| if (!mayComplete) throw "COMPLETED EARLY"; | |
| asyncEnd(); | |
| }); | |
| Isolate.spawn(isomain, reply.sendPort) | |
| .then((Isolate isolate) { | |
| isolate.addOnExitListener(onExitPort.sendPort, response: "RESPONSE"); | |
| isolate.addOnExitListener(onExitPort.sendPort, response: "RESPONSE2"); | |
| return completer.future; | |
| }) | |
| .then((echoPort) { | |
| int counter = 4; | |
| reply.handler = (v) { | |
| if (v != counter) throw "WRONG REPLY"; | |
| if (v == 0) throw "REPLY INSTEAD OF SHUTDOWN"; | |
| counter--; | |
| mayComplete = (counter == 0); | |
| echoPort.send(counter); | |
| }; | |
| echoPort.send(counter); | |
| }); | |
| } |