diff options
author | Anna Henningsen <anna@addaleax.net> | 2017-09-04 23:02:55 +0300 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2018-05-10 15:15:16 +0300 |
commit | 17e289eca8f8398243df5c4006d80f7381fd08bc (patch) | |
tree | 781f1398f78aa4b602ae3fca8654c28576e70b52 /src/handle_wrap.cc | |
parent | 5c6cf30143f3191b043ba0b4e814768efa1069f7 (diff) |
src: make CleanupHandles() tear down handles/reqs
Previously, handles would not be closed when the current `Environment`
stopped, which is acceptable in a single-`Environment`-per-process
situation, but would otherwise create memory and file descriptor
leaks.
Also, introduce a generic way to close handles via the
`Environment::CloseHandle()` function, which automatically keeps
track of whether a close callback has been called yet or not.
Many thanks for Stephen Belanger for reviewing the original version of
this commit in the Ayo.js project.
Refs: https://github.com/ayojs/ayo/pull/85
PR-URL: https://github.com/nodejs/node/pull/19377
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/handle_wrap.cc')
-rw-r--r-- | src/handle_wrap.cc | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc index 49bf0c55bea..20356b94a57 100644 --- a/src/handle_wrap.cc +++ b/src/handle_wrap.cc @@ -61,29 +61,40 @@ void HandleWrap::HasRef(const FunctionCallbackInfo<Value>& args) { void HandleWrap::Close(const FunctionCallbackInfo<Value>& args) { - Environment* env = Environment::GetCurrent(args); - HandleWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); - // Guard against uninitialized handle or double close. - if (!IsAlive(wrap)) - return; + wrap->Close(args[0]); +} - if (wrap->state_ != kInitialized) +void HandleWrap::Close(v8::Local<v8::Value> close_callback) { + if (state_ != kInitialized) return; - CHECK_EQ(false, wrap->persistent().IsEmpty()); - uv_close(wrap->handle_, OnClose); - wrap->state_ = kClosing; + CHECK_EQ(false, persistent().IsEmpty()); + uv_close(handle_, OnClose); + state_ = kClosing; - if (args[0]->IsFunction()) { - wrap->object()->Set(env->onclose_string(), args[0]); - wrap->state_ = kClosingWithCallback; + if (!close_callback.IsEmpty() && close_callback->IsFunction()) { + object()->Set(env()->context(), env()->onclose_string(), close_callback) + .FromJust(); + state_ = kClosingWithCallback; } } +void HandleWrap::MarkAsInitialized() { + env()->handle_wrap_queue()->PushBack(this); + state_ = kInitialized; +} + + +void HandleWrap::MarkAsUninitialized() { + handle_wrap_queue_.Remove(); + state_ = kClosed; +} + + HandleWrap::HandleWrap(Environment* env, Local<Object> object, uv_handle_t* handle, @@ -110,6 +121,8 @@ void HandleWrap::OnClose(uv_handle_t* handle) { const bool have_close_callback = (wrap->state_ == kClosingWithCallback); wrap->state_ = kClosed; + wrap->OnClose(); + if (have_close_callback) wrap->MakeCallback(env->onclose_string(), 0, nullptr); |