Fix windows swallowing IOCP events in many cases.

This fixes windows hanging on "failed" IO operations.
This commit is contained in:
Calvin Rose 2021-01-17 20:41:59 -06:00
parent fbe3849b4b
commit 634219da2c
2 changed files with 23 additions and 28 deletions

View File

@ -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); BOOL result = GetQueuedCompletionStatus(janet_vm_iocp, &num_bytes_transfered, &completionKey, &overlapped, (DWORD) waittime);
if (!result) { if (result || overlapped) {
if (!has_timeout) { if (0 == completionKey) {
/* queue emptied */ /* Custom event */
} JanetSelfPipeEvent *response = (JanetSelfPipeEvent *)(overlapped);
} else if (0 == completionKey) { response->cb(response->msg);
/* Custom event */ free(response);
JanetSelfPipeEvent *response = (JanetSelfPipeEvent *)(overlapped); janet_ev_dec_refcount();
response->cb(response->msg); } else {
free(response); /* Normal event */
janet_ev_dec_refcount(); JanetStream *stream = (JanetStream *) completionKey;
} else { JanetListenerState *state = stream->state;
/* Normal event */ while (state != NULL) {
JanetStream *stream = (JanetStream *) completionKey; if (state->tag == overlapped) {
JanetListenerState *state = stream->state; state->event = overlapped;
while (state != NULL) { state->bytes = num_bytes_transfered;
if (state->tag == overlapped) { JanetAsyncStatus status = state->machine(state, JANET_ASYNC_EVENT_COMPLETE);
state->event = overlapped; if (status == JANET_ASYNC_STATUS_DONE) {
state->bytes = num_bytes_transfered; janet_unlisten(state);
JanetAsyncStatus status = state->machine(state, JANET_ASYNC_EVENT_COMPLETE); }
if (status == JANET_ASYNC_STATUS_DONE) { break;
janet_unlisten(state); } 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)); janet_mark(janet_wrap_buffer(state->buf));
break; break;
case JANET_ASYNC_EVENT_CLOSE: 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; return JANET_ASYNC_STATUS_DONE;
#ifdef JANET_WINDOWS #ifdef JANET_WINDOWS
case JANET_ASYNC_EVENT_COMPLETE: { case JANET_ASYNC_EVENT_COMPLETE: {

View File

@ -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_STDOUT) janet_file_close(proc->out);
if (proc->flags & JANET_PROC_OWNS_STDERR) janet_file_close(proc->err); if (proc->flags & JANET_PROC_OWNS_STDERR) janet_file_close(proc->err);
#endif #endif
proc->in = NULL;
proc->out = NULL;
proc->err = NULL;
proc->flags &= ~(JANET_PROC_OWNS_STDIN | JANET_PROC_OWNS_STDOUT | JANET_PROC_OWNS_STDERR); proc->flags &= ~(JANET_PROC_OWNS_STDIN | JANET_PROC_OWNS_STDOUT | JANET_PROC_OWNS_STDERR);
if (proc->flags & (JANET_PROC_WAITED | JANET_PROC_WAITING)) { if (proc->flags & (JANET_PROC_WAITED | JANET_PROC_WAITING)) {
return janet_wrap_nil(); return janet_wrap_nil();