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 51e2bb27c524224493161dbc7db00c2893fd1b21 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
---
 src/ldap_helper.c | 45 +++++++++++++++++++++++++++++++++------------
 src/ldap_helper.h |  1 +
 2 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index a11751d..9362849 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;
 	}
@@ -696,18 +697,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;
 	}
 
@@ -747,6 +737,37 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
 	*ldap_instp = NULL;
 }
 
+/**
+ * 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
+ */
+void 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);
+}
+
 static isc_result_t ATTR_NONNULLS ATTR_CHECKRESULT
 new_ldap_connection(ldap_pool_t *pool, ldap_connection_t **ldap_connp)
 {
diff --git a/src/ldap_helper.h b/src/ldap_helper.h
index 6cfece5..abc8220 100644
--- a/src/ldap_helper.h
+++ b/src/ldap_helper.h
@@ -45,6 +45,7 @@ new_ldap_instance(isc_mem_t *mctx, const char *db_name, const char *parameters,
 		  const char *file, unsigned long line,
 		  const dns_dyndbctx_t *dctx, ldap_instance_t **ldap_instp) ATTR_NONNULLS;
 void destroy_ldap_instance(ldap_instance_t **ldap_inst) ATTR_NONNULLS;
+void ldap_syncrepl_watcher_shutdown(ldap_instance_t *ldap_inst) ATTR_NONNULLS;
 
 isc_result_t
 ldap_delete_zone2(ldap_instance_t *inst, dns_name_t *name, isc_boolean_t lock)
-- 
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

Reply via email to