From: Sree Harsha Totakura Date: Mon, 16 Jul 2012 18:58:55 +0000 (+0000) Subject: extended HELPER api to notify when child crashes X-Git-Tag: initial-import-from-subversion-38251~12456 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=717bd5e03fbc05b7bb1f621033eabb785750d03f;p=oweals%2Fgnunet.git extended HELPER api to notify when child crashes --- diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c index 644f2e1c8..570f742d8 100644 --- a/src/dns/gnunet-service-dns.c +++ b/src/dns/gnunet-service-dns.c @@ -1656,7 +1656,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, hijacker = GNUNET_HELPER_start ("gnunet-helper-dns", helper_argv, &process_helper_messages, - NULL); + NULL, NULL); GNUNET_SERVER_add_handlers (server, handlers); GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL); } diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c index e9e961fd5..2614ba908 100644 --- a/src/exit/gnunet-daemon-exit.c +++ b/src/exit/gnunet-daemon-exit.c @@ -3213,7 +3213,8 @@ run (void *cls, char *const *args GNUNET_UNUSED, } helper_handle = GNUNET_HELPER_start ("gnunet-helper-exit", exit_argv, - &message_token, NULL); + &message_token, + NULL, NULL); } diff --git a/src/fs/fs_dirmetascan.c b/src/fs/fs_dirmetascan.c index 6dac690ff..3e2512206 100644 --- a/src/fs/fs_dirmetascan.c +++ b/src/fs/fs_dirmetascan.c @@ -457,7 +457,7 @@ GNUNET_FS_directory_scan_start (const char *filename, ds->helper = GNUNET_HELPER_start ("gnunet-helper-fs-publish", ds->args, &process_helper_msgs, - ds); + NULL, ds); if (NULL == ds->helper) { GNUNET_free (filename_expanded); diff --git a/src/include/gnunet_helper_lib.h b/src/include/gnunet_helper_lib.h index 9c1bc21e2..2756cdf4e 100644 --- a/src/include/gnunet_helper_lib.h +++ b/src/include/gnunet_helper_lib.h @@ -24,6 +24,7 @@ * @author Philipp Toelke * @author Christian Grothoff */ + #ifndef GNUNET_HELPER_LIB_H #define GNUNET_HELPER_LIB_H @@ -37,24 +38,43 @@ struct GNUNET_HELPER_Handle; /** - * @brief Starts a helper and begins reading from it + * Callback that will be called when the helper process dies. This is not called + * when the helper process is stoped using GNUNET_HELPER_stop() + * + * @param cls the closure from GNUNET_HELPER_start() + * @param h the handle representing the helper process. This handle is invalid + * in this callback. It is only presented for reference. No operations + * can be performed using it. + */ +typedef void (*GNUNET_HELPER_ExceptionCallback) (void *cls, + const struct GNUNET_HELPER_Handle *h); + + +/** + * Starts a helper and begins reading from it. The helper process is + * restarted when it dies except when it is stopped using GNUNET_HELPER_stop() + * or when the exp_cb callback is not NULL. * * @param binary_name name of the binary to run * @param binary_argv NULL-terminated list of arguments to give when starting the binary (this * argument must not be modified by the client for * the lifetime of the helper handle) * @param cb function to call if we get messages from the helper - * @param cb_cls Closure for the callback + * @param exp_cb the exception callback to call. Set this to NULL if the helper + * process has to be restarted automatically when it dies/crashes + * @param cb_cls closure for the above callbacks * @return the new Handle, NULL on error */ struct GNUNET_HELPER_Handle * GNUNET_HELPER_start (const char *binary_name, char *const binary_argv[], - GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls); + GNUNET_SERVER_MessageTokenizerCallback cb, + GNUNET_HELPER_ExceptionCallback exp_cb, + void *cb_cls); /** - * @brief Kills the helper, closes the pipe and frees the handle + * Kills the helper, closes the pipe and frees the handle * * @param h handle to helper to stop */ diff --git a/src/testbed/test_gnunet_testbed_helper.c b/src/testbed/test_gnunet_testbed_helper.c index a2f8936ab..654e5dd3e 100644 --- a/src/testbed/test_gnunet_testbed_helper.c +++ b/src/testbed/test_gnunet_testbed_helper.c @@ -151,7 +151,7 @@ run (void *cls, char *const *args, const char *cfgfile, helper = GNUNET_HELPER_start ("gnunet-testbed-helper", binary_argv, - NULL, NULL); + NULL, NULL, NULL); GNUNET_assert (NULL != helper); cfg = GNUNET_CONFIGURATION_dup (cfg2); config = GNUNET_CONFIGURATION_serialize (cfg, &config_size); diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index c2565a4a8..2d786e2a9 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c @@ -1713,6 +1713,7 @@ libgnunet_plugin_transport_wlan_init (void *cls) plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan", plugin->helper_argv, &handle_helper_message, + NULL, plugin); break; case 1: /* testmode, peer 1 */ @@ -1722,6 +1723,7 @@ libgnunet_plugin_transport_wlan_init (void *cls) plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan-dummy", plugin->helper_argv, &handle_helper_message, + NULL, plugin); break; case 2: /* testmode, peer 2 */ @@ -1731,6 +1733,7 @@ libgnunet_plugin_transport_wlan_init (void *cls) plugin->suid_helper = GNUNET_HELPER_start ("gnunet-helper-transport-wlan-dummy", plugin->helper_argv, &handle_helper_message, + NULL, plugin); break; default: diff --git a/src/util/helper.c b/src/util/helper.c index 16b3465c0..3fe3705b1 100644 --- a/src/util/helper.c +++ b/src/util/helper.c @@ -108,6 +108,16 @@ struct GNUNET_HELPER_Handle */ struct GNUNET_SERVER_MessageStreamTokenizer *mst; + /** + * The exception callback + */ + GNUNET_HELPER_ExceptionCallback exp_cb; + + /** + * The closure for callbacks + */ + void *cb_cls; + /** * First message queued for transmission to helper. */ @@ -244,11 +254,16 @@ helper_read (void *cls, _("Error reading from `%s': %s\n"), h->binary_name, STRERROR (errno)); + if (NULL != h->exp_cb) + { + h->exp_cb (h->cb_cls, h); + GNUNET_HELPER_stop (h); + return; + } stop_helper (h); /* Restart the helper */ h->restart_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &restart_task, h); + GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &restart_task, h); return; } if (0 == t) @@ -258,6 +273,12 @@ helper_read (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Got 0 bytes from helper `%s' (EOF)\n"), h->binary_name); + if (NULL != h->exp_cb) + { + h->exp_cb (h->cb_cls, h); + GNUNET_HELPER_stop (h); + return; + } stop_helper (h); /* Restart the helper */ h->restart_task = @@ -277,6 +298,12 @@ helper_read (void *cls, GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Failed to parse inbound message from helper `%s'\n"), h->binary_name); + if (NULL != h->exp_cb) + { + h->exp_cb (h->cb_cls, h); + GNUNET_HELPER_stop (h); + return; + } stop_helper (h); /* Restart the helper */ h->restart_task = @@ -354,27 +381,35 @@ restart_task (void *cls, /** - * @brief Starts a helper and begins reading from it + * Starts a helper and begins reading from it. The helper process is + * restarted when it dies except when it is stopped using GNUNET_HELPER_stop() + * or when the exp_cb callback is not NULL. * * @param binary_name name of the binary to run * @param binary_argv NULL-terminated list of arguments to give when starting the binary (this * argument must not be modified by the client for - * the lifetime of the helper h) + * the lifetime of the helper handle) * @param cb function to call if we get messages from the helper - * @param cb_cls Closure for the callback - * @return the new H, NULL on error + * @param exp_cb the exception callback to call. Set this to NULL if the helper + * process has to be restarted automatically when it dies/crashes + * @param cb_cls closure for the above callback + * @return the new Handle, NULL on error */ -struct GNUNET_HELPER_Handle* +struct GNUNET_HELPER_Handle * GNUNET_HELPER_start (const char *binary_name, char *const binary_argv[], - GNUNET_SERVER_MessageTokenizerCallback cb, void *cb_cls) + GNUNET_SERVER_MessageTokenizerCallback cb, + GNUNET_HELPER_ExceptionCallback exp_cb, + void *cb_cls) { struct GNUNET_HELPER_Handle*h; h = GNUNET_malloc (sizeof (struct GNUNET_HELPER_Handle)); h->binary_name = binary_name; h->binary_argv = binary_argv; - h->mst = GNUNET_SERVER_mst_create (cb, cb_cls); + h->cb_cls = cb_cls; + h->mst = GNUNET_SERVER_mst_create (cb, h->cb_cls); + h->exp_cb = exp_cb; start_helper (h); return h; } @@ -390,6 +425,7 @@ GNUNET_HELPER_stop (struct GNUNET_HELPER_Handle *h) { struct GNUNET_HELPER_SendHandle *sh; + h->exp_cb = NULL; /* signal pending writes that we were stopped */ while (NULL != (sh = h->sh_head)) { diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 219949bd3..0b9a4dcb2 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c @@ -3183,7 +3183,7 @@ run (void *cls, mesh_handlers, types); helper_handle = GNUNET_HELPER_start ("gnunet-helper-vpn", vpn_argv, - &message_token, NULL); + &message_token, NULL, NULL); nc = GNUNET_SERVER_notification_context_create (server, 1); GNUNET_SERVER_add_handlers (server, service_handlers); GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL);