Skip to content

Commit

Permalink
Close server socket handle when client side closes
Browse files Browse the repository at this point in the history
We've so far relied on the user explicitly doing the `close` call, but
if they forget, the result is a server where new requests just pile up
due to the unclosed handles. Since `.close` is already idempotent (you
can call it many times on an async socket handle without problem), we
can simply close the handle when notified that the client side has
closed without any bad effects on existing code. Meanwhile, code that
doesn't bother will simply work. Change inspired by issue reported at
rakudo/rakudo#1775.
  • Loading branch information
jnthn committed Apr 26, 2018
1 parent 1b78b04 commit 0e9418d
Showing 1 changed file with 26 additions and 23 deletions.
49 changes: 26 additions & 23 deletions src/io/asyncsocket.c
Expand Up @@ -55,33 +55,36 @@ static void on_read(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf) {
MVM_repr_push_o(tc, arr, tc->instance->boot_types.BOOTStr);
});
}
else if (nread == UV_EOF) {
MVMROOT2(tc, t, arr, {
MVMObject *final = MVM_repr_box_int(tc,
tc->instance->boot_types.BOOTInt, ri->seq_number);
MVM_repr_push_o(tc, arr, final);
MVM_repr_push_o(tc, arr, tc->instance->boot_types.BOOTStr);
MVM_repr_push_o(tc, arr, tc->instance->boot_types.BOOTStr);
});
if (buf->base)
MVM_free(buf->base);
uv_read_stop(handle);
MVM_io_eventloop_remove_active_work(tc, &(ri->work_idx));
}
else {
MVM_repr_push_o(tc, arr, tc->instance->boot_types.BOOTInt);
MVM_repr_push_o(tc, arr, tc->instance->boot_types.BOOTStr);
MVMROOT2(tc, t, arr, {
MVMString *msg_str = MVM_string_ascii_decode_nt(tc,
tc->instance->VMString, uv_strerror(nread));
MVMObject *msg_box = MVM_repr_box_str(tc,
tc->instance->boot_types.BOOTStr, msg_str);
MVM_repr_push_o(tc, arr, msg_box);
});
MVMIOAsyncSocketData *handle_data = (MVMIOAsyncSocketData *)ri->handle->body.data;
uv_handle_t *conn_handle = (uv_handle_t *)handle_data->handle;
if (nread == UV_EOF) {
MVMROOT2(tc, t, arr, {
MVMObject *final = MVM_repr_box_int(tc,
tc->instance->boot_types.BOOTInt, ri->seq_number);
MVM_repr_push_o(tc, arr, final);
MVM_repr_push_o(tc, arr, tc->instance->boot_types.BOOTStr);
MVM_repr_push_o(tc, arr, tc->instance->boot_types.BOOTStr);
});
}
else {
MVM_repr_push_o(tc, arr, tc->instance->boot_types.BOOTInt);
MVM_repr_push_o(tc, arr, tc->instance->boot_types.BOOTStr);
MVMROOT2(tc, t, arr, {
MVMString *msg_str = MVM_string_ascii_decode_nt(tc,
tc->instance->VMString, uv_strerror(nread));
MVMObject *msg_box = MVM_repr_box_str(tc,
tc->instance->boot_types.BOOTStr, msg_str);
MVM_repr_push_o(tc, arr, msg_box);
});
}
if (buf->base)
MVM_free(buf->base);
uv_read_stop(handle);
MVM_io_eventloop_remove_active_work(tc, &(ri->work_idx));
if (conn_handle && !uv_is_closing(conn_handle)) {
handle_data->handle = NULL;
uv_close(conn_handle, free_on_close_cb);
}
}
MVM_repr_push_o(tc, t->body.queue, arr);
}
Expand Down

0 comments on commit 0e9418d

Please sign in to comment.