Revert "src: close libuv handles on exit"
authorBen Noordhuis <info@bnoordhuis.nl>
Fri, 30 Aug 2013 21:21:05 +0000 (23:21 +0200)
committerBen Noordhuis <info@bnoordhuis.nl>
Fri, 30 Aug 2013 21:28:14 +0000 (23:28 +0200)
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
test/simple/test-process-exit-print.js [deleted file]

index 989c025..b8270f7 100644 (file)
@@ -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> object,
              const Handle<Function> callback,
              int argc,
              Handle<Value> argv[]) {
-  if (process_state == SHUTTING_DOWN)
-    return Undefined(node_isolate);
-
   // TODO(trevnorris) Hook for long stack traces to be made here.
   Local<Object> process = PersistentToLocal(node_isolate, process_p);
 
@@ -1725,66 +1714,9 @@ static void InitGroups(const FunctionCallbackInfo<Value>& args) {
 #endif  // __POSIX__ && !defined(__ANDROID__)
 
 
-void MaybeCloseNamedPipe(uv_shutdown_t* req, int status) {
-  uv_handle_t* handle = reinterpret_cast<uv_handle_t*>(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<uv_stream_t*>(handle));
-
-  if (do_shutdown == false) {
-    uv_close(handle, NULL);
-    return;
-  }
-
-  uv_shutdown_t* req = new uv_shutdown_t;
-  uv_stream_t* stream = reinterpret_cast<uv_stream_t*>(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<Value>& 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 (file)
index 3addc73..0000000
+++ /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.
-});