diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/node_file.cc | 34 | ||||
-rw-r--r-- | src/node_file.h | 22 |
2 files changed, 56 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 diff --git a/src/node_file.h b/src/node_file.h index ad493bd944c..fd17fc99d52 100644 --- a/src/node_file.h +++ b/src/node_file.h @@ -5,6 +5,7 @@ #include "node.h" #include "aliased_buffer.h" +#include "node_messaging.h" #include "stream_base.h" #include <iostream> @@ -273,7 +274,28 @@ class FileHandle final : public AsyncWrap, public StreamBase { FileHandle(const FileHandle&&) = delete; FileHandle& operator=(const FileHandle&&) = delete; + TransferMode GetTransferMode() const override; + std::unique_ptr<worker::TransferData> TransferForMessaging() override; + private: + class TransferData : public worker::TransferData { + public: + explicit TransferData(int fd); + ~TransferData(); + + BaseObjectPtr<BaseObject> Deserialize( + Environment* env, + v8::Local<v8::Context> context, + std::unique_ptr<worker::TransferData> self) override; + + SET_NO_MEMORY_INFO() + SET_MEMORY_INFO_NAME(FileHandleTransferData) + SET_SELF_SIZE(TransferData) + + private: + int fd_; + }; + FileHandle(BindingData* binding_data, v8::Local<v8::Object> obj, int fd); // Synchronous close that emits a warning |