From bbed881ec413e8d6d266152c218ebee702d4d526 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 30 Aug 2013 23:21:05 +0200 Subject: [PATCH] Revert "src: close libuv handles on exit" This change is not entirely ready for prime time: it's making ~50 tests fail on Windows, mostly due to timeouts. It's up for debate who is at fault here: node.js or libuv. It does however expose a libuv bug on OS X, where the event loop sometimes gets stuck in uv__io_poll() when there is a single UV_SHUTDOWN request left in the queue. Needs further investigation. This reverts commit 4915884da69814bd4daab22393919a628c9ecf23. --- src/node.cc | 76 +++------------------------------- test/simple/test-process-exit-print.js | 27 ------------ 2 files changed, 5 insertions(+), 98 deletions(-) delete mode 100644 test/simple/test-process-exit-print.js diff --git a/src/node.cc b/src/node.cc index 989c025..b8270f7 100644 --- a/src/node.cc +++ b/src/node.cc @@ -197,14 +197,6 @@ static uv_async_t emit_debug_enabled_async; // Declared in node_internals.h Isolate* node_isolate = NULL; -enum ProcessState { - INITIALIZING, - RUNNING, - SHUTTING_DOWN -}; - -static ProcessState process_state = INITIALIZING; - class ArrayBufferAllocator : public ArrayBuffer::Allocator { public: @@ -1034,9 +1026,6 @@ MakeCallback(const Handle object, const Handle callback, int argc, Handle argv[]) { - if (process_state == SHUTTING_DOWN) - return Undefined(node_isolate); - // TODO(trevnorris) Hook for long stack traces to be made here. Local process = PersistentToLocal(node_isolate, process_p); @@ -1725,66 +1714,9 @@ static void InitGroups(const FunctionCallbackInfo& args) { #endif // __POSIX__ && !defined(__ANDROID__) -void MaybeCloseNamedPipe(uv_shutdown_t* req, int status) { - uv_handle_t* handle = reinterpret_cast(req->handle); - delete req; - - if (status == UV_ECANCELED) { - return; // Already closing. - } - if (status == UV_EPIPE) { - return; // Read end went away before shutdown completed. - } - assert(status == 0); - - if (uv_is_closing(handle)) { - return; - } - - uv_close(handle, NULL); -} - - -void MaybeCloseHandle(uv_handle_t* handle, void* unused) { - if (uv_is_closing(handle)) { - return; - } - - // Named pipes get special treatment: we do a shutdown first to flush - // pending writes. Avoids truncated stdout/stderr output on Windows. - bool do_shutdown = handle->type == UV_NAMED_PIPE && - uv_is_writable(reinterpret_cast(handle)); - - if (do_shutdown == false) { - uv_close(handle, NULL); - return; - } - - uv_shutdown_t* req = new uv_shutdown_t; - uv_stream_t* stream = reinterpret_cast(handle); - int err = uv_shutdown(req, stream, MaybeCloseNamedPipe); - if (err) { - assert(err == UV_ENOTCONN); - delete req; - } -} - - -void DisposeEventLoop(uv_loop_t* loop) { - // Don't call into JS land from now on. - process_state = SHUTTING_DOWN; - // Force-close open handles. - uv_walk(loop, MaybeCloseHandle, NULL); - uv_run(loop, UV_RUN_DEFAULT); - uv_loop_delete(loop); -} - - void Exit(const FunctionCallbackInfo& args) { HandleScope scope(node_isolate); - int32_t exit_code = args[0]->Int32Value(); - DisposeEventLoop(uv_default_loop()); - exit(exit_code); + exit(args[0]->IntegerValue()); } @@ -3238,15 +3170,17 @@ int Start(int argc, char *argv[]) { // there are no watchers on the loop (except for the ones that were // uv_unref'd) then this function exits. As long as there are active // watchers, it blocks. - process_state = RUNNING; uv_run(uv_default_loop(), UV_RUN_DEFAULT); EmitExit(process_l); RunAtExit(); } - DisposeEventLoop(uv_default_loop()); +#ifndef NDEBUG + // Clean up. Not strictly necessary. V8::Dispose(); + uv_loop_delete(uv_default_loop()); +#endif // NDEBUG // Clean up the copy: free(argv_copy); diff --git a/test/simple/test-process-exit-print.js b/test/simple/test-process-exit-print.js deleted file mode 100644 index 3addc73..0000000 --- a/test/simple/test-process-exit-print.js +++ /dev/null @@ -1,27 +0,0 @@ -// 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. - -var common = require('../common'); -var assert = require('assert'); - -process.on('exit', function() { - console.log(''); // Should not assert, see joyent/libuv#911. -}); -- 2.7.4