From 634219da2cad87c7c3c7ef6bd09538843c919782 Mon Sep 17 00:00:00 2001 From: Calvin Rose Date: Sun, 17 Jan 2021 20:41:59 -0600 Subject: [PATCH] Fix windows swallowing IOCP events in many cases. This fixes windows hanging on "failed" IO operations. --- src/core/ev.c | 48 +++++++++++++++++++++++------------------------- src/core/os.c | 3 --- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/src/core/ev.c b/src/core/ev.c index 89442ca8..ad51fcd9 100644 --- a/src/core/ev.c +++ b/src/core/ev.c @@ -1024,31 +1024,29 @@ void janet_loop1_impl(int has_timeout, JanetTimestamp to) { } BOOL result = GetQueuedCompletionStatus(janet_vm_iocp, &num_bytes_transfered, &completionKey, &overlapped, (DWORD) waittime); - if (!result) { - if (!has_timeout) { - /* queue emptied */ - } - } else if (0 == completionKey) { - /* Custom event */ - JanetSelfPipeEvent *response = (JanetSelfPipeEvent *)(overlapped); - response->cb(response->msg); - free(response); - janet_ev_dec_refcount(); - } else { - /* Normal event */ - JanetStream *stream = (JanetStream *) completionKey; - JanetListenerState *state = stream->state; - while (state != NULL) { - if (state->tag == overlapped) { - state->event = overlapped; - state->bytes = num_bytes_transfered; - JanetAsyncStatus status = state->machine(state, JANET_ASYNC_EVENT_COMPLETE); - if (status == JANET_ASYNC_STATUS_DONE) { - janet_unlisten(state); + if (result || overlapped) { + if (0 == completionKey) { + /* Custom event */ + JanetSelfPipeEvent *response = (JanetSelfPipeEvent *)(overlapped); + response->cb(response->msg); + free(response); + janet_ev_dec_refcount(); + } else { + /* Normal event */ + JanetStream *stream = (JanetStream *) completionKey; + JanetListenerState *state = stream->state; + while (state != NULL) { + if (state->tag == overlapped) { + state->event = overlapped; + state->bytes = num_bytes_transfered; + JanetAsyncStatus status = state->machine(state, JANET_ASYNC_EVENT_COMPLETE); + if (status == JANET_ASYNC_STATUS_DONE) { + janet_unlisten(state); + } + break; + } else { + state = state->_next; } - break; - } else { - state = state->_next; } } } @@ -1545,7 +1543,7 @@ JanetAsyncStatus ev_machine_read(JanetListenerState *s, JanetAsyncEvent event) { janet_mark(janet_wrap_buffer(state->buf)); break; case JANET_ASYNC_EVENT_CLOSE: - janet_cancel(s->fiber, janet_cstringv("stream closed")); + janet_schedule(s->fiber, janet_wrap_nil()); return JANET_ASYNC_STATUS_DONE; #ifdef JANET_WINDOWS case JANET_ASYNC_EVENT_COMPLETE: { diff --git a/src/core/os.c b/src/core/os.c index 9690c221..aba96dae 100644 --- a/src/core/os.c +++ b/src/core/os.c @@ -524,9 +524,6 @@ static Janet os_proc_close(int32_t argc, Janet *argv) { if (proc->flags & JANET_PROC_OWNS_STDOUT) janet_file_close(proc->out); if (proc->flags & JANET_PROC_OWNS_STDERR) janet_file_close(proc->err); #endif - proc->in = NULL; - proc->out = NULL; - proc->err = NULL; proc->flags &= ~(JANET_PROC_OWNS_STDIN | JANET_PROC_OWNS_STDOUT | JANET_PROC_OWNS_STDERR); if (proc->flags & (JANET_PROC_WAITED | JANET_PROC_WAITING)) { return janet_wrap_nil();