This repository has been archived by the owner on Aug 31, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 97
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make MessagePort an EventEmitter everywhere
- Loading branch information
Showing
7 changed files
with
108 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
(function(global, binding, v8) { | ||
|
||
'use strict'; | ||
|
||
const { defineProperty, setPrototypeOf } = global.Object; | ||
|
||
// A communication channel consisting of a handle (that wraps around an | ||
// uv_async_t) which can receive information from other threads and emits | ||
// .onmessage events, and a function used for sending data to a MessagePort | ||
// in some other thread. | ||
function onmessage(payload, flag) { | ||
if (flag !== 0 /*MESSAGE_FLAG_NONE*/ && flag < 100 /*MESSAGE_FLAG_CUSTOM_OFFSET*/) { | ||
// This was not handled in C++, but it is also not a custom message in the | ||
// sense that it was generated in JS, so some special handling is still | ||
// required for deserialization. | ||
// (This is primarily for error situations) | ||
// debug(`[${threadId}] received raw message`, flag, payload); | ||
return this.emit('flaggedMessage', flag, payload); | ||
} | ||
|
||
// debug(`[${threadId}] received message`, flag, payload); | ||
// Emit the flag and deserialized object to userland. | ||
if (flag === 0 || flag === undefined) | ||
this.emit('message', payload); | ||
else | ||
this.emit('flaggedMessage', flag, payload); | ||
} | ||
|
||
function oninit() { | ||
// Keep track of whether there are any workerMessage listeners: | ||
// If there are some, ref() the channel so it keeps the event loop alive. | ||
// If there are none or all are removed, unref() the channel so the worker | ||
// can shutdown gracefully. | ||
this.unref(); | ||
this.on('newListener', (name) => { | ||
if (name === 'message' && this.listenerCount('message') === 0) { | ||
this.ref(); | ||
this.start(); | ||
} | ||
}); | ||
this.on('removeListener', (name) => { | ||
if (name === 'message' && this.listenerCount('message') === 0) { | ||
this.unref(); | ||
} | ||
}); | ||
} | ||
|
||
function onclose() { | ||
this.emit('close'); | ||
} | ||
|
||
function makeMessagePort(MessagePort) { | ||
setPrototypeOf(MessagePort.prototype, binding.EventEmitter.prototype); | ||
This comment has been minimized.
Sorry, something went wrong. |
||
|
||
defineProperty(MessagePort.prototype, 'onmessage', { | ||
enumerable: false, | ||
writable: false, | ||
value: onmessage | ||
}); | ||
|
||
defineProperty(MessagePort.prototype, 'oninit', { | ||
enumerable: false, | ||
writable: false, | ||
value: oninit | ||
}); | ||
|
||
defineProperty(MessagePort.prototype, 'onclose', { | ||
enumerable: false, | ||
writable: false, | ||
value: onclose | ||
}); | ||
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
|
||
binding.makeMessagePort = makeMessagePort; | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,8 +26,10 @@ using v8::Maybe; | |
using v8::MaybeLocal; | ||
using v8::Nothing; | ||
using v8::Object; | ||
using v8::Private; | ||
using v8::SharedArrayBuffer; | ||
using v8::String; | ||
using v8::Undefined; | ||
using v8::Value; | ||
using v8::ValueDeserializer; | ||
using v8::ValueSerializer; | ||
|
@@ -754,8 +756,30 @@ MaybeLocal<Function> GetMessagePortConstructor( | |
// of code, because it is needed early on in the child environment setup. | ||
Local<FunctionTemplate> templ; | ||
templ = env->message_port_constructor_template(); | ||
if (!templ.IsEmpty()) | ||
return templ->GetFunction(context); | ||
if (!templ.IsEmpty()) { | ||
auto maybe_ctor = templ->GetFunction(context); | ||
Local<Function> ctor; | ||
if (!maybe_ctor.ToLocal(&ctor)) return maybe_ctor; | ||
|
||
// Set up EventEmitter inheritance and some default listners. | ||
Local<Private> initialized = env->messageport_initialized_private_symbol(); | ||
if (!ctor->HasPrivate(context, initialized).FromJust()) { | ||
Local<Object> extras = context->GetExtrasBindingObject(); | ||
Local<Function> make_message_port = | ||
extras->Get(context, | ||
FIXED_ONE_BYTE_STRING(env->isolate(), "makeMessagePort")) | ||
.ToLocalChecked().As<Function>(); | ||
CHECK(make_message_port->IsFunction()); | ||
This comment has been minimized.
Sorry, something went wrong.
addaleax
Contributor
|
||
Local<Value> args[] = { ctor }; | ||
make_message_port->Call(context, Undefined(env->isolate()), | ||
arraysize(args), args).ToLocalChecked(); | ||
This comment has been minimized.
Sorry, something went wrong.
addaleax
Contributor
|
||
|
||
ctor->SetPrivate(context, initialized, Undefined(env->isolate())) | ||
.FromJust(); | ||
} | ||
|
||
return maybe_ctor; | ||
} | ||
|
||
{ | ||
Local<FunctionTemplate> m = env->NewFunctionTemplate(MessagePort::New); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
I think there should be a second prototype chain for the constructors as well (we can choose to not do that, but it’s what ES classes do)