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 60db7a008c9655b9e7f8c8a8e9f52a55249fa0ed 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 | 31 +++++++++++++++++++++----------
 src/ldap_helper.h |  1 +
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/src/ldap_helper.c b/src/ldap_helper.c
index a11751d..570e202 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,16 +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);
+		watcher_shutdown(ldap_inst);
 		RUNTIME_CHECK(isc_thread_join(ldap_inst->watcher, NULL)
 			      == ISC_R_SUCCESS);
 		ldap_inst->watcher = 0;
@@ -747,6 +739,25 @@ destroy_ldap_instance(ldap_instance_t **ldap_instp)
 	*ldap_instp = NULL;
 }
 
+void 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?)");
+	}
+}
+
 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..3599b8e 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 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