X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fhelper.c;h=f0123460b9fec29e506b688cba617b8044619ab8;hb=cf5a23aa7d5d939038b78ff6ce47ceb5665281bb;hp=21f196ebce8219d6e86dd9ab5c2a59f362d1a584;hpb=61c39c60565b386e0e12ea669556b030e8cd7180;p=oweals%2Fgnunet.git diff --git a/src/util/helper.c b/src/util/helper.c index 21f196ebc..f0123460b 100644 --- a/src/util/helper.c +++ b/src/util/helper.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2011, 2012 Christian Grothoff + Copyright (C) 2011, 2012 Christian Grothoff GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -14,8 +14,8 @@ You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /** @@ -142,23 +142,27 @@ struct GNUNET_HELPER_Handle /** * Task to read from the helper. */ - GNUNET_SCHEDULER_TaskIdentifier read_task; + struct GNUNET_SCHEDULER_Task * read_task; /** * Task to read from the helper. */ - GNUNET_SCHEDULER_TaskIdentifier write_task; + struct GNUNET_SCHEDULER_Task * write_task; /** * Restart task. */ - GNUNET_SCHEDULER_TaskIdentifier restart_task; + struct GNUNET_SCHEDULER_Task * restart_task; /** * Does the helper support the use of a control pipe for signalling? */ int with_control_pipe; + /** + * Count start attempts to increase linear back off + */ + unsigned int retry_back_off; }; @@ -187,15 +191,15 @@ GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, sh->cont (sh->cont_cls, GNUNET_NO); GNUNET_free (sh); } - if (GNUNET_SCHEDULER_NO_TASK != h->restart_task) + if (NULL != h->restart_task) { GNUNET_SCHEDULER_cancel (h->restart_task); - h->restart_task = GNUNET_SCHEDULER_NO_TASK; + h->restart_task = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != h->read_task) + if (NULL != h->read_task) { GNUNET_SCHEDULER_cancel (h->read_task); - h->read_task = GNUNET_SCHEDULER_NO_TASK; + h->read_task = NULL; } if (NULL == h->helper_proc) return GNUNET_SYSERR; @@ -208,7 +212,7 @@ GNUNET_HELPER_kill (struct GNUNET_HELPER_Handle *h, h->fh_to_helper = NULL; return ret; } - if (0 != GNUNET_OS_process_kill (h->helper_proc, SIGTERM)) + if (0 != GNUNET_OS_process_kill (h->helper_proc, GNUNET_TERM_SIG)) return GNUNET_SYSERR; return GNUNET_OK; } @@ -235,15 +239,15 @@ GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h) GNUNET_OS_process_destroy (h->helper_proc); h->helper_proc = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != h->read_task) + if (NULL != h->read_task) { GNUNET_SCHEDULER_cancel (h->read_task); - h->read_task = GNUNET_SCHEDULER_NO_TASK; + h->read_task = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != h->write_task) + if (NULL != h->write_task) { GNUNET_SCHEDULER_cancel (h->write_task); - h->write_task = GNUNET_SCHEDULER_NO_TASK; + h->write_task = NULL; } if (NULL != h->helper_in) { @@ -284,10 +288,10 @@ static void stop_helper (struct GNUNET_HELPER_Handle *h, int soft_kill) { - if (GNUNET_SCHEDULER_NO_TASK != h->restart_task) + if (NULL != h->restart_task) { GNUNET_SCHEDULER_cancel (h->restart_task); - h->restart_task = GNUNET_SCHEDULER_NO_TASK; + h->restart_task = NULL; } else { @@ -322,7 +326,7 @@ helper_read (void *cls, char buf[GNUNET_SERVER_MAX_MESSAGE_SIZE] GNUNET_ALIGN; ssize_t t; - h->read_task = GNUNET_SCHEDULER_NO_TASK; + h->read_task = NULL; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { /* try again */ @@ -346,8 +350,9 @@ helper_read (void *cls, } stop_helper (h, GNUNET_NO); /* Restart the helper */ - h->restart_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &restart_task, h); + h->restart_task = GNUNET_SCHEDULER_add_delayed( + GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, + h->retry_back_off), &restart_task, h); return; } if (0 == t) @@ -365,9 +370,9 @@ helper_read (void *cls, } stop_helper (h, GNUNET_NO); /* Restart the helper */ - h->restart_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &restart_task, h); + h->restart_task = GNUNET_SCHEDULER_add_delayed( + GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, + h->retry_back_off), &restart_task, h); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -390,9 +395,9 @@ helper_read (void *cls, } stop_helper (h, GNUNET_NO); /* Restart the helper */ - h->restart_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &restart_task, h); + h->restart_task = GNUNET_SCHEDULER_add_delayed( + GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, + h->retry_back_off), &restart_task, h); return; } } @@ -413,8 +418,9 @@ start_helper (struct GNUNET_HELPER_Handle *h) /* out of file descriptors? try again later... */ stop_helper (h, GNUNET_NO); h->restart_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &restart_task, h); + GNUNET_SCHEDULER_add_delayed( + GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, + h->retry_back_off), &restart_task, h); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -426,16 +432,16 @@ start_helper (struct GNUNET_HELPER_Handle *h) GNUNET_DISK_pipe_handle (h->helper_in, GNUNET_DISK_PIPE_END_WRITE); h->helper_proc = GNUNET_OS_start_process_vap (h->with_control_pipe, GNUNET_OS_INHERIT_STD_ERR, - h->helper_in, h->helper_out, + h->helper_in, h->helper_out, NULL, h->binary_name, h->binary_argv); if (NULL == h->helper_proc) { /* failed to start process? try again later... */ stop_helper (h, GNUNET_NO); - h->restart_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &restart_task, h); + h->restart_task = GNUNET_SCHEDULER_add_delayed( + GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, + h->retry_back_off), &restart_task, h); return; } GNUNET_DISK_pipe_close_end (h->helper_out, GNUNET_DISK_PIPE_END_WRITE); @@ -460,7 +466,11 @@ restart_task (void *cls, { struct GNUNET_HELPER_Handle*h = cls; - h->restart_task = GNUNET_SCHEDULER_NO_TASK; + h->restart_task = NULL; + h->retry_back_off++; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Restarting helper with back-off %u\n", + h->retry_back_off); start_helper (h); } @@ -498,7 +508,7 @@ GNUNET_HELPER_start (int with_control_pipe, if (NULL != strstr (binary_name, "gnunet")) h->binary_name = GNUNET_OS_get_libexec_binary_path (binary_name); else - h->binary_name = strdup (binary_name); + h->binary_name = GNUNET_strdup (binary_name); for (c = 0; NULL != binary_argv[c]; c++); h->binary_argv = GNUNET_malloc (sizeof (char *) * (c + 1)); for (c = 0; NULL != binary_argv[c]; c++) @@ -508,6 +518,7 @@ GNUNET_HELPER_start (int with_control_pipe, if (NULL != cb) h->mst = GNUNET_SERVER_mst_create (cb, h->cb_cls); h->exp_cb = exp_cb; + h->retry_back_off = 0; start_helper (h); return h; } @@ -524,13 +535,13 @@ GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h) unsigned int c; struct GNUNET_HELPER_SendHandle *sh; - if (GNUNET_SCHEDULER_NO_TASK != h->write_task) + if (NULL != h->write_task) { GNUNET_SCHEDULER_cancel (h->write_task); - h->write_task = GNUNET_SCHEDULER_NO_TASK; + h->write_task = NULL; } - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->read_task); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->restart_task); + GNUNET_assert (NULL == h->read_task); + GNUNET_assert (NULL == h->restart_task); while (NULL != (sh = h->sh_head)) { GNUNET_CONTAINER_DLL_remove (h->sh_head, @@ -582,7 +593,7 @@ helper_write (void *cls, const char *buf; ssize_t t; - h->write_task = GNUNET_SCHEDULER_NO_TASK; + h->write_task = NULL; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { /* try again */ @@ -619,9 +630,9 @@ helper_write (void *cls, "Stopping and restarting helper task!\n"); stop_helper (h, GNUNET_NO); /* Restart the helper */ - h->restart_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &restart_task, h); + h->restart_task = GNUNET_SCHEDULER_add_delayed( + GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, + h->retry_back_off), &restart_task, h); return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -684,7 +695,7 @@ GNUNET_HELPER_send (struct GNUNET_HELPER_Handle *h, GNUNET_CONTAINER_DLL_insert_tail (h->sh_head, h->sh_tail, sh); - if (GNUNET_SCHEDULER_NO_TASK == h->write_task) + if (NULL == h->write_task) h->write_task = GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL, h->fh_to_helper, &helper_write, @@ -714,7 +725,7 @@ GNUNET_HELPER_send_cancel (struct GNUNET_HELPER_SendHandle *sh) if (NULL == h->sh_head) { GNUNET_SCHEDULER_cancel (h->write_task); - h->write_task = GNUNET_SCHEDULER_NO_TASK; + h->write_task = NULL; } } }