Fixup windows server

pull/3097/head
Craig Tiller 10 years ago
parent fb94111259
commit 063560e3fb
  1. 49
      src/core/iomgr/tcp_server_windows.c

@ -75,18 +75,18 @@ struct grpc_tcp_server {
void *cb_arg;
gpr_mu mu;
gpr_cv cv;
/* active port count: how many ports are actually still listening */
int active_ports;
/* number of iomgr callbacks that have been explicitly scheduled during
* shutdown */
int iomgr_callbacks_pending;
/* all listening ports */
server_port *ports;
size_t nports;
size_t port_capacity;
/* shutdown callback */
void(*shutdown_complete)(void *);
void *shutdown_complete_arg;
};
/* Public function. Allocates the proper data structures to hold a
@ -94,34 +94,41 @@ struct grpc_tcp_server {
grpc_tcp_server *grpc_tcp_server_create(void) {
grpc_tcp_server *s = gpr_malloc(sizeof(grpc_tcp_server));
gpr_mu_init(&s->mu);
gpr_cv_init(&s->cv);
s->active_ports = 0;
s->iomgr_callbacks_pending = 0;
s->cb = NULL;
s->cb_arg = NULL;
s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP);
s->nports = 0;
s->port_capacity = INIT_PORT_CAP;
s->shutdown_complete = NULL;
return s;
}
static void dont_care_about_shutdown_completion(void *arg) {}
/* Public function. Stops and destroys a grpc_tcp_server. */
void grpc_tcp_server_destroy(grpc_tcp_server *s,
void (*shutdown_done)(void *shutdown_done_arg),
void *shutdown_done_arg) {
void (*shutdown_complete)(void *shutdown_done_arg),
void *shutdown_complete_arg) {
size_t i;
int immediately_done = 0;
gpr_mu_lock(&s->mu);
s->shutdown_complete = shutdown_complete
? shutdown_complete
: dont_care_about_shutdown_completion;
s->shutdown_complete_arg = shutdown_complete_arg;
/* First, shutdown all fd's. This will queue abortion calls for all
of the pending accepts due to the normal operation mechanism. */
if (s->active_ports == 0) {
immediately_done = 1;
}
for (i = 0; i < s->nports; i++) {
server_port *sp = &s->ports[i];
sp->shutting_down = 1;
grpc_winsocket_shutdown(sp->socket);
}
/* This happens asynchronously. Wait while that happens. */
while (s->active_ports || s->iomgr_callbacks_pending) {
gpr_cv_wait(&s->cv, &s->mu, gpr_inf_future(GPR_CLOCK_REALTIME));
}
gpr_mu_unlock(&s->mu);
/* Now that the accepts have been aborted, we can destroy the sockets.
@ -134,8 +141,8 @@ void grpc_tcp_server_destroy(grpc_tcp_server *s,
gpr_free(s->ports);
gpr_free(s);
if (shutdown_done) {
shutdown_done(shutdown_done_arg);
if (immediately_done) {
s->shutdown_complete(s->shutdown_complete_arg);
}
}
@ -188,13 +195,19 @@ error:
}
static void decrement_active_ports_and_notify(server_port *sp) {
void(*notify)(void *) = NULL;
void *notify_arg = NULL;
sp->shutting_down = 0;
gpr_mu_lock(&sp->server->mu);
GPR_ASSERT(sp->server->active_ports > 0);
if (0 == --sp->server->active_ports) {
gpr_cv_broadcast(&sp->server->cv);
notify = sp->server->shutdown_complete;
notify_arg = sp->server->shutdown_complete_arg;
}
gpr_mu_unlock(&sp->server->mu);
if (notify != NULL) {
notify(notify_arg);
}
}
/* start_accept will reference that for the IOCP notification request. */
@ -279,12 +292,6 @@ static void on_accept(void *arg, int from_iocp) {
this is necessary in the read/write case, it's useless for the accept
case. We only need to adjust the pending callback count */
if (!from_iocp) {
gpr_mu_lock(&sp->server->mu);
GPR_ASSERT(sp->server->iomgr_callbacks_pending > 0);
if (0 == --sp->server->iomgr_callbacks_pending) {
gpr_cv_broadcast(&sp->server->cv);
}
gpr_mu_unlock(&sp->server->mu);
return;
}

Loading…
Cancel
Save