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 4915884da6.
pull/41362/head
Ben Noordhuis 2013-08-30 23:21:05 +02:00
parent 8a272cabe2
commit bbed881ec4
2 changed files with 5 additions and 98 deletions

View 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);

View File

@ -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.
});