diff options
author | Anna Henningsen <anna@addaleax.net> | 2020-06-06 17:27:30 +0300 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2020-06-14 15:53:40 +0300 |
commit | 8641d94189398063b20d5e38549bfd8f023af2d6 (patch) | |
tree | ecb18fb2e97803c51b6b5105361a3e4fb0a5904d /src/node_file.cc | |
parent | 9129cf21ab51432675521ea158191ae3f866cafb (diff) |
worker,fs: make FileHandle transferable
Allow passing `FileHandle` instances in the transfer list
of a `.postMessage()` call.
PR-URL: https://github.com/nodejs/node/pull/33772
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Diffstat (limited to 'src/node_file.cc')
-rw-r--r-- | src/node_file.cc | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/node_file.cc b/src/node_file.cc index c2ed56f43fb..9ed2d2960cf 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -190,6 +190,40 @@ void FileHandle::MemoryInfo(MemoryTracker* tracker) const { tracker->TrackField("current_read", current_read_); } +FileHandle::TransferMode FileHandle::GetTransferMode() const { + return reading_ || closing_ || closed_ ? + TransferMode::kUntransferable : TransferMode::kTransferable; +} + +std::unique_ptr<worker::TransferData> FileHandle::TransferForMessaging() { + CHECK_NE(GetTransferMode(), TransferMode::kUntransferable); + auto ret = std::make_unique<TransferData>(fd_); + closed_ = true; + return ret; +} + +FileHandle::TransferData::TransferData(int fd) : fd_(fd) {} + +FileHandle::TransferData::~TransferData() { + if (fd_ > 0) { + uv_fs_t close_req; + CHECK_EQ(0, uv_fs_close(nullptr, &close_req, fd_, nullptr)); + uv_fs_req_cleanup(&close_req); + } +} + +BaseObjectPtr<BaseObject> FileHandle::TransferData::Deserialize( + Environment* env, + v8::Local<v8::Context> context, + std::unique_ptr<worker::TransferData> self) { + BindingData* bd = Environment::GetBindingData<BindingData>(context); + if (bd == nullptr) return {}; + + int fd = fd_; + fd_ = -1; + return BaseObjectPtr<BaseObject> { FileHandle::New(bd, fd) }; +} + // Close the file descriptor if it hasn't already been closed. A process // warning will be emitted using a SetImmediate to avoid calling back to // JS during GC. If closing the fd fails at this point, a fatal exception |