Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(571)

Unified Diff: sdk/lib/_internal/lib/isolate_helper.dart

Issue 190013005: Add Isolate.kill(). (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Changed naming and meaning of priorities Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | sdk/lib/isolate/isolate.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/lib/isolate_helper.dart
diff --git a/sdk/lib/_internal/lib/isolate_helper.dart b/sdk/lib/_internal/lib/isolate_helper.dart
index 8a19dc68f8ec115055d8fa9849269fa69506318b..fa8cfacb6c89a6dd7868cf2987bbcc3e42f990de 100644
--- a/sdk/lib/_internal/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/lib/isolate_helper.dart
@@ -280,6 +280,15 @@ class _IsolateContext implements IsolateContext {
// Container with the "on exit" handler send-ports.
var doneHandlers;
+ /**
+ * Queue of functions to call when the current event is complete.
+ *
+ * These events are not just put at the front of the event queue, because
+ * they represent control messages, and should be handled even if the
+ * event queue is paused.
+ */
+ var _scheduledControlEvents;
+
/** Whether errors are considered fatal. */
// This doesn't do anything yet. We need to be able to catch uncaught errors
// (oxymoronically) in order to take lethal action. This is waiting for the
@@ -332,15 +341,41 @@ class _IsolateContext implements IsolateContext {
}
void handlePing(SendPort responsePort, int pingType) {
- if (pingType == Isolate.PING_EVENT) {
- _globalState.topEventLoop.enqueue(this, () {
- responsePort.send(null);
- }, "ping");
- } else {
- // There is no difference between PING_ALIVE and PING_CONTROL
- // since we don't handle it before the control event queue.
+ if (pingType == Isolate.OUT_OF_BAND ||
+ (pingType == Isolate.BEFORE_NEXT_EVENT &&
+ !identical(_globalState.currentContext, this))) {
floitsch 2014/03/14 13:01:44 Create a helper function, so that it's more obviou
responsePort.send(null);
+ return;
+ }
+ void respond() { responsePort.send(null); }
+ if (pingType == Isolate.AS_EVENT) {
+ _globalState.topEventLoop.enqueue(this, respond, "ping");
+ return;
+ }
+ assert(pingType == Isolate.BEFORE_NEXT_EVENT);
+ if (_scheduledControlEvents == null) {
+ _scheduledControlEvents = new Queue();
+ }
+ _scheduledControlEvents.addLast(respond);
+ }
+
+ void handleKill(Capability authentification, int priority) {
+ if (this.terminateCapability != authentification) return;
+ if (priority == Isolate.OUT_OF_BAND ||
+ (priority == Isolate.BEFORE_NEXT_EVENT &&
+ !identical(_globalState.currentContext, this))) {
+ kill();
+ return;
+ }
+ if (priority == Isolate.AS_EVENT) {
+ _globalState.topEventLoop.enqueue(this, kill, "kill");
+ return;
+ }
+ assert(pingType == Isolate.BEFORE_NEXT_EVENT);
floitsch 2014/03/14 13:01:44 priority.
Lasse Reichstein Nielsen 2014/03/19 13:07:51 Ack.
+ if (_scheduledControlEvents == null) {
+ _scheduledControlEvents = new Queue();
}
+ _scheduledControlEvents.addLast(kill);
}
/**
@@ -356,6 +391,11 @@ class _IsolateContext implements IsolateContext {
} finally {
_globalState.currentContext = old;
if (old != null) old._setGlobals();
+ if (_scheduledControlEvents != null) {
+ while (_scheduledControlEvents.isNotEmpty) {
+ (_scheduledControlEvents.removeFirst())();
+ }
+ }
}
return result;
}
@@ -364,6 +404,13 @@ class _IsolateContext implements IsolateContext {
JS_SET_CURRENT_ISOLATE(isolateStatics);
}
+ /**
+ * Handle messages comming in on the control port.
+ *
+ * These events do not go through the event queue.
+ * The `_globalState.currentContext` context is not set to this context
+ * during the handling.
+ */
void handleControlMessage(message) {
switch (message[0]) {
case "pause":
@@ -384,8 +431,10 @@ class _IsolateContext implements IsolateContext {
case "ping":
handlePing(message[1], message[2]);
break;
+ case "kill":
+ handleKill(message[1], message[2]);
+ break;
default:
- print("UNKNOWN MESSAGE: $message");
}
}
@@ -419,18 +468,30 @@ class _IsolateContext implements IsolateContext {
if (ports.length - weakPorts.length > 0 || isPaused) {
_globalState.isolates[id] = this; // indicate this isolate is active
} else {
- _shutdown();
+ kill();
}
}
- void _shutdown() {
+ void kill() {
+ if (_scheduledControlEvents != null) {
+ // Kill all pending events.
+ _scheduledControlEvents.clear();
+ }
+ // Stop listening on all ports.
+ // This should happen before sending events to done handlers, in case
+ // we are listening on ourselves.
+ // Closes all ports, including control port.
+ for (var port in ports.values) {
+ port._close();
+ }
+ ports.clear();
+ weakPorts.clear();
_globalState.isolates.remove(id); // indicate this isolate is not active
- // Send "done" event to all listeners. This must be done after deactivating
- // the current isolate, or it may get events if listening to itself.
if (doneHandlers != null) {
for (SendPort port in doneHandlers) {
port.send(null);
}
+ doneHandlers = null;
}
}
@@ -1046,6 +1107,13 @@ class RawReceivePortImpl implements RawReceivePort {
_handler = newHandler;
}
+ // Close the port without unregistering it.
+ // Used by an isolate context to close all ports when shutting down.
+ void _close() {
+ _isClosed = true;
+ _handler = null;
+ }
+
void close() {
if (_isClosed) return;
_isClosed = true;
« no previous file with comments | « no previous file | sdk/lib/isolate/isolate.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698