diff options
author | Christian Grothoff <christian@grothoff.org> | 2019-02-10 22:12:35 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2019-02-10 22:12:42 +0100 |
commit | 7844da7bd860f5b55fe87083a7aa037b95df9ee7 (patch) | |
tree | 7d97883a04d09817c5eea4b15580bc64f5500835 /src | |
parent | 9e4efa200430f286afc5bd07280b6b3974cfadfc (diff) | |
download | gnunet-7844da7bd860f5b55fe87083a7aa037b95df9ee7.tar.gz gnunet-7844da7bd860f5b55fe87083a7aa037b95df9ee7.zip |
fix service shutdown regression
Diffstat (limited to 'src')
-rw-r--r-- | src/util/service.c | 80 |
1 files changed, 38 insertions, 42 deletions
diff --git a/src/util/service.c b/src/util/service.c index ee140f88e..5117f006f 100644 --- a/src/util/service.c +++ b/src/util/service.c | |||
@@ -214,12 +214,6 @@ struct GNUNET_SERVICE_Handle | |||
214 | int match_gid; | 214 | int match_gid; |
215 | 215 | ||
216 | /** | 216 | /** |
217 | * Set to #GNUNET_YES if we got a shutdown signal and terminate | ||
218 | * the service if #have_non_monitor_clients() returns #GNUNET_YES. | ||
219 | */ | ||
220 | int got_shutdown; | ||
221 | |||
222 | /** | ||
223 | * Are we suspended, and if so, why? | 217 | * Are we suspended, and if so, why? |
224 | */ | 218 | */ |
225 | enum SuspendReason suspend_state; | 219 | enum SuspendReason suspend_state; |
@@ -379,6 +373,32 @@ have_non_monitor_clients (struct GNUNET_SERVICE_Handle *sh) | |||
379 | 373 | ||
380 | 374 | ||
381 | /** | 375 | /** |
376 | * Suspend accepting connections from the listen socket temporarily. | ||
377 | * Resume activity using #do_resume. | ||
378 | * | ||
379 | * @param sh service to stop accepting connections. | ||
380 | * @param sr reason for suspending accepting connections | ||
381 | */ | ||
382 | static void | ||
383 | do_suspend (struct GNUNET_SERVICE_Handle *sh, | ||
384 | enum SuspendReason sr) | ||
385 | { | ||
386 | struct ServiceListenContext *slc; | ||
387 | |||
388 | GNUNET_assert (0 == (sh->suspend_state & sr)); | ||
389 | sh->suspend_state |= sr; | ||
390 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) | ||
391 | { | ||
392 | if (NULL != slc->listen_task) | ||
393 | { | ||
394 | GNUNET_SCHEDULER_cancel (slc->listen_task); | ||
395 | slc->listen_task = NULL; | ||
396 | } | ||
397 | } | ||
398 | } | ||
399 | |||
400 | |||
401 | /** | ||
382 | * Shutdown task triggered when a service should be terminated. | 402 | * Shutdown task triggered when a service should be terminated. |
383 | * This considers active clients and the service options to see | 403 | * This considers active clients and the service options to see |
384 | * how this specific service is to be terminated, and depending | 404 | * how this specific service is to be terminated, and depending |
@@ -402,8 +422,9 @@ service_shutdown (void *cls) | |||
402 | GNUNET_assert (0); | 422 | GNUNET_assert (0); |
403 | break; | 423 | break; |
404 | case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: | 424 | case GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN: |
405 | sh->got_shutdown = GNUNET_YES; | 425 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) |
406 | GNUNET_SERVICE_suspend (sh); | 426 | do_suspend (sh, |
427 | SUSPEND_STATE_SHUTDOWN); | ||
407 | if (GNUNET_NO == have_non_monitor_clients (sh)) | 428 | if (GNUNET_NO == have_non_monitor_clients (sh)) |
408 | GNUNET_SERVICE_shutdown (sh); | 429 | GNUNET_SERVICE_shutdown (sh); |
409 | break; | 430 | break; |
@@ -479,32 +500,6 @@ NEXT: | |||
479 | 500 | ||
480 | 501 | ||
481 | /** | 502 | /** |
482 | * Suspend accepting connections from the listen socket temporarily. | ||
483 | * Resume activity using #do_resume. | ||
484 | * | ||
485 | * @param sh service to stop accepting connections. | ||
486 | * @param sr reason for suspending accepting connections | ||
487 | */ | ||
488 | static void | ||
489 | do_suspend (struct GNUNET_SERVICE_Handle *sh, | ||
490 | enum SuspendReason sr) | ||
491 | { | ||
492 | struct ServiceListenContext *slc; | ||
493 | |||
494 | GNUNET_assert (0 == (sh->suspend_state & sr)); | ||
495 | sh->suspend_state |= sr; | ||
496 | for (slc = sh->slc_head; NULL != slc; slc = slc->next) | ||
497 | { | ||
498 | if (NULL != slc->listen_task) | ||
499 | { | ||
500 | GNUNET_SCHEDULER_cancel (slc->listen_task); | ||
501 | slc->listen_task = NULL; | ||
502 | } | ||
503 | } | ||
504 | } | ||
505 | |||
506 | |||
507 | /** | ||
508 | * Task run when we are ready to transmit data to the | 503 | * Task run when we are ready to transmit data to the |
509 | * client. | 504 | * client. |
510 | * | 505 | * |
@@ -838,7 +833,7 @@ accept_client (void *cls) | |||
838 | if (EMFILE == errno) | 833 | if (EMFILE == errno) |
839 | do_suspend (sh, | 834 | do_suspend (sh, |
840 | SUSPEND_STATE_EMFILE); | 835 | SUSPEND_STATE_EMFILE); |
841 | else | 836 | else if (EAGAIN != errno) |
842 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, | 837 | GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, |
843 | "accept"); | 838 | "accept"); |
844 | break; | 839 | break; |
@@ -2633,7 +2628,8 @@ finish_client_drop (void *cls) | |||
2633 | { | 2628 | { |
2634 | GNUNET_break (GNUNET_OK == | 2629 | GNUNET_break (GNUNET_OK == |
2635 | GNUNET_NETWORK_socket_close (c->sock)); | 2630 | GNUNET_NETWORK_socket_close (c->sock)); |
2636 | if (0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) | 2631 | if ( (0 != (SUSPEND_STATE_EMFILE & sh->suspend_state)) && |
2632 | (0 == (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) ) | ||
2637 | do_resume (sh, | 2633 | do_resume (sh, |
2638 | SUSPEND_STATE_EMFILE); | 2634 | SUSPEND_STATE_EMFILE); |
2639 | } | 2635 | } |
@@ -2642,7 +2638,7 @@ finish_client_drop (void *cls) | |||
2642 | GNUNET_NETWORK_socket_free_memory_only_ (c->sock); | 2638 | GNUNET_NETWORK_socket_free_memory_only_ (c->sock); |
2643 | } | 2639 | } |
2644 | GNUNET_free (c); | 2640 | GNUNET_free (c); |
2645 | if ( (GNUNET_YES == sh->got_shutdown) && | 2641 | if ( (0 != (SUSPEND_STATE_SHUTDOWN & sh->suspend_state)) && |
2646 | (GNUNET_NO == have_non_monitor_clients (sh)) ) | 2642 | (GNUNET_NO == have_non_monitor_clients (sh)) ) |
2647 | GNUNET_SERVICE_shutdown (sh); | 2643 | GNUNET_SERVICE_shutdown (sh); |
2648 | } | 2644 | } |
@@ -2724,9 +2720,9 @@ GNUNET_SERVICE_shutdown (struct GNUNET_SERVICE_Handle *sh) | |||
2724 | { | 2720 | { |
2725 | struct GNUNET_SERVICE_Client *client; | 2721 | struct GNUNET_SERVICE_Client *client; |
2726 | 2722 | ||
2727 | do_suspend (sh, | 2723 | if (0 == (sh->suspend_state & SUSPEND_STATE_SHUTDOWN)) |
2728 | SUSPEND_STATE_SHUTDOWN); | 2724 | do_suspend (sh, |
2729 | sh->got_shutdown = GNUNET_NO; | 2725 | SUSPEND_STATE_SHUTDOWN); |
2730 | while (NULL != (client = sh->clients_head)) | 2726 | while (NULL != (client = sh->clients_head)) |
2731 | GNUNET_SERVICE_client_drop (client); | 2727 | GNUNET_SERVICE_client_drop (client); |
2732 | } | 2728 | } |
@@ -2748,8 +2744,8 @@ void | |||
2748 | GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c) | 2744 | GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c) |
2749 | { | 2745 | { |
2750 | c->is_monitor = GNUNET_YES; | 2746 | c->is_monitor = GNUNET_YES; |
2751 | if ( (GNUNET_YES == c->sh->got_shutdown) && | 2747 | if ( (0 != (SUSPEND_STATE_SHUTDOWN & c->sh->suspend_state) && |
2752 | (GNUNET_NO == have_non_monitor_clients (c->sh)) ) | 2748 | (GNUNET_NO == have_non_monitor_clients (c->sh)) ) ) |
2753 | GNUNET_SERVICE_shutdown (c->sh); | 2749 | GNUNET_SERVICE_shutdown (c->sh); |
2754 | } | 2750 | } |
2755 | 2751 | ||