[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