[PATCH ulogd2 v2 v2 26/34] db: avoid cancelling ring-buffer thread

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Using `pthread_cancel` can leave the DB driver in an inconsistent state
and may lead to undefined behaviour when cleaning up the plug-in.
Instead of cancelling the thread, set a flag and signal the condition
variable, thereby giving the thread a chance to exit in good order.

Signed-off-by: Jeremy Sowden <jeremy@xxxxxxxxxx>
---
 include/ulogd/db.h |  1 +
 util/db.c          | 30 +++++++++++++-----------------
 2 files changed, 14 insertions(+), 17 deletions(-)

diff --git a/include/ulogd/db.h b/include/ulogd/db.h
index bf4a19dea150..17eaa7cf60db 100644
--- a/include/ulogd/db.h
+++ b/include/ulogd/db.h
@@ -47,6 +47,7 @@ struct db_stmt_ring {
 	pthread_mutex_t mutex;
 
 	int full;
+	volatile sig_atomic_t shut_down;
 
 };
 
diff --git a/util/db.c b/util/db.c
index 6cfbcbc16791..42b59cc6284c 100644
--- a/util/db.c
+++ b/util/db.c
@@ -184,17 +184,11 @@ ulogd_db_signal(struct ulogd_pluginstance *upi, int signal)
 	case SIGTERM:
 	case SIGINT:
 		if (di->ring.size) {
-			int s = pthread_cancel(di->ring.thread_id);
-			if (s != 0) {
+			di->ring.shut_down = 1;
+			pthread_cond_signal(&di->ring.cond);
+			if (pthread_join(di->ring.thread_id, NULL) != 0)
 				ulogd_log(ULOGD_ERROR,
-					  "Can't cancel ring-processing thread\n");
-				break;
-			}
-			s = pthread_join(di->ring.thread_id, NULL);
-			if (s != 0) {
-				ulogd_log(ULOGD_ERROR,
-					  "Error waiting for ring-processing thread cancellation\n");
-			}
+					  "Error waiting for ring-processing thread exit\n");
 		}
 		break;
 	default:
@@ -371,8 +365,6 @@ _stop_db(struct ulogd_pluginstance *upi)
 		di->stmt = NULL;
 	}
 	if (di->ring.size > 0) {
-		pthread_cancel(di->ring.thread_id);
-
 		pthread_cond_destroy(&di->ring.cond);
 		pthread_mutex_destroy(&di->ring.mutex);
 
@@ -832,11 +824,11 @@ _process_ring(void *arg)
 
 	pthread_mutex_lock(&di->ring.mutex);
 
-	while(1) {
+	while(!di->ring.shut_down) {
 
 		pthread_cond_wait(&di->ring.cond, &di->ring.mutex);
 
-		while (di->ring.used > 0) {
+		while (!di->ring.shut_down && di->ring.used > 0) {
 
 			memcpy(stmt, _get_ring_elem(&di->ring, di->ring.rd_idx),
 			       di->ring.length);
@@ -859,9 +851,13 @@ exec_stmt:
 			 * statement.
 			 */
 			di->driver->close_db(upi);
-			while (di->driver->open_db(upi) < 0)
-				sleep(1);
-			goto exec_stmt;
+			while (!di->ring.shut_down) {
+				if (di->driver->open_db(upi) < 0) {
+					sleep(1);
+					continue;
+				}
+				goto exec_stmt;
+			}
 
 		}
 
-- 
2.35.1




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux