aboutsummaryrefslogtreecommitdiff
path: root/src/util/service.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-02-10 22:12:35 +0100
committerChristian Grothoff <christian@grothoff.org>2019-02-10 22:12:42 +0100
commit7844da7bd860f5b55fe87083a7aa037b95df9ee7 (patch)
tree7d97883a04d09817c5eea4b15580bc64f5500835 /src/util/service.c
parent9e4efa200430f286afc5bd07280b6b3974cfadfc (diff)
downloadgnunet-7844da7bd860f5b55fe87083a7aa037b95df9ee7.tar.gz
gnunet-7844da7bd860f5b55fe87083a7aa037b95df9ee7.zip
fix service shutdown regression
Diffstat (limited to 'src/util/service.c')
-rw-r--r--src/util/service.c80
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 */
382static void
383do_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 */
488static void
489do_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
2748GNUNET_SERVICE_client_mark_monitor (struct GNUNET_SERVICE_Client *c) 2744GNUNET_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