diff options
author | Anna Henningsen <anna@addaleax.net> | 2018-05-13 19:39:32 +0200 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2018-06-06 19:43:46 +0200 |
commit | b0404047c1e4f7652aaf6ecf911d5850d5acf570 (patch) | |
tree | f8e09cfda61b24d4c548e6d9ab560bfaa5d3a03a /src/node_messaging.cc | |
parent | 749a13b76c351d515ed489844ece575b8918d2ed (diff) | |
download | android-node-v8-b0404047c1e4f7652aaf6ecf911d5850d5acf570.tar.gz android-node-v8-b0404047c1e4f7652aaf6ecf911d5850d5acf570.tar.bz2 android-node-v8-b0404047c1e4f7652aaf6ecf911d5850d5acf570.zip |
worker: add `SharedArrayBuffer` sharing
Logic is added to the `MessagePort` mechanism that
attaches hidden objects to those instances when they are transferred
that track their lifetime and maintain a reference count, to make
sure that memory is freed at the appropriate times.
Thanks to Stephen Belanger for reviewing this change in its original PR.
Refs: https://github.com/ayojs/ayo/pull/106
PR-URL: https://github.com/nodejs/node/pull/20876
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Shingo Inoue <leko.noor@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: John-David Dalton <john.david.dalton@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Diffstat (limited to 'src/node_messaging.cc')
-rw-r--r-- | src/node_messaging.cc | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/src/node_messaging.cc b/src/node_messaging.cc index 1c6551e096..ede38cc817 100644 --- a/src/node_messaging.cc +++ b/src/node_messaging.cc @@ -24,6 +24,7 @@ using v8::Maybe; using v8::MaybeLocal; using v8::Nothing; using v8::Object; +using v8::SharedArrayBuffer; using v8::String; using v8::Value; using v8::ValueDeserializer; @@ -43,8 +44,13 @@ class DeserializerDelegate : public ValueDeserializer::Delegate { public: DeserializerDelegate(Message* m, Environment* env, - const std::vector<MessagePort*>& message_ports) - : env_(env), msg_(m), message_ports_(message_ports) {} + const std::vector<MessagePort*>& message_ports, + const std::vector<Local<SharedArrayBuffer>>& + shared_array_buffers) + : env_(env), + msg_(m), + message_ports_(message_ports), + shared_array_buffers_(shared_array_buffers) {} MaybeLocal<Object> ReadHostObject(Isolate* isolate) override { // Currently, only MessagePort hosts objects are supported, so identifying @@ -56,12 +62,19 @@ class DeserializerDelegate : public ValueDeserializer::Delegate { return message_ports_[id]->object(); }; + MaybeLocal<SharedArrayBuffer> GetSharedArrayBufferFromId( + Isolate* isolate, uint32_t clone_id) override { + CHECK_LE(clone_id, shared_array_buffers_.size()); + return shared_array_buffers_[clone_id]; + } + ValueDeserializer* deserializer = nullptr; private: Environment* env_; Message* msg_; const std::vector<MessagePort*>& message_ports_; + const std::vector<Local<SharedArrayBuffer>>& shared_array_buffers_; }; } // anonymous namespace @@ -87,7 +100,18 @@ MaybeLocal<Value> Message::Deserialize(Environment* env, } message_ports_.clear(); - DeserializerDelegate delegate(this, env, ports); + std::vector<Local<SharedArrayBuffer>> shared_array_buffers; + // Attach all transfered SharedArrayBuffers to their new Isolate. + for (uint32_t i = 0; i < shared_array_buffers_.size(); ++i) { + Local<SharedArrayBuffer> sab; + if (!shared_array_buffers_[i]->GetSharedArrayBuffer(env, context) + .ToLocal(&sab)) + return MaybeLocal<Value>(); + shared_array_buffers.push_back(sab); + } + shared_array_buffers_.clear(); + + DeserializerDelegate delegate(this, env, ports, shared_array_buffers); ValueDeserializer deserializer( env->isolate(), reinterpret_cast<const uint8_t*>(main_message_buf_.data), @@ -112,6 +136,11 @@ MaybeLocal<Value> Message::Deserialize(Environment* env, deserializer.ReadValue(context).FromMaybe(Local<Value>())); } +void Message::AddSharedArrayBuffer( + SharedArrayBufferMetadataReference reference) { + shared_array_buffers_.push_back(reference); +} + void Message::AddMessagePort(std::unique_ptr<MessagePortData>&& data) { message_ports_.emplace_back(std::move(data)); } @@ -139,6 +168,27 @@ class SerializerDelegate : public ValueSerializer::Delegate { return Nothing<bool>(); } + Maybe<uint32_t> GetSharedArrayBufferId( + Isolate* isolate, + Local<SharedArrayBuffer> shared_array_buffer) override { + uint32_t i; + for (i = 0; i < seen_shared_array_buffers_.size(); ++i) { + if (seen_shared_array_buffers_[i] == shared_array_buffer) + return Just(i); + } + + auto reference = SharedArrayBufferMetadata::ForSharedArrayBuffer( + env_, + context_, + shared_array_buffer); + if (!reference) { + return Nothing<uint32_t>(); + } + seen_shared_array_buffers_.push_back(shared_array_buffer); + msg_->AddSharedArrayBuffer(reference); + return Just(i); + } + void Finish() { // Only close the MessagePort handles and actually transfer them // once we know that serialization succeeded. @@ -166,6 +216,7 @@ class SerializerDelegate : public ValueSerializer::Delegate { Environment* env_; Local<Context> context_; Message* msg_; + std::vector<Local<SharedArrayBuffer>> seen_shared_array_buffers_; std::vector<MessagePort*> ports_; friend class worker::Message; |