@ -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 ) {