summaryrefslogtreecommitdiff
path: root/src/node_messaging.cc
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2018-05-13 19:39:32 +0200
committerAnna Henningsen <anna@addaleax.net>2018-06-06 19:43:46 +0200
commitb0404047c1e4f7652aaf6ecf911d5850d5acf570 (patch)
treef8e09cfda61b24d4c548e6d9ab560bfaa5d3a03a /src/node_messaging.cc
parent749a13b76c351d515ed489844ece575b8918d2ed (diff)
downloadandroid-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.cc57
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;