summaryrefslogtreecommitdiff
path: root/src/req_wrap-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/req_wrap-inl.h')
-rw-r--r--src/req_wrap-inl.h43
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