diff options
Diffstat (limited to 'src/util/server.c')
-rw-r--r-- | src/util/server.c | 152 |
1 files changed, 59 insertions, 93 deletions
diff --git a/src/util/server.c b/src/util/server.c index ff9c8c192..af26d278c 100644 --- a/src/util/server.c +++ b/src/util/server.c | |||
@@ -123,20 +123,15 @@ struct GNUNET_SERVER_Handle | |||
123 | size_t maxbuf; | 123 | size_t maxbuf; |
124 | 124 | ||
125 | /** | 125 | /** |
126 | * Pipe used to signal shutdown of the server. | ||
127 | */ | ||
128 | struct GNUNET_DISK_PipeHandle *shutpipe; | ||
129 | |||
130 | /** | ||
131 | * Socket used to listen for new connections. Set to | 126 | * Socket used to listen for new connections. Set to |
132 | * "-1" by GNUNET_SERVER_destroy to initiate shutdown. | 127 | * "-1" by GNUNET_SERVER_destroy to initiate shutdown. |
133 | */ | 128 | */ |
134 | struct GNUNET_NETWORK_Handle *listen_socket; | 129 | struct GNUNET_NETWORK_Handle *listen_socket; |
135 | 130 | ||
136 | /** | 131 | /** |
137 | * Set to GNUNET_YES if we are shutting down. | 132 | * Task scheduled to do the listening. |
138 | */ | 133 | */ |
139 | int do_shutdown; | 134 | GNUNET_SCHEDULER_TaskIdentifier listen_task; |
140 | 135 | ||
141 | /** | 136 | /** |
142 | * Do we ignore messages of types that we do not | 137 | * Do we ignore messages of types that we do not |
@@ -262,42 +257,6 @@ struct GNUNET_SERVER_Client | |||
262 | 257 | ||
263 | 258 | ||
264 | /** | 259 | /** |
265 | * Server has been asked to shutdown, free resources. | ||
266 | */ | ||
267 | static void | ||
268 | destroy_server (struct GNUNET_SERVER_Handle *server) | ||
269 | { | ||
270 | struct GNUNET_SERVER_Client *pos; | ||
271 | struct HandlerList *hpos; | ||
272 | struct NotifyList *npos; | ||
273 | |||
274 | #if DEBUG_SERVER | ||
275 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n"); | ||
276 | #endif | ||
277 | GNUNET_assert (server->listen_socket == NULL); | ||
278 | if (GNUNET_OK != GNUNET_DISK_pipe_close (server->shutpipe)) | ||
279 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "pipe-close"); | ||
280 | while (server->clients != NULL) | ||
281 | { | ||
282 | pos = server->clients; | ||
283 | server->clients = pos->next; | ||
284 | pos->server = NULL; | ||
285 | } | ||
286 | while (NULL != (hpos = server->handlers)) | ||
287 | { | ||
288 | server->handlers = hpos->next; | ||
289 | GNUNET_free (hpos); | ||
290 | } | ||
291 | while (NULL != (npos = server->disconnect_notify_list)) | ||
292 | { | ||
293 | server->disconnect_notify_list = npos->next; | ||
294 | GNUNET_free (npos); | ||
295 | } | ||
296 | GNUNET_free (server); | ||
297 | } | ||
298 | |||
299 | |||
300 | /** | ||
301 | * Scheduler says our listen socket is ready. | 260 | * Scheduler says our listen socket is ready. |
302 | * Process it! | 261 | * Process it! |
303 | */ | 262 | */ |
@@ -309,26 +268,23 @@ process_listen_socket (void *cls, | |||
309 | struct GNUNET_CONNECTION_Handle *sock; | 268 | struct GNUNET_CONNECTION_Handle *sock; |
310 | struct GNUNET_SERVER_Client *client; | 269 | struct GNUNET_SERVER_Client *client; |
311 | struct GNUNET_NETWORK_FDSet *r; | 270 | struct GNUNET_NETWORK_FDSet *r; |
312 | const struct GNUNET_DISK_FileHandle *shutpipe; | ||
313 | 271 | ||
314 | if ((server->do_shutdown) || | 272 | server->listen_task = GNUNET_SCHEDULER_NO_TASK; |
315 | ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)) | 273 | r = GNUNET_NETWORK_fdset_create (); |
274 | GNUNET_NETWORK_fdset_set (r, server->listen_socket); | ||
275 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | ||
316 | { | 276 | { |
317 | /* shutdown was initiated */ | 277 | server->listen_task = GNUNET_SCHEDULER_add_select (server->sched, |
318 | GNUNET_assert (server->listen_socket != NULL); | 278 | GNUNET_SCHEDULER_PRIORITY_HIGH, |
319 | GNUNET_break (GNUNET_OK == | 279 | GNUNET_SCHEDULER_NO_TASK, |
320 | GNUNET_NETWORK_socket_close (server->listen_socket)); | 280 | GNUNET_TIME_UNIT_FOREVER_REL, |
321 | server->listen_socket = NULL; | 281 | r, NULL, &process_listen_socket, |
322 | if (server->do_shutdown) | 282 | server); |
323 | destroy_server (server); | 283 | GNUNET_NETWORK_fdset_destroy (r); |
324 | return; | 284 | return; /* ignore shutdown, someone else will take care of it! */ |
325 | } | 285 | } |
326 | shutpipe = GNUNET_DISK_pipe_handle (server->shutpipe, | ||
327 | GNUNET_DISK_PIPE_END_READ); | ||
328 | GNUNET_assert (GNUNET_NETWORK_fdset_isset | 286 | GNUNET_assert (GNUNET_NETWORK_fdset_isset |
329 | (tc->read_ready, server->listen_socket)); | 287 | (tc->read_ready, server->listen_socket)); |
330 | GNUNET_assert (!GNUNET_NETWORK_fdset_handle_isset | ||
331 | (tc->read_ready, shutpipe)); | ||
332 | sock = | 288 | sock = |
333 | GNUNET_CONNECTION_create_from_accept (tc->sched, server->access, | 289 | GNUNET_CONNECTION_create_from_accept (tc->sched, server->access, |
334 | server->access_cls, | 290 | server->access_cls, |
@@ -345,14 +301,11 @@ process_listen_socket (void *cls, | |||
345 | GNUNET_SERVER_client_drop (client); | 301 | GNUNET_SERVER_client_drop (client); |
346 | } | 302 | } |
347 | /* listen for more! */ | 303 | /* listen for more! */ |
348 | r = GNUNET_NETWORK_fdset_create (); | 304 | server->listen_task = GNUNET_SCHEDULER_add_select (server->sched, |
349 | GNUNET_NETWORK_fdset_set (r, server->listen_socket); | 305 | GNUNET_SCHEDULER_PRIORITY_HIGH, |
350 | GNUNET_NETWORK_fdset_handle_set (r, shutpipe); | 306 | GNUNET_SCHEDULER_NO_TASK, |
351 | GNUNET_SCHEDULER_add_select (server->sched, | 307 | GNUNET_TIME_UNIT_FOREVER_REL, |
352 | GNUNET_SCHEDULER_PRIORITY_HIGH, | 308 | r, NULL, &process_listen_socket, server); |
353 | GNUNET_SCHEDULER_NO_TASK, | ||
354 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
355 | r, NULL, &process_listen_socket, server); | ||
356 | GNUNET_NETWORK_fdset_destroy (r); | 309 | GNUNET_NETWORK_fdset_destroy (r); |
357 | } | 310 | } |
358 | 311 | ||
@@ -454,12 +407,6 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched, | |||
454 | return NULL; | 407 | return NULL; |
455 | } | 408 | } |
456 | ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle)); | 409 | ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle)); |
457 | if (NULL == (ret->shutpipe = GNUNET_DISK_pipe (GNUNET_NO))) | ||
458 | { | ||
459 | GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (lsock)); | ||
460 | GNUNET_free (ret); | ||
461 | return NULL; | ||
462 | } | ||
463 | ret->sched = sched; | 410 | ret->sched = sched; |
464 | ret->maxbuf = maxbuf; | 411 | ret->maxbuf = maxbuf; |
465 | ret->idle_timeout = idle_timeout; | 412 | ret->idle_timeout = idle_timeout; |
@@ -471,14 +418,11 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched, | |||
471 | { | 418 | { |
472 | r = GNUNET_NETWORK_fdset_create (); | 419 | r = GNUNET_NETWORK_fdset_create (); |
473 | GNUNET_NETWORK_fdset_set (r, ret->listen_socket); | 420 | GNUNET_NETWORK_fdset_set (r, ret->listen_socket); |
474 | GNUNET_NETWORK_fdset_handle_set (r, | 421 | ret->listen_task = GNUNET_SCHEDULER_add_select (sched, |
475 | GNUNET_DISK_pipe_handle (ret->shutpipe, | 422 | GNUNET_SCHEDULER_PRIORITY_HIGH, |
476 | GNUNET_DISK_PIPE_END_READ)); | 423 | GNUNET_SCHEDULER_NO_TASK, |
477 | GNUNET_SCHEDULER_add_select (sched, | 424 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, |
478 | GNUNET_SCHEDULER_PRIORITY_HIGH, | 425 | &process_listen_socket, ret); |
479 | GNUNET_SCHEDULER_NO_TASK, | ||
480 | GNUNET_TIME_UNIT_FOREVER_REL, r, NULL, | ||
481 | &process_listen_socket, ret); | ||
482 | GNUNET_NETWORK_fdset_destroy (r); | 426 | GNUNET_NETWORK_fdset_destroy (r); |
483 | } | 427 | } |
484 | return ret; | 428 | return ret; |
@@ -491,18 +435,40 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched, | |||
491 | void | 435 | void |
492 | GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s) | 436 | GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s) |
493 | { | 437 | { |
494 | static char c; | 438 | struct GNUNET_SERVER_Client *pos; |
495 | 439 | struct HandlerList *hpos; | |
496 | GNUNET_assert (s->do_shutdown == GNUNET_NO); | 440 | struct NotifyList *npos; |
497 | s->do_shutdown = GNUNET_YES; | 441 | |
498 | if (s->listen_socket == NULL) | 442 | #if DEBUG_SERVER |
499 | destroy_server (s); | 443 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Server shutting down.\n"); |
500 | else | 444 | #endif |
501 | GNUNET_break (1 == | 445 | if (GNUNET_SCHEDULER_NO_TASK != s->listen_task) |
502 | GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle | 446 | { |
503 | (s->shutpipe, | 447 | GNUNET_SCHEDULER_cancel (s->sched, |
504 | GNUNET_DISK_PIPE_END_WRITE), &c, | 448 | s->listen_task); |
505 | sizeof (c))); | 449 | s->listen_task = GNUNET_SCHEDULER_NO_TASK; |
450 | } | ||
451 | GNUNET_break (GNUNET_OK == | ||
452 | GNUNET_NETWORK_socket_close (s->listen_socket)); | ||
453 | s->listen_socket = NULL; | ||
454 | while (s->clients != NULL) | ||
455 | { | ||
456 | pos = s->clients; | ||
457 | s->clients = pos->next; | ||
458 | pos->server = NULL; | ||
459 | } | ||
460 | while (NULL != (hpos = s->handlers)) | ||
461 | { | ||
462 | s->handlers = hpos->next; | ||
463 | GNUNET_free (hpos); | ||
464 | } | ||
465 | while (NULL != (npos = s->disconnect_notify_list)) | ||
466 | { | ||
467 | s->disconnect_notify_list = npos->next; | ||
468 | GNUNET_free (npos); | ||
469 | } | ||
470 | GNUNET_free (s); | ||
471 | |||
506 | } | 472 | } |
507 | 473 | ||
508 | 474 | ||