diff options
Diffstat (limited to 'src/req_wrap-inl.h')
-rw-r--r-- | src/req_wrap-inl.h | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/src/req_wrap-inl.h b/src/req_wrap-inl.h index 54abf74430..e3b26c1f5c 100644 --- a/src/req_wrap-inl.h +++ b/src/req_wrap-inl.h @@ -20,6 +20,8 @@ ReqWrap<T>::ReqWrap(Environment* env, // FIXME(bnoordhuis) The fact that a reinterpret_cast is needed is // arguably a good indicator that there should be more than one queue. env->req_wrap_queue()->PushBack(reinterpret_cast<ReqWrap<uv_req_t>*>(this)); + + Reset(); } template <typename T> @@ -34,13 +36,20 @@ void ReqWrap<T>::Dispatched() { } template <typename T> +void ReqWrap<T>::Reset() { + original_callback_ = nullptr; + req_.data = nullptr; +} + +template <typename T> ReqWrap<T>* ReqWrap<T>::from_req(T* req) { return ContainerOf(&ReqWrap<T>::req_, req); } template <typename T> void ReqWrap<T>::Cancel() { - uv_cancel(reinterpret_cast<uv_req_t*>(&req_)); + if (req_.data == this) // Only cancel if already dispatched. + uv_cancel(reinterpret_cast<uv_req_t*>(&req_)); } // Below is dark template magic designed to invoke libuv functions that @@ -95,7 +104,7 @@ struct CallLibuvFunction<ReqT, void(*)(ReqT*, Args...)> { template <typename ReqT, typename T> struct MakeLibuvRequestCallback { static T For(ReqWrap<ReqT>* req_wrap, T v) { - static_assert(!std::is_function<T>::value, + static_assert(!is_callable<T>::value, "MakeLibuvRequestCallback missed a callback"); return v; } @@ -109,6 +118,7 @@ struct MakeLibuvRequestCallback<ReqT, void(*)(ReqT*, Args...)> { static void Wrapper(ReqT* req, Args... args) { ReqWrap<ReqT>* req_wrap = ContainerOf(&ReqWrap<ReqT>::req_, req); + req_wrap->env()->DecreaseWaitingRequestCounter(); F original_callback = reinterpret_cast<F>(req_wrap->original_callback_); original_callback(req, args...); } @@ -128,23 +138,26 @@ int ReqWrap<T>::Dispatch(LibuvFunction fn, Args... args) { // This expands as: // - // return fn(env()->event_loop(), req(), arg1, arg2, Wrapper, arg3, ...) - // ^ ^ ^ - // | | | - // \-- Omitted if `fn` has no | | - // first `uv_loop_t*` argument | | - // | | - // A function callback whose first argument | | - // matches the libuv request type is replaced ---/ | - // by the `Wrapper` method defined above | - // | - // Other (non-function) arguments are passed -----/ - // through verbatim - return CallLibuvFunction<T, LibuvFunction>::Call( + // int err = fn(env()->event_loop(), req(), arg1, arg2, Wrapper, arg3, ...) + // ^ ^ ^ + // | | | + // \-- Omitted if `fn` has no | | + // first `uv_loop_t*` argument | | + // | | + // A function callback whose first argument | | + // matches the libuv request type is replaced ---/ | + // by the `Wrapper` method defined above | + // | + // Other (non-function) arguments are passed -----/ + // through verbatim + int err = CallLibuvFunction<T, LibuvFunction>::Call( fn, env()->event_loop(), req(), MakeLibuvRequestCallback<T, Args>::For(this, args)...); + if (err >= 0) + env()->IncreaseWaitingRequestCounter(); + return err; } } // namespace node |