[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b

Török Edvin edwin at clamav.net
Sun Apr 4 01:17:32 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit 80301d0cd6fc345c220595f704b1ecab97b23738
Author: Török Edvin <edwin at clamav.net>
Date:   Wed Jan 27 11:56:10 2010 +0200

    Fix clamd hang when number of multiscan commands == MaxThreads (bb #1700).
    
    Each multiscan command needs 1 control thread, and 1 (possibly shared) scanner
    thread.
    If the number of multiscan control threads would be equal to MaxThreads no
    progress could be made, since each one would be waiting for 1 free scanner
    thread (but none can be spawned since maxthreads was already reached).
    As long as there is 1 thread free for scanning, we can have N-1 multiscan
    commands active, with N MaxThreads.

diff --git a/clamd/session.c b/clamd/session.c
index e3b47d3..cc4d443 100644
--- a/clamd/session.c
+++ b/clamd/session.c
@@ -220,7 +220,27 @@ int command(client_conn_t *conn, int *virus)
 	    thrmgr_setactivetask(NULL, "CONTSCAN");
 	    type = TYPE_CONTSCAN;
 	    break;
-	case COMMAND_MULTISCAN:
+	case COMMAND_MULTISCAN: {
+	    int multiscan, max, alive;
+	    pthread_mutex_lock(&conn->thrpool->pool_mutex);
+	    multiscan = conn->thrpool->thr_multiscan;
+	    max = conn->thrpool->thr_max;
+	    if (multiscan+1 < max)
+		conn->thrpool->thr_multiscan = multiscan+1;
+	    else {
+		alive = conn->thrpool->thr_alive;
+		ret = -1;
+	    }
+	    pthread_mutex_unlock(&conn->thrpool->pool_mutex);
+	    if (ret) {
+		// multiscan has 1 control thread, so there needs to be at least
+		// 1 threads that is a non-multiscan controlthread to scan and
+		// make progress.
+		logg("^Not enough threads for multiscan. Max: %d, Alive: %d, Multiscan: %d+1\n",
+		     max, alive, multiscan);
+		conn_reply(conn, conn->filename, "Not enough threads for multiscan. Increase MaxThreads.","ERROR");
+		return 1;
+	    }
 	    flags &= ~CLI_FTW_NEED_STAT;
 	    thrmgr_setactivetask(NULL, "MULTISCAN");
 	    type = TYPE_MULTISCAN;
@@ -228,6 +248,7 @@ int command(client_conn_t *conn, int *virus)
 	    if (!group)
 		return CL_EMEM;
 	    break;
+	    }
 	case COMMAND_MULTISCANFILE:
 	    thrmgr_setactivetask(NULL, "MULTISCANFILE");
 	    scandata.group = NULL;
@@ -324,6 +345,9 @@ int command(client_conn_t *conn, int *virus)
 	    return -1;
     if (scandata.group && conn->cmdtype == COMMAND_MULTISCAN) {
 	thrmgr_group_waitforall(group, &ok, &error, &total);
+	pthread_mutex_lock(&conn->thrpool->pool_mutex);
+	conn->thrpool->thr_multiscan--;
+	pthread_mutex_unlock(&conn->thrpool->pool_mutex);
     } else {
 	error = scandata.errors;
 	total = scandata.total;
diff --git a/clamd/thrmgr.c b/clamd/thrmgr.c
index 0a20bbe..ab83f29 100644
--- a/clamd/thrmgr.c
+++ b/clamd/thrmgr.c
@@ -387,6 +387,7 @@ threadpool_t *thrmgr_new(int max_threads, int idle_timeout, int max_queue, void
 	threadpool->thr_max = max_threads;
 	threadpool->thr_alive = 0;
 	threadpool->thr_idle = 0;
+	threadpool->thr_multiscan = 0;
 	threadpool->idle_timeout = idle_timeout;
 	threadpool->handler = handler;
 	threadpool->tasks = NULL;
diff --git a/clamd/thrmgr.h b/clamd/thrmgr.h
index 4f71e4a..b0b8b12 100644
--- a/clamd/thrmgr.h
+++ b/clamd/thrmgr.h
@@ -69,6 +69,7 @@ typedef struct threadpool_tag {
 	int queue_max;
 	int thr_alive;
 	int thr_idle;
+	int thr_multiscan;
 	int idle_timeout;
 	struct task_desc *tasks;
 	

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list