From fbc396189494077c47f7afdaa3d889f1e31ba226 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 14 Dec 2017 10:49:55 -0800 Subject: [PATCH 1/3] fs: refactor FSReqWrap and After Separate FSReqWrap definition into a new node_file.h. Add Reject and Resolve methods to encapsulate the callbacks and make the constructor, destructor protected instead of private in preparation to make FSReqWrap subclassable for the Promises implementation. Rework and simplify the After function slightly in preparation for a refactor. Introduce the node::fs namespace instead of using an anonymous namespace for fs methods. --- node.gyp | 1 + src/node_file.cc | 226 +++++++++++++++++------------------------------ src/node_file.h | 102 +++++++++++++++++++++ 3 files changed, 185 insertions(+), 144 deletions(-) create mode 100644 src/node_file.h diff --git a/node.gyp b/node.gyp index e362b67830537f..5d4650e560ccfc 100644 --- a/node.gyp +++ b/node.gyp @@ -261,6 +261,7 @@ 'src/node_buffer.h', 'src/node_constants.h', 'src/node_debug_options.h', + 'src/node_file.h', 'src/node_http2.h', 'src/node_http2_state.h', 'src/node_internals.h', diff --git a/src/node_file.cc b/src/node_file.cc index e615179bee2bfd..62a7f864cfb682 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -22,6 +22,7 @@ #include "node_buffer.h" #include "node_internals.h" #include "node_stat_watcher.h" +#include "node_file.h" #include "req_wrap-inl.h" #include "string_bytes.h" @@ -41,7 +42,42 @@ #include namespace node { -namespace { + +void FillStatsArray(double* fields, const uv_stat_t* s) { + fields[0] = s->st_dev; + fields[1] = s->st_mode; + fields[2] = s->st_nlink; + fields[3] = s->st_uid; + fields[4] = s->st_gid; + fields[5] = s->st_rdev; +#if defined(__POSIX__) + fields[6] = s->st_blksize; +#else + fields[6] = -1; +#endif + fields[7] = s->st_ino; + fields[8] = s->st_size; +#if defined(__POSIX__) + fields[9] = s->st_blocks; +#else + fields[9] = -1; +#endif +// Dates. +// NO-LINT because the fields are 'long' and we just want to cast to `unsigned` +#define X(idx, name) \ + /* NOLINTNEXTLINE(runtime/int) */ \ + fields[idx] = ((unsigned long)(s->st_##name.tv_sec) * 1e3) + \ + /* NOLINTNEXTLINE(runtime/int) */ \ + ((unsigned long)(s->st_##name.tv_nsec) / 1e6); \ + + X(10, atim) + X(11, mtim) + X(12, ctim) + X(13, birthtim) +#undef X +} + +namespace fs { using v8::Array; using v8::ArrayBuffer; @@ -67,60 +103,6 @@ using v8::Value; #define GET_OFFSET(a) ((a)->IsNumber() ? (a)->IntegerValue() : -1) -class FSReqWrap: public ReqWrap { - public: - enum Ownership { COPY, MOVE }; - - inline static FSReqWrap* New(Environment* env, - Local req, - const char* syscall, - const char* data = nullptr, - enum encoding encoding = UTF8, - Ownership ownership = COPY); - - inline void Dispose(); - - void ReleaseEarly() { - if (data_ != inline_data()) { - delete[] data_; - data_ = nullptr; - } - } - - const char* syscall() const { return syscall_; } - const char* data() const { return data_; } - const enum encoding encoding_; - - size_t self_size() const override { return sizeof(*this); } - - private: - FSReqWrap(Environment* env, - Local req, - const char* syscall, - const char* data, - enum encoding encoding) - : ReqWrap(env, req, AsyncWrap::PROVIDER_FSREQWRAP), - encoding_(encoding), - syscall_(syscall), - data_(data) { - Wrap(object(), this); - } - - ~FSReqWrap() { - ReleaseEarly(); - ClearWrap(object()); - } - - void* operator new(size_t size) = delete; - void* operator new(size_t size, char* storage) { return storage; } - char* inline_data() { return reinterpret_cast(this + 1); } - - const char* syscall_; - const char* data_; - - DISALLOW_COPY_AND_ASSIGN(FSReqWrap); -}; - #define ASSERT_PATH(path) \ if (*path == nullptr) \ return TYPE_ERROR( #path " must be a string or Buffer"); @@ -148,6 +130,19 @@ void FSReqWrap::Dispose() { } +void FSReqWrap::Reject(Local reject) { + Local argv[1] { reject }; + MakeCallback(env()->oncomplete_string(), arraysize(argv), argv); +} + +void FSReqWrap::Resolve(Local value) { + Local argv[2] { + Null(env()->isolate()), + value + }; + MakeCallback(env()->oncomplete_string(), arraysize(argv), argv); +} + void NewFSReqWrap(const FunctionCallbackInfo& args) { CHECK(args.IsConstructCall()); ClearWrap(args.This()); @@ -163,29 +158,23 @@ void After(uv_fs_t *req) { HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); - // there is always at least one argument. "error" - int argc = 1; - // Allocate space for two args. We may only use one depending on the case. // (Feel free to increase this if you need more) - Local argv[2]; MaybeLocal link; Local error; if (req->result < 0) { // An error happened. - argv[0] = UVException(env->isolate(), - req->result, - req_wrap->syscall(), - nullptr, - req->path, - req_wrap->data()); + req_wrap->Reject(UVException(env->isolate(), + req->result, + req_wrap->syscall(), + nullptr, + req->path, + req_wrap->data())); } else { // error value is empty or null for non-error. - argv[0] = Null(env->isolate()); - - // All have at least two args now. - argc = 2; + Local ret = Undefined(env->isolate()); + bool reject = false; switch (req->fs_type) { // These all have no data to pass. @@ -205,31 +194,25 @@ void After(uv_fs_t *req) { case UV_FS_CHOWN: case UV_FS_FCHOWN: case UV_FS_COPYFILE: + case UV_FS_UTIME: + case UV_FS_FUTIME: // These, however, don't. - argc = 1; break; case UV_FS_STAT: case UV_FS_LSTAT: case UV_FS_FSTAT: - argc = 1; FillStatsArray(env->fs_stats_field_array(), static_cast(req->ptr)); break; - case UV_FS_UTIME: - case UV_FS_FUTIME: - argc = 0; - break; - case UV_FS_OPEN: - argv[1] = Integer::New(env->isolate(), req->result); - break; - case UV_FS_WRITE: - argv[1] = Integer::New(env->isolate(), req->result); + case UV_FS_READ: + ret = Integer::New(env->isolate(), req->result); break; + case UV_FS_MKDTEMP: { link = StringBytes::Encode(env->isolate(), @@ -237,42 +220,28 @@ void After(uv_fs_t *req) { req_wrap->encoding_, &error); if (link.IsEmpty()) { - argv[0] = error; + reject = true; + ret = error; } else { - argv[1] = link.ToLocalChecked(); + ret = link.ToLocalChecked(); } break; } case UV_FS_READLINK: - link = StringBytes::Encode(env->isolate(), - static_cast(req->ptr), - req_wrap->encoding_, - &error); - if (link.IsEmpty()) { - argv[0] = error; - } else { - argv[1] = link.ToLocalChecked(); - } - break; - case UV_FS_REALPATH: link = StringBytes::Encode(env->isolate(), static_cast(req->ptr), req_wrap->encoding_, &error); if (link.IsEmpty()) { - argv[0] = error; + reject = true; + ret = error; } else { - argv[1] = link.ToLocalChecked(); + ret = link.ToLocalChecked(); } break; - case UV_FS_READ: - // Buffer interface - argv[1] = Integer::New(env->isolate(), req->result); - break; - case UV_FS_SCANDIR: { int r; @@ -288,10 +257,9 @@ void After(uv_fs_t *req) { if (r == UV_EOF) break; if (r != 0) { - argv[0] = UVException(r, - nullptr, - req_wrap->syscall(), - static_cast(req->path)); + reject = true; + ret = UVException(r, nullptr, req_wrap->syscall(), + static_cast(req->path)); break; } @@ -301,7 +269,8 @@ void After(uv_fs_t *req) { req_wrap->encoding_, &error); if (filename.IsEmpty()) { - argv[0] = error; + reject = true; + ret = error; break; } name_argv[name_idx++] = filename.ToLocalChecked(); @@ -318,17 +287,19 @@ void After(uv_fs_t *req) { .ToLocalChecked(); } - argv[1] = names; + ret = names; } break; default: CHECK(0 && "Unhandled eio response"); } + if (!reject) + req_wrap->Resolve(ret); + else + req_wrap->Reject(ret); } - req_wrap->MakeCallback(env->oncomplete_string(), argc, argv); - uv_fs_req_cleanup(req_wrap->req()); req_wrap->Dispose(); } @@ -471,41 +442,6 @@ void Close(const FunctionCallbackInfo& args) { } } -} // anonymous namespace - -void FillStatsArray(double* fields, const uv_stat_t* s) { - fields[0] = s->st_dev; - fields[1] = s->st_mode; - fields[2] = s->st_nlink; - fields[3] = s->st_uid; - fields[4] = s->st_gid; - fields[5] = s->st_rdev; -#if defined(__POSIX__) - fields[6] = s->st_blksize; -#else - fields[6] = -1; -#endif - fields[7] = s->st_ino; - fields[8] = s->st_size; -#if defined(__POSIX__) - fields[9] = s->st_blocks; -#else - fields[9] = -1; -#endif -// Dates. -// NO-LINT because the fields are 'long' and we just want to cast to `unsigned` -#define X(idx, name) \ - /* NOLINTNEXTLINE(runtime/int) */ \ - fields[idx] = ((unsigned long)(s->st_##name.tv_sec) * 1e3) + \ - /* NOLINTNEXTLINE(runtime/int) */ \ - ((unsigned long)(s->st_##name.tv_nsec) / 1e6); \ - - X(10, atim) - X(11, mtim) - X(12, ctim) - X(13, birthtim) -#undef X -} // Used to speed up module loading. Returns the contents of the file as // a string or undefined when the file cannot be opened. Returns an empty @@ -1460,6 +1396,8 @@ void InitFs(Local target, target->Set(wrapString, fst->GetFunction()); } +} // namespace fs + } // end namespace node -NODE_BUILTIN_MODULE_CONTEXT_AWARE(fs, node::InitFs) +NODE_BUILTIN_MODULE_CONTEXT_AWARE(fs, node::fs::InitFs) diff --git a/src/node_file.h b/src/node_file.h new file mode 100644 index 00000000000000..53515ac7558228 --- /dev/null +++ b/src/node_file.h @@ -0,0 +1,102 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +#ifndef SRC_NODE_FILE_H_ +#define SRC_NODE_FILE_H_ + +#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#include "node.h" +#include "req_wrap-inl.h" + +namespace node { + +using v8::Local; +using v8::Object; +using v8::Value; + +namespace fs { + +class FSReqWrap: public ReqWrap { + public: + enum Ownership { COPY, MOVE }; + + inline static FSReqWrap* New(Environment* env, + Local req, + const char* syscall, + const char* data = nullptr, + enum encoding encoding = UTF8, + Ownership ownership = COPY); + + inline void Dispose(); + + virtual void Reject(Local reject); + virtual void Resolve(Local value); + + void ReleaseEarly() { + if (data_ != inline_data()) { + delete[] data_; + data_ = nullptr; + } + } + + const char* syscall() const { return syscall_; } + const char* data() const { return data_; } + const enum encoding encoding_; + + size_t self_size() const override { return sizeof(*this); } + + protected: + FSReqWrap(Environment* env, + Local req, + const char* syscall, + const char* data, + enum encoding encoding) + : ReqWrap(env, req, AsyncWrap::PROVIDER_FSREQWRAP), + encoding_(encoding), + syscall_(syscall), + data_(data) { + Wrap(object(), this); + } + + virtual ~FSReqWrap() { + ReleaseEarly(); + ClearWrap(object()); + } + + void* operator new(size_t size) = delete; + void* operator new(size_t size, char* storage) { return storage; } + char* inline_data() { return reinterpret_cast(this + 1); } + + private: + const char* syscall_; + const char* data_; + + DISALLOW_COPY_AND_ASSIGN(FSReqWrap); +}; + +} // namespace fs + +} // namespace node + +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS + +#endif // SRC_NODE_FILE_H_ From 6b18e12926b7ee960893a70653cb8c939e449e82 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 14 Dec 2017 12:33:21 -0800 Subject: [PATCH 2/3] fs: refactor After for easier maintainability --- src/node_file.cc | 350 +++++++++++++++++++++++------------------------ src/node_file.h | 40 +++--- 2 files changed, 193 insertions(+), 197 deletions(-) diff --git a/src/node_file.cc b/src/node_file.cc index 62a7f864cfb682..a42f12912a1285 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -149,161 +149,155 @@ void NewFSReqWrap(const FunctionCallbackInfo& args) { } -void After(uv_fs_t *req) { +FSReqAfterScope::FSReqAfterScope(FSReqWrap* wrap, uv_fs_t* req) + : wrap_(wrap), + req_(req), + handle_scope_(wrap->env()->isolate()), + context_scope_(wrap->env()->context()) { + CHECK_EQ(wrap_->req(), req); + wrap_->ReleaseEarly(); // Free memory that's no longer used now. +} + +FSReqAfterScope::~FSReqAfterScope() { + uv_fs_req_cleanup(wrap_->req()); + wrap_->Dispose(); +} + +void FSReqAfterScope::Reject(uv_fs_t* req) { + wrap_->Reject(UVException(wrap_->env()->isolate(), + req->result, + wrap_->syscall(), + nullptr, + req->path, + wrap_->data())); +} + +bool FSReqAfterScope::Proceed() { + if (req_->result < 0) { + Reject(req_); + return false; + } + return true; +} + +void AfterNoArgs(uv_fs_t* req) { FSReqWrap* req_wrap = static_cast(req->data); - CHECK_EQ(req_wrap->req(), req); - req_wrap->ReleaseEarly(); // Free memory that's no longer used now. + FSReqAfterScope after(req_wrap, req); + + if (after.Proceed()) + req_wrap->Resolve(Undefined(req_wrap->env()->isolate())); +} +void AfterStat(uv_fs_t* req) { + FSReqWrap* req_wrap = static_cast(req->data); + FSReqAfterScope after(req_wrap, req); Environment* env = req_wrap->env(); - HandleScope handle_scope(env->isolate()); - Context::Scope context_scope(env->context()); - // Allocate space for two args. We may only use one depending on the case. - // (Feel free to increase this if you need more) + if (after.Proceed()) { + FillStatsArray(env->fs_stats_field_array(), + static_cast(req->ptr)); + req_wrap->Resolve(Undefined(req_wrap->env()->isolate())); + } +} + +void AfterInteger(uv_fs_t* req) { + FSReqWrap* req_wrap = static_cast(req->data); + FSReqAfterScope after(req_wrap, req); + + if (after.Proceed()) + req_wrap->Resolve(Integer::New(req_wrap->env()->isolate(), req->result)); +} + +void AfterStringPath(uv_fs_t* req) { + FSReqWrap* req_wrap = static_cast(req->data); + FSReqAfterScope after(req_wrap, req); + MaybeLocal link; Local error; - if (req->result < 0) { - // An error happened. - req_wrap->Reject(UVException(env->isolate(), - req->result, - req_wrap->syscall(), - nullptr, - req->path, - req_wrap->data())); - } else { - // error value is empty or null for non-error. - Local ret = Undefined(env->isolate()); - bool reject = false; - - switch (req->fs_type) { - // These all have no data to pass. - case UV_FS_ACCESS: - case UV_FS_CLOSE: - case UV_FS_RENAME: - case UV_FS_UNLINK: - case UV_FS_RMDIR: - case UV_FS_MKDIR: - case UV_FS_FTRUNCATE: - case UV_FS_FSYNC: - case UV_FS_FDATASYNC: - case UV_FS_LINK: - case UV_FS_SYMLINK: - case UV_FS_CHMOD: - case UV_FS_FCHMOD: - case UV_FS_CHOWN: - case UV_FS_FCHOWN: - case UV_FS_COPYFILE: - case UV_FS_UTIME: - case UV_FS_FUTIME: - // These, however, don't. - break; + if (after.Proceed()) { + link = StringBytes::Encode(req_wrap->env()->isolate(), + static_cast(req->path), + req_wrap->encoding_, + &error); + if (link.IsEmpty()) + req_wrap->Reject(error); + else + req_wrap->Resolve(link.ToLocalChecked()); + } +} - case UV_FS_STAT: - case UV_FS_LSTAT: - case UV_FS_FSTAT: - FillStatsArray(env->fs_stats_field_array(), - static_cast(req->ptr)); - break; +void AfterStringPtr(uv_fs_t* req) { + FSReqWrap* req_wrap = static_cast(req->data); + FSReqAfterScope after(req_wrap, req); - case UV_FS_OPEN: - case UV_FS_WRITE: - case UV_FS_READ: - ret = Integer::New(env->isolate(), req->result); - break; + MaybeLocal link; + Local error; + + if (after.Proceed()) { + link = StringBytes::Encode(req_wrap->env()->isolate(), + static_cast(req->ptr), + req_wrap->encoding_, + &error); + if (link.IsEmpty()) + req_wrap->Reject(error); + else + req_wrap->Resolve(link.ToLocalChecked()); + } +} + +void AfterScanDir(uv_fs_t* req) { + FSReqWrap* req_wrap = static_cast(req->data); + FSReqAfterScope after(req_wrap, req); + if (after.Proceed()) { + Environment* env = req_wrap->env(); + Local error; + int r; + Local names = Array::New(env->isolate(), 0); + Local fn = env->push_values_to_array_function(); + Local name_argv[NODE_PUSH_VAL_TO_ARRAY_MAX]; + size_t name_idx = 0; + + for (int i = 0; ; i++) { + uv_dirent_t ent; - case UV_FS_MKDTEMP: - { - link = StringBytes::Encode(env->isolate(), - static_cast(req->path), - req_wrap->encoding_, - &error); - if (link.IsEmpty()) { - reject = true; - ret = error; - } else { - ret = link.ToLocalChecked(); - } + r = uv_fs_scandir_next(req, &ent); + if (r == UV_EOF) break; + if (r != 0) { + return req_wrap->Reject( + UVException(r, nullptr, req_wrap->syscall(), + static_cast(req->path))); } - case UV_FS_READLINK: - case UV_FS_REALPATH: - link = StringBytes::Encode(env->isolate(), - static_cast(req->ptr), - req_wrap->encoding_, - &error); - if (link.IsEmpty()) { - reject = true; - ret = error; - } else { - ret = link.ToLocalChecked(); - } - break; + MaybeLocal filename = + StringBytes::Encode(env->isolate(), + ent.name, + req_wrap->encoding_, + &error); + if (filename.IsEmpty()) + return req_wrap->Reject(error); - case UV_FS_SCANDIR: - { - int r; - Local names = Array::New(env->isolate(), 0); - Local fn = env->push_values_to_array_function(); - Local name_argv[NODE_PUSH_VAL_TO_ARRAY_MAX]; - size_t name_idx = 0; - - for (int i = 0; ; i++) { - uv_dirent_t ent; - - r = uv_fs_scandir_next(req, &ent); - if (r == UV_EOF) - break; - if (r != 0) { - reject = true; - ret = UVException(r, nullptr, req_wrap->syscall(), - static_cast(req->path)); - break; - } - - MaybeLocal filename = - StringBytes::Encode(env->isolate(), - ent.name, - req_wrap->encoding_, - &error); - if (filename.IsEmpty()) { - reject = true; - ret = error; - break; - } - name_argv[name_idx++] = filename.ToLocalChecked(); - - if (name_idx >= arraysize(name_argv)) { - fn->Call(env->context(), names, name_idx, name_argv) - .ToLocalChecked(); - name_idx = 0; - } - } - - if (name_idx > 0) { - fn->Call(env->context(), names, name_idx, name_argv) - .ToLocalChecked(); - } - - ret = names; - } - break; + name_argv[name_idx++] = filename.ToLocalChecked(); - default: - CHECK(0 && "Unhandled eio response"); + if (name_idx >= arraysize(name_argv)) { + fn->Call(env->context(), names, name_idx, name_argv) + .ToLocalChecked(); + name_idx = 0; + } } - if (!reject) - req_wrap->Resolve(ret); - else - req_wrap->Reject(ret); - } - uv_fs_req_cleanup(req_wrap->req()); - req_wrap->Dispose(); + if (name_idx > 0) { + fn->Call(env->context(), names, name_idx, name_argv) + .ToLocalChecked(); + } + + req_wrap->Resolve(names); + } } + // This struct is only used on sync fs calls. // For async calls FSReqWrap is used. class fs_req_wrap { @@ -320,15 +314,15 @@ class fs_req_wrap { template inline FSReqWrap* AsyncDestCall(Environment* env, Local req, const char* dest, enum encoding enc, const char* syscall, - Func fn, Args... args) { + uv_fs_cb after, Func fn, Args... args) { FSReqWrap* req_wrap = FSReqWrap::New(env, req, syscall, dest, enc); - int err = fn(env->event_loop(), req_wrap->req(), args..., After); + int err = fn(env->event_loop(), req_wrap->req(), args..., after); req_wrap->Dispatched(); if (err < 0) { uv_fs_t* uv_req = req_wrap->req(); uv_req->result = err; uv_req->path = nullptr; - After(uv_req); + after(uv_req); req_wrap = nullptr; } @@ -338,11 +332,12 @@ inline FSReqWrap* AsyncDestCall(Environment* env, Local req, // Template counterpart of ASYNC_CALL template inline FSReqWrap* AsyncCall(Environment* env, Local req, - enum encoding enc, const char* syscall, Func fn, Args... args) { - return AsyncDestCall(env, req, nullptr, enc, syscall, fn, args...); + enum encoding enc, const char* syscall, uv_fs_cb after, + Func fn, Args... args) { + return AsyncDestCall(env, req, nullptr, enc, syscall, after, fn, args...); } -#define ASYNC_DEST_CALL(func, request, dest, encoding, ...) \ +#define ASYNC_DEST_CALL(after, func, request, dest, encoding, ...) \ Environment* env = Environment::GetCurrent(args); \ CHECK(request->IsObject()); \ FSReqWrap* req_wrap = FSReqWrap::New(env, request.As(), \ @@ -350,20 +345,20 @@ inline FSReqWrap* AsyncCall(Environment* env, Local req, int err = uv_fs_ ## func(env->event_loop(), \ req_wrap->req(), \ __VA_ARGS__, \ - After); \ + after); \ req_wrap->Dispatched(); \ if (err < 0) { \ uv_fs_t* uv_req = req_wrap->req(); \ uv_req->result = err; \ uv_req->path = nullptr; \ - After(uv_req); \ + after(uv_req); \ req_wrap = nullptr; \ } else { \ args.GetReturnValue().Set(req_wrap->persistent()); \ } -#define ASYNC_CALL(func, req, encoding, ...) \ - ASYNC_DEST_CALL(func, req, nullptr, encoding, __VA_ARGS__) \ +#define ASYNC_CALL(after, func, req, encoding, ...) \ + ASYNC_DEST_CALL(after, func, req, nullptr, encoding, __VA_ARGS__) \ // Template counterpart of SYNC_DEST_CALL template @@ -418,7 +413,7 @@ void Access(const FunctionCallbackInfo& args) { if (args[2]->IsObject()) { Local req_obj = args[2]->ToObject(context).ToLocalChecked(); FSReqWrap* req_wrap = AsyncCall( - env, req_obj, UTF8, "access", uv_fs_access, *path, mode); + env, req_obj, UTF8, "access", AfterNoArgs, uv_fs_access, *path, mode); if (req_wrap != nullptr) { args.GetReturnValue().Set(req_wrap->persistent()); } @@ -436,7 +431,7 @@ void Close(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); if (args[1]->IsObject()) { - ASYNC_CALL(close, args[1], UTF8, fd) + ASYNC_CALL(AfterNoArgs, close, args[1], UTF8, fd) } else { SYNC_CALL(close, 0, fd) } @@ -537,7 +532,7 @@ static void Stat(const FunctionCallbackInfo& args) { ASSERT_PATH(path) if (args[1]->IsObject()) { - ASYNC_CALL(stat, args[1], UTF8, *path) + ASYNC_CALL(AfterStat, stat, args[1], UTF8, *path) } else { SYNC_CALL(stat, *path, *path) FillStatsArray(env->fs_stats_field_array(), @@ -555,7 +550,7 @@ static void LStat(const FunctionCallbackInfo& args) { ASSERT_PATH(path) if (args[1]->IsObject()) { - ASYNC_CALL(lstat, args[1], UTF8, *path) + ASYNC_CALL(AfterStat, lstat, args[1], UTF8, *path) } else { SYNC_CALL(lstat, *path, *path) FillStatsArray(env->fs_stats_field_array(), @@ -571,7 +566,7 @@ static void FStat(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); if (args[1]->IsObject()) { - ASYNC_CALL(fstat, args[1], UTF8, fd) + ASYNC_CALL(AfterStat, fstat, args[1], UTF8, fd) } else { SYNC_CALL(fstat, nullptr, fd) FillStatsArray(env->fs_stats_field_array(), @@ -607,7 +602,8 @@ static void Symlink(const FunctionCallbackInfo& args) { } if (args[3]->IsObject()) { - ASYNC_DEST_CALL(symlink, args[3], *path, UTF8, *target, *path, flags) + ASYNC_DEST_CALL(AfterNoArgs, symlink, args[3], *path, + UTF8, *target, *path, flags) } else { SYNC_DEST_CALL(symlink, *target, *path, *target, *path, flags) } @@ -629,7 +625,7 @@ static void Link(const FunctionCallbackInfo& args) { ASSERT_PATH(dest) if (args[2]->IsObject()) { - ASYNC_DEST_CALL(link, args[2], *dest, UTF8, *src, *dest) + ASYNC_DEST_CALL(AfterNoArgs, link, args[2], *dest, UTF8, *src, *dest) } else { SYNC_DEST_CALL(link, *src, *dest, *src, *dest) } @@ -653,7 +649,7 @@ static void ReadLink(const FunctionCallbackInfo& args) { callback = args[2]; if (callback->IsObject()) { - ASYNC_CALL(readlink, callback, encoding, *path) + ASYNC_CALL(AfterStringPtr, readlink, callback, encoding, *path) } else { SYNC_CALL(readlink, *path, *path) const char* link_path = static_cast(SYNC_REQ.ptr); @@ -686,7 +682,8 @@ static void Rename(const FunctionCallbackInfo& args) { ASSERT_PATH(new_path) if (args[2]->IsObject()) { - ASYNC_DEST_CALL(rename, args[2], *new_path, UTF8, *old_path, *new_path) + ASYNC_DEST_CALL(AfterNoArgs, rename, args[2], *new_path, + UTF8, *old_path, *new_path) } else { SYNC_DEST_CALL(rename, *old_path, *new_path, *old_path, *new_path) } @@ -702,7 +699,7 @@ static void FTruncate(const FunctionCallbackInfo& args) { const int64_t len = args[1]->IntegerValue(); if (args[2]->IsObject()) { - ASYNC_CALL(ftruncate, args[2], UTF8, fd, len) + ASYNC_CALL(AfterNoArgs, ftruncate, args[2], UTF8, fd, len) } else { SYNC_CALL(ftruncate, 0, fd, len) } @@ -716,7 +713,7 @@ static void Fdatasync(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); if (args[1]->IsObject()) { - ASYNC_CALL(fdatasync, args[1], UTF8, fd) + ASYNC_CALL(AfterNoArgs, fdatasync, args[1], UTF8, fd) } else { SYNC_CALL(fdatasync, 0, fd) } @@ -730,7 +727,7 @@ static void Fsync(const FunctionCallbackInfo& args) { int fd = args[0]->Int32Value(); if (args[1]->IsObject()) { - ASYNC_CALL(fsync, args[1], UTF8, fd) + ASYNC_CALL(AfterNoArgs, fsync, args[1], UTF8, fd) } else { SYNC_CALL(fsync, 0, fd) } @@ -746,7 +743,7 @@ static void Unlink(const FunctionCallbackInfo& args) { ASSERT_PATH(path) if (args[1]->IsObject()) { - ASYNC_CALL(unlink, args[1], UTF8, *path) + ASYNC_CALL(AfterNoArgs, unlink, args[1], UTF8, *path) } else { SYNC_CALL(unlink, *path, *path) } @@ -762,7 +759,7 @@ static void RMDir(const FunctionCallbackInfo& args) { ASSERT_PATH(path) if (args[1]->IsObject()) { - ASYNC_CALL(rmdir, args[1], UTF8, *path) + ASYNC_CALL(AfterNoArgs, rmdir, args[1], UTF8, *path) } else { SYNC_CALL(rmdir, *path, *path) } @@ -782,7 +779,7 @@ static void MKDir(const FunctionCallbackInfo& args) { int mode = static_cast(args[1]->Int32Value()); if (args[2]->IsObject()) { - ASYNC_CALL(mkdir, args[2], UTF8, *path, mode) + ASYNC_CALL(AfterNoArgs, mkdir, args[2], UTF8, *path, mode) } else { SYNC_CALL(mkdir, *path, *path, mode) } @@ -797,7 +794,7 @@ static void RealPath(const FunctionCallbackInfo& args) { const enum encoding encoding = ParseEncoding(env->isolate(), args[1], UTF8); if (args[2]->IsObject()) { - ASYNC_CALL(realpath, args[2], encoding, *path); + ASYNC_CALL(AfterStringPtr, realpath, args[2], encoding, *path); } else { SYNC_CALL(realpath, *path, *path); const char* link_path = static_cast(SYNC_REQ.ptr); @@ -833,7 +830,7 @@ static void ReadDir(const FunctionCallbackInfo& args) { callback = args[2]; if (callback->IsObject()) { - ASYNC_CALL(scandir, callback, encoding, *path, 0 /*flags*/) + ASYNC_CALL(AfterScanDir, scandir, callback, encoding, *path, 0 /*flags*/) } else { SYNC_CALL(scandir, *path, *path, 0 /*flags*/) @@ -902,7 +899,7 @@ static void Open(const FunctionCallbackInfo& args) { int mode = static_cast(args[2]->Int32Value()); if (args[3]->IsObject()) { - ASYNC_CALL(open, args[3], UTF8, *path, flags, mode) + ASYNC_CALL(AfterInteger, open, args[3], UTF8, *path, flags, mode) } else { SYNC_CALL(open, *path, *path, flags, mode) args.GetReturnValue().Set(SYNC_RESULT); @@ -927,7 +924,8 @@ static void CopyFile(const FunctionCallbackInfo& args) { int flags = args[2]->Int32Value(); if (args[3]->IsObject()) { - ASYNC_DEST_CALL(copyfile, args[3], *dest, UTF8, *src, *dest, flags) + ASYNC_DEST_CALL(AfterNoArgs, copyfile, args[3], *dest, + UTF8, *src, *dest, flags) } else { SYNC_DEST_CALL(copyfile, *src, *dest, *src, *dest, flags) } @@ -974,7 +972,7 @@ static void WriteBuffer(const FunctionCallbackInfo& args) { uv_buf_t uvbuf = uv_buf_init(const_cast(buf), len); if (req->IsObject()) { - ASYNC_CALL(write, req, UTF8, fd, &uvbuf, 1, pos) + ASYNC_CALL(AfterInteger, write, req, UTF8, fd, &uvbuf, 1, pos) return; } @@ -1013,7 +1011,7 @@ static void WriteBuffers(const FunctionCallbackInfo& args) { } if (req->IsObject()) { - ASYNC_CALL(write, req, UTF8, fd, *iovs, iovs.length(), pos) + ASYNC_CALL(AfterInteger, write, req, UTF8, fd, *iovs, iovs.length(), pos) return; } @@ -1081,13 +1079,13 @@ static void WriteString(const FunctionCallbackInfo& args) { &uvbuf, 1, pos, - After); + AfterInteger); req_wrap->Dispatched(); if (err < 0) { uv_fs_t* uv_req = req_wrap->req(); uv_req->result = err; uv_req->path = nullptr; - After(uv_req); + AfterInteger(uv_req); return; } @@ -1141,7 +1139,7 @@ static void Read(const FunctionCallbackInfo& args) { req = args[5]; if (req->IsObject()) { - ASYNC_CALL(read, req, UTF8, fd, &uvbuf, 1, pos); + ASYNC_CALL(AfterInteger, read, req, UTF8, fd, &uvbuf, 1, pos); } else { SYNC_CALL(read, 0, fd, &uvbuf, 1, pos) args.GetReturnValue().Set(SYNC_RESULT); @@ -1166,7 +1164,7 @@ static void Chmod(const FunctionCallbackInfo& args) { int mode = static_cast(args[1]->Int32Value()); if (args[2]->IsObject()) { - ASYNC_CALL(chmod, args[2], UTF8, *path, mode); + ASYNC_CALL(AfterNoArgs, chmod, args[2], UTF8, *path, mode); } else { SYNC_CALL(chmod, *path, *path, mode); } @@ -1186,7 +1184,7 @@ static void FChmod(const FunctionCallbackInfo& args) { int mode = static_cast(args[1]->Int32Value()); if (args[2]->IsObject()) { - ASYNC_CALL(fchmod, args[2], UTF8, fd, mode); + ASYNC_CALL(AfterNoArgs, fchmod, args[2], UTF8, fd, mode); } else { SYNC_CALL(fchmod, 0, fd, mode); } @@ -1218,7 +1216,7 @@ static void Chown(const FunctionCallbackInfo& args) { uv_gid_t gid = static_cast(args[2]->Uint32Value()); if (args[3]->IsObject()) { - ASYNC_CALL(chown, args[3], UTF8, *path, uid, gid); + ASYNC_CALL(AfterNoArgs, chown, args[3], UTF8, *path, uid, gid); } else { SYNC_CALL(chown, *path, *path, uid, gid); } @@ -1240,7 +1238,7 @@ static void FChown(const FunctionCallbackInfo& args) { uv_gid_t gid = static_cast(args[2]->Uint32Value()); if (args[3]->IsObject()) { - ASYNC_CALL(fchown, args[3], UTF8, fd, uid, gid); + ASYNC_CALL(AfterNoArgs, fchown, args[3], UTF8, fd, uid, gid); } else { SYNC_CALL(fchown, 0, fd, uid, gid); } @@ -1269,7 +1267,7 @@ static void UTimes(const FunctionCallbackInfo& args) { const double mtime = static_cast(args[2]->NumberValue()); if (args[3]->IsObject()) { - ASYNC_CALL(utime, args[3], UTF8, *path, atime, mtime); + ASYNC_CALL(AfterNoArgs, utime, args[3], UTF8, *path, atime, mtime); } else { SYNC_CALL(utime, *path, *path, atime, mtime); } @@ -1287,7 +1285,7 @@ static void FUTimes(const FunctionCallbackInfo& args) { const double mtime = static_cast(args[2]->NumberValue()); if (args[3]->IsObject()) { - ASYNC_CALL(futime, args[3], UTF8, fd, atime, mtime); + ASYNC_CALL(AfterNoArgs, futime, args[3], UTF8, fd, atime, mtime); } else { SYNC_CALL(futime, 0, fd, atime, mtime); } @@ -1304,7 +1302,7 @@ static void Mkdtemp(const FunctionCallbackInfo& args) { const enum encoding encoding = ParseEncoding(env->isolate(), args[1], UTF8); if (args[2]->IsObject()) { - ASYNC_CALL(mkdtemp, args[2], encoding, *tmpl); + ASYNC_CALL(AfterStringPath, mkdtemp, args[2], encoding, *tmpl); } else { SYNC_CALL(mkdtemp, *tmpl, *tmpl); const char* path = static_cast(SYNC_REQ.path); diff --git a/src/node_file.h b/src/node_file.h index 53515ac7558228..db85451b67a9df 100644 --- a/src/node_file.h +++ b/src/node_file.h @@ -1,24 +1,3 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - #ifndef SRC_NODE_FILE_H_ #define SRC_NODE_FILE_H_ @@ -29,8 +8,11 @@ namespace node { +using v8::Context; +using v8::HandleScope; using v8::Local; using v8::Object; +using v8::Undefined; using v8::Value; namespace fs { @@ -93,6 +75,22 @@ class FSReqWrap: public ReqWrap { DISALLOW_COPY_AND_ASSIGN(FSReqWrap); }; +class FSReqAfterScope { + public: + FSReqAfterScope(FSReqWrap* wrap, uv_fs_t* req); + ~FSReqAfterScope(); + + bool Proceed(); + + void Reject(uv_fs_t* req); + + private: + FSReqWrap* wrap_ = nullptr; + uv_fs_t* req_ = nullptr; + HandleScope handle_scope_; + Context::Scope context_scope_; +}; + } // namespace fs } // namespace node From 7656875e4768b18009512b364325234967709ae9 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 14 Dec 2017 12:35:15 -0800 Subject: [PATCH 3/3] fs: remove unused macro --- src/node_file.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/node_file.cc b/src/node_file.cc index a42f12912a1285..e7ad4900c43797 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -95,10 +95,6 @@ using v8::Object; using v8::String; using v8::Value; -#ifndef MIN -# define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif - #define TYPE_ERROR(msg) env->ThrowTypeError(msg) #define GET_OFFSET(a) ((a)->IsNumber() ? (a)->IntegerValue() : -1)