File iscsi-cancel-conn-worker-threads-using-the-task_pipe.patch of Package istgt

From 077e65d1019edd4998b7af73b8934410c3e97bac Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@suse.de>
Date: Wed, 27 Mar 2013 18:30:27 +0100
Subject: [PATCH 05/12] iscsi: cancel conn worker threads using the task_pipe

Currently istgt_iscsi_drop_*_conns() use pthread_cancel() to tell the
connection worker thread to exit. This is unnecessary, as the worker
thread already accepts exit requests via the task_pipe.
---
 src/istgt_iscsi.c | 87 ++++++++++---------------------------------------------
 1 file changed, 16 insertions(+), 71 deletions(-)

diff --git src/istgt_iscsi.c src/istgt_iscsi.c
index 7f241d8..8a76379 100644
--- src/istgt_iscsi.c
+++ src/istgt_iscsi.c
@@ -5260,9 +5260,8 @@ wait_all_task(CONN_Ptr conn)
 }
 
 static void
-worker_cleanup(void *arg)
+worker_cleanup(CONN_Ptr conn)
 {
-	CONN_Ptr conn = (CONN_Ptr) arg;
 	ISTGT_LU_Ptr lu;
 	int rc;
 
@@ -5538,9 +5537,6 @@ worker(void *arg)
 	conn->exec_lu_task = NULL;
 	lu_task = NULL;
 
-	pthread_cleanup_push(worker_cleanup, conn);
-	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
-
 	conn->use_sender = 0;
 	if (conn->istgt->swmode >= ISTGT_SWMODE_NORMAL) {
 		/* create sender thread */
@@ -5589,7 +5585,6 @@ worker(void *arg)
 			}
 		}
 
-		pthread_testcancel();
 		if (conn->state != CONN_STATE_RUNNING) {
 			break;
 		}
@@ -5705,9 +5700,6 @@ worker(void *arg)
 		execute_pdu:
 			opcode = BGET8W(&conn->pdu.bhs.opcode, 5, 6);
 
-#if 0
-			pthread_testcancel();
-#endif
 			if (conn->state != CONN_STATE_RUNNING) {
 				break;
 			}
@@ -5926,62 +5918,7 @@ worker(void *arg)
 
     cleanup_exit:
 	;
-	pthread_cleanup_pop(0);
-	conn->state = CONN_STATE_EXITING;
-	if (conn->sess != NULL) {
-		SESS_MTX_LOCK(conn);
-		lu = conn->sess->lu;
-		if (lu != NULL && lu->queue_depth != 0) {
-			rc = istgt_lu_clear_task_IT(conn, lu);
-			if (rc < 0) {
-				ISTGT_ERRLOG("lu_clear_task_IT() failed\n");
-			}
-			istgt_clear_all_transfer_task(conn);
-		}
-		SESS_MTX_UNLOCK(conn);
-	}
-	if (conn->pdu.copy_pdu == 0) {
-		xfree(conn->pdu.ahs);
-		conn->pdu.ahs = NULL;
-		if (conn->pdu.data != conn->pdu.shortdata) {
-			xfree(conn->pdu.data);
-		}
-		conn->pdu.data = NULL;
-	}
-	wait_all_task(conn);
-
-	if (conn->use_sender) {
-		ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "stop sender thread (%d)\n", conn->id);
-		/* stop sender thread */
-		MTX_LOCK(&conn->result_queue_mutex);
-		rc = pthread_cond_broadcast(&conn->result_queue_cond);
-		MTX_UNLOCK(&conn->result_queue_mutex);
-		if (rc != 0) {
-			ISTGT_ERRLOG("cond_broadcast() failed\n");
-			/* ignore errors */
-		}
-		rc = pthread_join(conn->sender_thread, NULL);
-		if (rc != 0) {
-			ISTGT_ERRLOG("pthread_join() failed\n");
-			/* ignore errors */
-		}
-	}
-
-	close(conn->sock);
-#ifdef ISTGT_USE_KQUEUE
-	close(kq);
-	conn->kq = -1;
-#endif /* ISTGT_USE_KQUEUE */
-	sleep(1);
-	ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "worker %d end\n", conn->id);
-
-	/* cleanup conn & sess */
-	ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "cleanup LOCK\n");
-	MTX_LOCK(&g_conns_mutex);
-	g_conns[conn->id] = NULL;
-	istgt_remove_conn(conn);
-	MTX_UNLOCK(&g_conns_mutex);
-	ISTGT_TRACELOG(ISTGT_TRACE_DEBUG, "cleanup UNLOCK\n");
+	worker_cleanup(conn);
 
 	return NULL;
 }
@@ -6719,7 +6656,6 @@ istgt_iscsi_drop_all_conns(CONN_Ptr conn)
 	istgt_yield();
 	sleep(1);
 	if (num > max_conns + 1) {
-		printf("try pthread_cancel\n");
 		for (i = 0; i < g_nconns; i++) {
 			xconn = g_conns[i];
 			if (xconn == NULL)
@@ -6741,9 +6677,14 @@ istgt_iscsi_drop_all_conns(CONN_Ptr conn)
 					    xconn->initiator_addr,
 					    xconn->cid);
 				}
-				rc = pthread_cancel(xconn->thread);
+				rc = write(xconn->task_pipe[1], "E", 1);
+				if (rc < 0 || rc != 1) {
+					ISTGT_ERRLOG("write() failed\n");
+					continue;
+				}
+				rc = pthread_join(xconn->thread, NULL);
 				if (rc != 0) {
-					ISTGT_ERRLOG("pthread_cancel() failed rc=%d\n", rc);
+					ISTGT_ERRLOG("pthread_join() failed rc=%d\n", rc);
 				}
 			}
 		}
@@ -6803,7 +6744,6 @@ istgt_iscsi_drop_old_conns(CONN_Ptr conn)
 	istgt_yield();
 	sleep(1);
 	if (num > max_conns + 1) {
-		printf("try pthread_cancel\n");
 		for (i = 0; i < g_nconns; i++) {
 			xconn = g_conns[i];
 			if (xconn == NULL)
@@ -6825,9 +6765,14 @@ istgt_iscsi_drop_old_conns(CONN_Ptr conn)
 					    xconn->initiator_addr,
 					    xconn->cid);
 				}
-				rc = pthread_cancel(xconn->thread);
+				rc = write(xconn->task_pipe[1], "E", 1);
+				if (rc < 0 || rc != 1) {
+					ISTGT_ERRLOG("write() failed\n");
+					continue;
+				}
+				rc = pthread_join(xconn->thread, NULL);
 				if (rc != 0) {
-					ISTGT_ERRLOG("pthread_cancel() failed rc=%d\n", rc);
+					ISTGT_ERRLOG("pthread_join() failed rc=%d\n", rc);
 				}
 			}
 		}
-- 
2.1.2

openSUSE Build Service is sponsored by