URL: https://github.com/freeipa/bind-dyndb-ldap/pull/6 Author: tomaskrizek Title: #6: handle termination of syncrepl watcher thread Action: synchronized
To pull the PR as Git branch: git remote add ghbind-dyndb-ldap https://github.com/freeipa/bind-dyndb-ldap git fetch ghbind-dyndb-ldap pull/6/head:pr6 git checkout pr6
From 8712baf2f7d45f895d8a418d2d4305ead0f7e82f Mon Sep 17 00:00:00 2001 From: Tomas Krizek <tkri...@redhat.com> Date: Mon, 19 Dec 2016 12:39:07 +0100 Subject: [PATCH] handle termination of syncrepl watcher thread In some cases, the thread could have been already terminated and sending a signal to the thread using pthread_kill() would result in an error. Now if the thread has already been terminated for some reason, only an error message is logged. https://fedorahosted.org/bind-dyndb-ldap/ticket/149 Reviewed-By: Petr Spacek <pspa...@redhat.com> Reviewed-By: Thierry Bordaz <tbor...@redhat.com> --- src/ldap_helper.c | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/src/ldap_helper.c b/src/ldap_helper.c index a11751d..5de9f69 100644 --- a/src/ldap_helper.c +++ b/src/ldap_helper.c @@ -668,6 +668,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name, const char *parameters, result = isc_thread_create(ldap_syncrepl_watcher, ldap_inst, &ldap_inst->watcher); if (result != ISC_R_SUCCESS) { + ldap_inst->watcher = 0; log_error("Failed to create syncrepl watcher thread"); goto cleanup; } @@ -684,6 +685,38 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name, const char *parameters, } #undef PRINT_BUFF_SIZE +/** + * Send SIGUSR1 to the SyncRepl watcher thread and wait for it to terminate. + * + * If the thread has already been terminated and a signal can't be sent to it, + * log an error instead. The thread is still joined, but since it is no longer + * running, it is instantaneous and doesn't block. + * + * @param[in] ldap_inst LDAP instance with ID of watcher thread + */ +static void ATTR_NONNULLS +ldap_syncrepl_watcher_shutdown(ldap_instance_t *ldap_inst) +{ + REQUIRE(ldap_inst != NULL); + + ldap_inst->exiting = ISC_TRUE; + /* + * Wake up the watcher thread. This might look like a hack + * but isc_thread_t is actually pthread_t and libisc don't + * have any isc_thread_kill() func. + * + * We use SIGUSR1 to not to interfere with any signal + * used by BIND itself. + */ + if (pthread_kill(ldap_inst->watcher, SIGUSR1) != 0) { + log_error("unable to send signal to SyncRepl watcher thread " + "(already terminated?)"); + } + + RUNTIME_CHECK(isc_thread_join(ldap_inst->watcher, NULL) + == ISC_R_SUCCESS); +} + void destroy_ldap_instance(ldap_instance_t **ldap_instp) { @@ -696,18 +729,7 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp) return; if (ldap_inst->watcher != 0) { - ldap_inst->exiting = ISC_TRUE; - /* - * Wake up the watcher thread. This might look like a hack - * but isc_thread_t is actually pthread_t and libisc don't - * have any isc_thread_kill() func. - * - * We use SIGUSR1 to not to interfere with any signal - * used by BIND itself. - */ - REQUIRE(pthread_kill(ldap_inst->watcher, SIGUSR1) == 0); - RUNTIME_CHECK(isc_thread_join(ldap_inst->watcher, NULL) - == ISC_R_SUCCESS); + ldap_syncrepl_watcher_shutdown(ldap_inst); ldap_inst->watcher = 0; }
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code