/* Closes the pipe. */ static MVMint64 do_close(MVMThreadContext *tc, MVMIOSyncPipeData *data) { #ifdef _WIN32 DWORD status = 0; #else int status = 0; #endif if (data->ss.handle == NULL || uv_is_closing((uv_handle_t*)data->ss.handle)) return 0; /* closing the in-/output std filehandle will shutdown the child process. */ uv_unref((uv_handle_t*)data->ss.handle); uv_close((uv_handle_t*)data->ss.handle, NULL); if (data->process) { #ifdef _WIN32 if (!uv_is_closing((uv_handle_t*)data->process)) uv_process_close(tc->loop, data->process); GetExitCodeProcess(data->process->process_handle, &status); status = status << 8; #else pid_t wpid; do wpid = waitpid(data->process->pid, &status, 0); while (wpid == -1 && errno == EINTR); #endif } if (!status && data->process->data) { status = *(MVMint64*)data->process->data; MVM_free(data->process->data); data->process->data = NULL; } uv_unref((uv_handle_t *)data->process); uv_run(tc->loop, UV_RUN_DEFAULT); data->process = NULL; data->ss.handle = NULL; if (data->ss.ds) { MVM_string_decodestream_destroy(tc, data->ss.ds); data->ss.ds = NULL; } return (MVMint64)status; }
void uv_close(uv_handle_t* handle, uv_close_cb cb) { uv_loop_t* loop = handle->loop; if (handle->flags & UV__HANDLE_CLOSING) { assert(0); return; } handle->close_cb = cb; /* Handle-specific close actions */ switch (handle->type) { case UV_TCP: uv_tcp_close(loop, (uv_tcp_t*)handle); return; case UV_NAMED_PIPE: uv_pipe_close(loop, (uv_pipe_t*) handle); return; case UV_TTY: uv_tty_close((uv_tty_t*) handle); return; case UV_UDP: uv_udp_close(loop, (uv_udp_t*) handle); return; case UV_POLL: uv_poll_close(loop, (uv_poll_t*) handle); return; case UV_TIMER: uv_timer_stop((uv_timer_t*)handle); uv__handle_closing(handle); uv_want_endgame(loop, handle); return; case UV_PREPARE: uv_prepare_stop((uv_prepare_t*)handle); uv__handle_closing(handle); uv_want_endgame(loop, handle); return; case UV_CHECK: uv_check_stop((uv_check_t*)handle); uv__handle_closing(handle); uv_want_endgame(loop, handle); return; case UV_IDLE: uv_idle_stop((uv_idle_t*)handle); uv__handle_closing(handle); uv_want_endgame(loop, handle); return; case UV_ASYNC: uv_async_close(loop, (uv_async_t*) handle); return; case UV_SIGNAL: uv_signal_close(loop, (uv_signal_t*) handle); return; case UV_PROCESS: uv_process_close(loop, (uv_process_t*) handle); return; case UV_FS_EVENT: uv_fs_event_close(loop, (uv_fs_event_t*) handle); return; case UV_FS_POLL: uv__fs_poll_close((uv_fs_poll_t*) handle); uv__handle_closing(handle); uv_want_endgame(loop, handle); return; default: /* Not supported */ abort(); } }
void uv_close(uv_handle_t* handle, uv_close_cb cb) { uv_tcp_t* tcp; uv_pipe_t* pipe; uv_udp_t* udp; uv_process_t* process; if (handle->flags & UV_HANDLE_CLOSING) { return; } handle->flags |= UV_HANDLE_CLOSING; handle->close_cb = cb; /* Handle-specific close actions */ switch (handle->type) { case UV_TCP: tcp = (uv_tcp_t*)handle; /* If we don't shutdown before calling closesocket, windows will */ /* silently discard the kernel send buffer and reset the connection. */ if (!(tcp->flags & UV_HANDLE_SHUT)) { shutdown(tcp->socket, SD_SEND); tcp->flags |= UV_HANDLE_SHUT; } tcp->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING); closesocket(tcp->socket); if (tcp->reqs_pending == 0) { uv_want_endgame(handle); } return; case UV_NAMED_PIPE: pipe = (uv_pipe_t*)handle; pipe->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING); close_pipe(pipe, NULL, NULL); if (pipe->reqs_pending == 0) { uv_want_endgame(handle); } return; case UV_UDP: udp = (uv_udp_t*) handle; uv_udp_recv_stop(udp); closesocket(udp->socket); if (udp->reqs_pending == 0) { uv_want_endgame(handle); } return; case UV_TIMER: uv_timer_stop((uv_timer_t*)handle); uv_want_endgame(handle); return; case UV_PREPARE: uv_prepare_stop((uv_prepare_t*)handle); uv_want_endgame(handle); return; case UV_CHECK: uv_check_stop((uv_check_t*)handle); uv_want_endgame(handle); return; case UV_IDLE: uv_idle_stop((uv_idle_t*)handle); uv_want_endgame(handle); return; case UV_ASYNC: if (!((uv_async_t*)handle)->async_sent) { uv_want_endgame(handle); } return; case UV_PROCESS: process = (uv_process_t*)handle; uv_process_close(process); return; default: /* Not supported */ abort(); } }
void uv_close(uv_handle_t* handle, uv_close_cb cb) { uv_pipe_t* pipe; uv_udp_t* udp; uv_process_t* process; uv_loop_t* loop = handle->loop; if (handle->flags & UV_HANDLE_CLOSING) { return; } handle->flags |= UV_HANDLE_CLOSING; handle->close_cb = cb; /* Handle-specific close actions */ switch (handle->type) { case UV_TCP: uv_tcp_close((uv_tcp_t*)handle); return; case UV_NAMED_PIPE: pipe = (uv_pipe_t*)handle; pipe->flags &= ~(UV_HANDLE_READING | UV_HANDLE_LISTENING); close_pipe(pipe, NULL, NULL); if (pipe->reqs_pending == 0) { uv_want_endgame(loop, handle); } return; case UV_TTY: uv_tty_close((uv_tty_t*) handle); return; case UV_UDP: udp = (uv_udp_t*) handle; uv_udp_recv_stop(udp); closesocket(udp->socket); if (udp->reqs_pending == 0) { uv_want_endgame(loop, handle); } return; case UV_POLL: uv_poll_close(handle->loop, (uv_poll_t*) handle); return; case UV_TIMER: uv_timer_stop((uv_timer_t*)handle); uv_want_endgame(loop, handle); return; case UV_PREPARE: uv_prepare_stop((uv_prepare_t*)handle); uv_want_endgame(loop, handle); return; case UV_CHECK: uv_check_stop((uv_check_t*)handle); uv_want_endgame(loop, handle); return; case UV_IDLE: uv_idle_stop((uv_idle_t*)handle); uv_want_endgame(loop, handle); return; case UV_ASYNC: if (!((uv_async_t*)handle)->async_sent) { uv_want_endgame(loop, handle); } return; case UV_PROCESS: process = (uv_process_t*)handle; uv_process_close(loop, process); return; case UV_FS_EVENT: uv_fs_event_close(loop, (uv_fs_event_t*)handle); return; default: /* Not supported */ abort(); } }