@ -43,12 +43,12 @@
# include "src/core/iomgr/pollset.h"
# include "src/core/iomgr/pollset_windows.h"
static gpr_mu g_polling_mu ;
gpr_mu grpc _polling_mu ;
static grpc_pollset_worker * g_active_poller ;
static grpc_pollset_worker g_global_root_worker ;
void grpc_pollset_global_init ( ) {
gpr_mu_init ( & g_polling_mu ) ;
gpr_mu_init ( & grpc _polling_mu ) ;
g_active_poller = NULL ;
g_global_root_worker . links [ GRPC_POLLSET_WORKER_LINK_GLOBAL ] . next =
g_global_root_worker . links [ GRPC_POLLSET_WORKER_LINK_GLOBAL ] . prev =
@ -56,7 +56,7 @@ void grpc_pollset_global_init() {
}
void grpc_pollset_global_shutdown ( ) {
gpr_mu_destroy ( & g_polling_mu ) ;
gpr_mu_destroy ( & grpc _polling_mu ) ;
}
static void remove_worker ( grpc_pollset_worker * worker ,
@ -108,7 +108,6 @@ static void push_front_worker(grpc_pollset_worker *root,
void grpc_pollset_init ( grpc_pollset * pollset ) {
memset ( pollset , 0 , sizeof ( * pollset ) ) ;
gpr_mu_init ( & pollset - > mu ) ;
pollset - > root_worker . links [ GRPC_POLLSET_WORKER_LINK_POLLSET ] . next =
pollset - > root_worker . links [ GRPC_POLLSET_WORKER_LINK_POLLSET ] . prev =
& pollset - > root_worker ;
@ -116,7 +115,7 @@ void grpc_pollset_init(grpc_pollset *pollset) {
void grpc_pollset_shutdown ( grpc_exec_ctx * exec_ctx , grpc_pollset * pollset ,
grpc_closure * closure ) {
gpr_mu_lock ( & pollset - > mu ) ;
gpr_mu_lock ( & grpc_polling_ mu) ;
pollset - > shutting_down = 1 ;
grpc_pollset_kick ( pollset , GRPC_POLLSET_KICK_BROADCAST ) ;
if ( ! pollset - > is_iocp_worker ) {
@ -124,11 +123,10 @@ void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
} else {
pollset - > on_shutdown = closure ;
}
gpr_mu_unlock ( & pollset - > mu ) ;
gpr_mu_unlock ( & grpc_polling_ mu) ;
}
void grpc_pollset_destroy ( grpc_pollset * pollset ) {
gpr_mu_destroy ( & pollset - > mu ) ;
}
void grpc_pollset_work ( grpc_exec_ctx * exec_ctx , grpc_pollset * pollset ,
@ -140,29 +138,31 @@ void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
worker - > links [ GRPC_POLLSET_WORKER_LINK_GLOBAL ] . next =
worker - > links [ GRPC_POLLSET_WORKER_LINK_GLOBAL ] . prev =
NULL ;
worker - > kicked = 0 ;
worker - > pollset = pollset ;
gpr_cv_init ( & worker - > cv ) ;
if ( grpc_alarm_check ( exec_ctx , now , & deadline ) ) {
goto done ;
}
if ( ! pollset - > kicked_without_pollers & & ! pollset - > shutting_down ) {
gpr_mu_lock ( & g_polling_mu ) ;
if ( g_active_poller = = NULL ) {
grpc_pollset_worker * next_worker ;
/* become poller */
pollset - > is_iocp_worker = 1 ;
g_active_poller = worker ;
gpr_mu_unlock ( & g_polling_mu ) ;
gpr_mu_unlock ( & pollset - > mu ) ;
gpr_mu_unlock ( & grpc_polling_mu ) ;
grpc_iocp_work ( exec_ctx , deadline ) ;
gpr_mu_lock ( & pollset - > mu ) ;
gpr_mu_lock ( & g_polling_mu ) ;
gpr_mu_lock ( & grpc_polling_mu ) ;
pollset - > is_iocp_worker = 0 ;
g_active_poller = NULL ;
/* try to get a worker from this pollsets worker list */
next_worker = pop_front_worker ( & pollset - > root_worker , GRPC_POLLSET_WORKER_LINK_POLLSET ) ;
/* try to get a worker from the global list */
next_worker = pop_front_worker ( & g_global_root_worker , GRPC_POLLSET_WORKER_LINK_GLOBAL ) ;
if ( next_worker ! = NULL ) {
next_worker - > kicked = 1 ;
gpr_cv_signal ( & next_worker - > cv ) ;
}
gpr_mu_unlock ( & g_polling_mu ) ;
if ( pollset - > shutting_down & & pollset - > on_shutdown ! = NULL ) {
grpc_exec_ctx_enqueue ( exec_ctx , pollset - > on_shutdown , 1 ) ;
@ -171,18 +171,21 @@ void grpc_pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
goto done ;
}
push_front_worker ( & g_global_root_worker , GRPC_POLLSET_WORKER_LINK_GLOBAL , worker ) ;
gpr_mu_unlock ( & g_polling_mu ) ;
push_front_worker ( & pollset - > root_worker , GRPC_POLLSET_WORKER_LINK_POLLSET , worker ) ;
added_worker = 1 ;
gpr_cv_wait ( & worker - > cv , & pollset - > mu , deadline ) ;
while ( ! worker - > kicked ) {
if ( gpr_cv_wait ( & worker - > cv , & grpc_polling_mu , deadline ) ) {
break ;
}
}
} else {
pollset - > kicked_without_pollers = 0 ;
}
done :
if ( ! grpc_closure_list_empty ( exec_ctx - > closure_list ) ) {
gpr_mu_unlock ( & pollset - > mu ) ;
gpr_mu_unlock ( & grpc_polling_ mu) ;
grpc_exec_ctx_flush ( exec_ctx ) ;
gpr_mu_lock ( & pollset - > mu ) ;
gpr_mu_lock ( & grpc_polling_ mu) ;
}
if ( added_worker ) {
remove_worker ( worker , GRPC_POLLSET_WORKER_LINK_GLOBAL ) ;
@ -197,6 +200,7 @@ void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) {
for ( specific_worker = p - > root_worker . links [ GRPC_POLLSET_WORKER_LINK_POLLSET ] . next ;
specific_worker ! = & p - > root_worker ;
specific_worker = specific_worker - > links [ GRPC_POLLSET_WORKER_LINK_POLLSET ] . next ) {
specific_worker - > kicked = 1 ;
gpr_cv_signal ( & specific_worker - > cv ) ;
}
p - > kicked_without_pollers = 1 ;
@ -205,12 +209,11 @@ void grpc_pollset_kick(grpc_pollset *p, grpc_pollset_worker *specific_worker) {
}
} else {
if ( p - > is_iocp_worker ) {
gpr_mu_lock ( & g_polling_mu ) ;
if ( g_active_poller = = specific_worker ) {
grpc_iocp_kick ( ) ;
}
gpr_mu_unlock ( & g_polling_mu ) ;
} else {
specific_worker - > kicked = 1 ;
gpr_cv_signal ( & specific_worker - > cv ) ;
}
}