|
|
@ -52,10 +52,11 @@ static OVERLAPPED g_iocp_custom_overlap; |
|
|
|
|
|
|
|
|
|
|
|
static gpr_event g_shutdown_iocp; |
|
|
|
static gpr_event g_shutdown_iocp; |
|
|
|
static gpr_event g_iocp_done; |
|
|
|
static gpr_event g_iocp_done; |
|
|
|
|
|
|
|
static gpr_atm g_orphans = 0; |
|
|
|
|
|
|
|
|
|
|
|
static HANDLE g_iocp; |
|
|
|
static HANDLE g_iocp; |
|
|
|
|
|
|
|
|
|
|
|
static int do_iocp_work() { |
|
|
|
static void do_iocp_work() { |
|
|
|
BOOL success; |
|
|
|
BOOL success; |
|
|
|
DWORD bytes = 0; |
|
|
|
DWORD bytes = 0; |
|
|
|
DWORD flags = 0; |
|
|
|
DWORD flags = 0; |
|
|
@ -71,14 +72,14 @@ static int do_iocp_work() { |
|
|
|
gpr_time_to_millis(wait_time)); |
|
|
|
gpr_time_to_millis(wait_time)); |
|
|
|
if (!success && !overlapped) { |
|
|
|
if (!success && !overlapped) { |
|
|
|
/* The deadline got attained. */ |
|
|
|
/* The deadline got attained. */ |
|
|
|
return 0; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
GPR_ASSERT(completion_key && overlapped); |
|
|
|
GPR_ASSERT(completion_key && overlapped); |
|
|
|
if (overlapped == &g_iocp_custom_overlap) { |
|
|
|
if (overlapped == &g_iocp_custom_overlap) { |
|
|
|
if (completion_key == (ULONG_PTR) &g_iocp_kick_token) { |
|
|
|
if (completion_key == (ULONG_PTR) &g_iocp_kick_token) { |
|
|
|
/* We were awoken from a kick. */ |
|
|
|
/* We were awoken from a kick. */ |
|
|
|
gpr_log(GPR_DEBUG, "do_iocp_work - got a kick"); |
|
|
|
gpr_log(GPR_DEBUG, "do_iocp_work - got a kick"); |
|
|
|
return 1; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
gpr_log(GPR_ERROR, "Unknown custom completion key."); |
|
|
|
gpr_log(GPR_ERROR, "Unknown custom completion key."); |
|
|
|
abort(); |
|
|
|
abort(); |
|
|
@ -97,8 +98,13 @@ static int do_iocp_work() { |
|
|
|
} |
|
|
|
} |
|
|
|
success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes, |
|
|
|
success = WSAGetOverlappedResult(socket->socket, &info->overlapped, &bytes, |
|
|
|
FALSE, &flags); |
|
|
|
FALSE, &flags); |
|
|
|
gpr_log(GPR_DEBUG, "bytes: %u, flags: %u - op %s", bytes, flags, |
|
|
|
gpr_log(GPR_DEBUG, "bytes: %u, flags: %u - op %s %s", bytes, flags, |
|
|
|
success ? "succeeded" : "failed"); |
|
|
|
success ? "succeeded" : "failed", socket->orphan ? "orphan" : ""); |
|
|
|
|
|
|
|
if (socket->orphan) { |
|
|
|
|
|
|
|
grpc_winsocket_destroy(socket); |
|
|
|
|
|
|
|
gpr_atm_full_fetch_add(&g_orphans, -1); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
info->bytes_transfered = bytes; |
|
|
|
info->bytes_transfered = bytes; |
|
|
|
info->wsa_error = success ? 0 : WSAGetLastError(); |
|
|
|
info->wsa_error = success ? 0 : WSAGetLastError(); |
|
|
|
GPR_ASSERT(overlapped == &info->overlapped); |
|
|
|
GPR_ASSERT(overlapped == &info->overlapped); |
|
|
@ -113,12 +119,10 @@ static int do_iocp_work() { |
|
|
|
} |
|
|
|
} |
|
|
|
gpr_mu_unlock(&socket->state_mu); |
|
|
|
gpr_mu_unlock(&socket->state_mu); |
|
|
|
if (f) f(opaque, 1); |
|
|
|
if (f) f(opaque, 1); |
|
|
|
|
|
|
|
|
|
|
|
return 1; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void iocp_loop(void *p) { |
|
|
|
static void iocp_loop(void *p) { |
|
|
|
while (!gpr_event_get(&g_shutdown_iocp)) { |
|
|
|
while (gpr_atm_acq_load(&g_orphans) || !gpr_event_get(&g_shutdown_iocp)) { |
|
|
|
grpc_maybe_call_delayed_callbacks(NULL, 1); |
|
|
|
grpc_maybe_call_delayed_callbacks(NULL, 1); |
|
|
|
do_iocp_work(); |
|
|
|
do_iocp_work(); |
|
|
|
} |
|
|
|
} |
|
|
@ -138,13 +142,19 @@ void grpc_iocp_init(void) { |
|
|
|
gpr_thd_new(&id, iocp_loop, NULL, NULL); |
|
|
|
gpr_thd_new(&id, iocp_loop, NULL, NULL); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void grpc_iocp_shutdown(void) { |
|
|
|
void grpc_iocp_kick(void) { |
|
|
|
BOOL success; |
|
|
|
BOOL success; |
|
|
|
gpr_event_set(&g_shutdown_iocp, (void *)1); |
|
|
|
|
|
|
|
success = PostQueuedCompletionStatus(g_iocp, 0, |
|
|
|
success = PostQueuedCompletionStatus(g_iocp, 0, |
|
|
|
(ULONG_PTR) &g_iocp_kick_token, |
|
|
|
(ULONG_PTR) &g_iocp_kick_token, |
|
|
|
&g_iocp_custom_overlap); |
|
|
|
&g_iocp_custom_overlap); |
|
|
|
GPR_ASSERT(success); |
|
|
|
GPR_ASSERT(success); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_iocp_shutdown(void) { |
|
|
|
|
|
|
|
BOOL success; |
|
|
|
|
|
|
|
gpr_event_set(&g_shutdown_iocp, (void *)1); |
|
|
|
|
|
|
|
grpc_iocp_kick(); |
|
|
|
gpr_event_wait(&g_iocp_done, gpr_inf_future); |
|
|
|
gpr_event_wait(&g_iocp_done, gpr_inf_future); |
|
|
|
success = CloseHandle(g_iocp); |
|
|
|
success = CloseHandle(g_iocp); |
|
|
|
GPR_ASSERT(success); |
|
|
|
GPR_ASSERT(success); |
|
|
@ -166,6 +176,10 @@ void grpc_iocp_add_socket(grpc_winsocket *socket) { |
|
|
|
GPR_ASSERT(ret == g_iocp); |
|
|
|
GPR_ASSERT(ret == g_iocp); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void grpc_iocp_socket_orphan(grpc_winsocket *socket) { |
|
|
|
|
|
|
|
gpr_atm_full_fetch_add(&g_orphans, 1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void socket_notify_on_iocp(grpc_winsocket *socket, |
|
|
|
static void socket_notify_on_iocp(grpc_winsocket *socket, |
|
|
|
void(*cb)(void *, int), void *opaque, |
|
|
|
void(*cb)(void *, int), void *opaque, |
|
|
|
grpc_winsocket_callback_info *info) { |
|
|
|
grpc_winsocket_callback_info *info) { |
|
|
|