From 9b20dceb26e1bae0feea2df03412da153bba619c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 4 Nov 2009 15:43:09 +0000 Subject: [PATCH] fixing core API for early shutdown handling --- src/core/core_api.c | 11 +-- src/fs/gnunet-service-fs.c | 117 +++++++++----------------- src/hostlist/gnunet-daemon-hostlist.c | 32 +++++-- src/include/gnunet_core_service.h | 6 +- src/topology/gnunet-daemon-topology.c | 47 ++++++++--- 5 files changed, 105 insertions(+), 108 deletions(-) diff --git a/src/core/core_api.c b/src/core/core_api.c index 91055dd03..febdfaf4b 100644 --- a/src/core/core_api.c +++ b/src/core/core_api.c @@ -804,7 +804,7 @@ transmit_start (void *cls, size_t size, void *buf) * @param timeout after how long should we give up trying to connect to the core service? * @param cls closure for the various callbacks that follow (including handlers in the handlers array) * @param init callback to call on timeout or once we have successfully - * connected to the core service + * connected to the core service; note that timeout is only meaningful if init is not NULL * @param connects function to call on peer connect, can be NULL * @param disconnects function to call on peer disconnect / timeout, can be NULL * @param bfc function to call to fill up spare bandwidth, can be NULL @@ -817,8 +817,10 @@ transmit_start (void *cls, size_t size, void *buf) * GNUNET_MessageHeader and hence we do not need to give it the full message * can be used to improve efficiency, ignored if outbound_notify is NULLL * @param handlers callbacks for messages we care about, NULL-terminated + * @return handle to the core service (only useful for disconnect until 'init' is called); + * NULL on error (in this case, init is never called) */ -void +struct GNUNET_CORE_Handle * GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TIME_Relative timeout, @@ -835,7 +837,6 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, { struct GNUNET_CORE_Handle *h; - GNUNET_assert (init != NULL); h = GNUNET_malloc (sizeof (struct GNUNET_CORE_Handle)); h->sched = sched; h->cfg = cfg; @@ -852,9 +853,8 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, h->client = GNUNET_CLIENT_connect (sched, "core", cfg); if (h->client == NULL) { - init (cls, NULL, NULL, NULL); GNUNET_free (h); - return; + return NULL; } h->startup_timeout = GNUNET_TIME_relative_to_absolute (timeout); h->hcnt = 0; @@ -874,6 +874,7 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, sizeof (uint16_t) * h->hcnt, timeout, GNUNET_YES, &transmit_start, h); + return h; } diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index ca6b9b426..0e592e094 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c @@ -792,6 +792,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *connected_peers; */ static uint64_t max_pending_requests = 32; + /** * Write the current index information list to disk. */ @@ -2326,10 +2327,16 @@ shutdown_task (void *cls, struct IndexInfo *pos; if (NULL != core) - GNUNET_CORE_disconnect (core); - GNUNET_DATASTORE_disconnect (dsh, - GNUNET_NO); - dsh = NULL; + { + GNUNET_CORE_disconnect (core); + core = NULL; + } + if (NULL != dsh) + { + GNUNET_DATASTORE_disconnect (dsh, + GNUNET_NO); + dsh = NULL; + } GNUNET_CONTAINER_multihashmap_iterate (requests_by_query, &destroy_pending_request_cb, NULL); @@ -3274,73 +3281,6 @@ static struct GNUNET_CORE_MessageHandler p2p_handlers[] = }; -/** - * Task that will try to initiate a connection with the - * core service. - * - * @param cls unused - * @param tc unused - */ -static void -core_connect_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); - - -/** - * Function called by the core after we've - * connected. - * - * @param cls closure, unused - * @param server handle to the core service - * @param my_identity our peer identity (unused) - * @param publicKey our public key (unused) - */ -static void -core_start_cb (void *cls, - struct GNUNET_CORE_Handle * server, - const struct GNUNET_PeerIdentity * - my_identity, - const struct - GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded * - publicKey) -{ - if (server == NULL) - { - GNUNET_SCHEDULER_add_delayed (sched, - GNUNET_TIME_UNIT_SECONDS, - &core_connect_task, - NULL); - return; - } - core = server; -} - - -/** - * Task that will try to initiate a connection with the - * core service. - * - * @param cls unused - * @param tc unused - */ -static void -core_connect_task (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - GNUNET_CORE_connect (sched, - cfg, - GNUNET_TIME_UNIT_FOREVER_REL, - NULL, - &core_start_cb, - &peer_connect_handler, - &peer_disconnect_handler, - NULL, - NULL, GNUNET_NO, - NULL, GNUNET_NO, - p2p_handlers); -} - - /** * Process fs requests. * @@ -3366,21 +3306,42 @@ run (void *cls, read_index_list (); dsh = GNUNET_DATASTORE_connect (cfg, sched); - if (NULL == dsh) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to connect to datastore service.\n")); - return; - } + core = GNUNET_CORE_connect (sched, + cfg, + GNUNET_TIME_UNIT_FOREVER_REL, + NULL, + NULL, + &peer_connect_handler, + &peer_disconnect_handler, + NULL, + NULL, GNUNET_NO, + NULL, GNUNET_NO, + p2p_handlers); + GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL); GNUNET_SERVER_add_handlers (server, handlers); - core_connect_task (NULL, NULL); GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); + if (NULL == dsh) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to connect to `%s' service.\n"), + "datastore"); + GNUNET_SCHEDULER_shutdown (sched); + return; + } + if (NULL == core) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to connect to `%s' service.\n"), + "core"); + GNUNET_SCHEDULER_shutdown (sched); + return; + } } diff --git a/src/hostlist/gnunet-daemon-hostlist.c b/src/hostlist/gnunet-daemon-hostlist.c index 78584cac9..2c4aca6d0 100644 --- a/src/hostlist/gnunet-daemon-hostlist.c +++ b/src/hostlist/gnunet-daemon-hostlist.c @@ -70,6 +70,11 @@ static int provide_hostlist; */ static struct GNUNET_STATISTICS_Handle *stats; +/** + * Handle to the core service (NULL until we've connected to it). + */ +struct GNUNET_CORE_Handle *core; + /** * gnunet-daemon-hostlist command line options. */ @@ -119,6 +124,7 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_NO); stats = NULL; } + GNUNET_CORE_disconnect (core); } @@ -167,18 +173,26 @@ run (void *cls, { GNUNET_HOSTLIST_server_start (cfg, sched, stats); } - GNUNET_CORE_connect (sched, cfg, - GNUNET_TIME_UNIT_FOREVER_REL, - NULL, - &core_init, - ch, dh, - NULL, - NULL, GNUNET_NO, - NULL, GNUNET_NO, - handlers); + core = GNUNET_CORE_connect (sched, cfg, + GNUNET_TIME_UNIT_FOREVER_REL, + NULL, + &core_init, + ch, dh, + NULL, + NULL, GNUNET_NO, + NULL, GNUNET_NO, + handlers); GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task, NULL); + if (NULL == core) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to connect to `%s' service.\n"), + "core"); + GNUNET_SCHEDULER_shutdown (sched); + return; + } } diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h index ca02f9874..dbe39d0d7 100644 --- a/src/include/gnunet_core_service.h +++ b/src/include/gnunet_core_service.h @@ -156,7 +156,7 @@ typedef void * @param timeout after how long should we give up trying to connect to the core service? * @param cls closure for the various callbacks that follow (including handlers in the handlers array) * @param init callback to call on timeout or once we have successfully - * connected to the core service + * connected to the core service; note that timeout is only meaningful if init is not NULL * @param connects function to call on peer connect, can be NULL * @param disconnects function to call on peer disconnect / timeout, can be NULL * @param bfc function to call to fill up spare bandwidth, can be NULL @@ -169,8 +169,10 @@ typedef void * GNUNET_MessageHeader and hence we do not need to give it the full message * can be used to improve efficiency, ignored if outbound_notify is NULLL * @param handlers callbacks for messages we care about, NULL-terminated + * @return handle to the core service (only useful for disconnect until 'init' is called), + * NULL on error (in this case, init is never called) */ -void +struct GNUNET_CORE_Handle * GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_TIME_Relative timeout, diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c index cdf3da809..be6f272be 100644 --- a/src/topology/gnunet-daemon-topology.c +++ b/src/topology/gnunet-daemon-topology.c @@ -809,6 +809,7 @@ core_init (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to connect to core service, can not manage topology!\n")); + GNUNET_SCHEDULER_shutdown (sched); return; } handle = server; @@ -1136,8 +1137,11 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_TRANSPORT_disconnect (transport); transport = NULL; - GNUNET_CORE_disconnect (handle); - handle = NULL; + if (handle != NULL) + { + GNUNET_CORE_disconnect (handle); + handle = NULL; + } while (NULL != (pl = friends)) { friends = pl->next; @@ -1208,21 +1212,36 @@ run (void *cls, NULL, NULL, NULL); - GNUNET_CORE_connect (sched, - cfg, - GNUNET_TIME_UNIT_FOREVER_REL, - NULL, - &core_init, - &connect_notify, - &disconnect_notify, - &hello_advertising, - NULL, GNUNET_NO, - NULL, GNUNET_NO, - handlers); - + handle = GNUNET_CORE_connect (sched, + cfg, + GNUNET_TIME_UNIT_FOREVER_REL, + NULL, + &core_init, + &connect_notify, + &disconnect_notify, + &hello_advertising, + NULL, GNUNET_NO, + NULL, GNUNET_NO, + handlers); GNUNET_SCHEDULER_add_delayed (sched, GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task, NULL); + if (NULL == transport) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to connect to `%s' service.\n"), + "transport"); + GNUNET_SCHEDULER_shutdown (sched); + return; + } + if (NULL == handle) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to connect to `%s' service.\n"), + "core"); + GNUNET_SCHEDULER_shutdown (sched); + return; + } } -- 2.25.1