
tony at becrux
Nov 20, 2006, 12:00 PM
Post #1 of 5
(1235 views)
Permalink
|
|
libclamav and thread-safety
|
|
Hi. I'm using libclamav in my opensource project, and I've some problems regarding thread-safety. There's written in the documentation that clamav library is thread-safe, but I still experience locks. In order to find out where's the problem, I've written this simple code: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #include <sys/types.h> #include <dirent.h> #include <clamav.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; struct cl_node *root; int counter = 0; void *scan(void *arg) { const char *virName; struct cl_limits limits; memset(&limits, 0, sizeof(struct cl_limits)); limits.maxfiles = 1000; limits.maxfilesize = 10 * 1048576; limits.maxreclevel = 5; limits.maxratio = 200; limits.archivememlim = 0; cl_scanfile((char *) arg,&virName,NULL,root,&limits,CL_SCAN_STDOPT); pthread_mutex_lock(&mutex); // cl_scanfile((char *) arg,&virName,NULL,root,&limits,CL_SCAN_STDOPT); --counter; pthread_mutex_unlock(&mutex); return NULL; } int main(int argc, char *argv) { DIR *dirFd; struct dirent *dirPtr; pthread_t thId; pthread_attr_t thAttr; unsigned int sigNo; char *buf; cl_loaddbdir(cl_retdbdir(),&root,&sigNo); cl_build(root); pthread_attr_init(&thAttr); pthread_attr_setdetachstate(&thAttr,PTHREAD_CREATE_DETACHED); dirFd = opendir("."); while ((dirPtr = readdir(dirFd)) != NULL) if (strcmp(dirPtr->d_name,".") && strcmp(dirPtr->d_name,"..")) { pthread_mutex_lock(&mutex); ++counter; pthread_mutex_unlock(&mutex); buf = new char[strlen(dirPtr->d_name)+1]; strcpy(buf,dirPtr->d_name); pthread_create(&thId,&thAttr,scan,(void *) buf); } while (counter) { printf("father sleeping, %d\n",counter); sleep(1); } closedir(dirFd); cl_free(root); return 0; } Don't care about memory leakage. It looks for directory entries and generates a thread for each entry. Every single thread makes a scan of his file. Please use a directory with several entries to reproduce test. Well, if I execute cl_scanfile *outside* the critical section (uncomment first, comment second), my output is (executed in /usr/bin): father sleeping, 1241 father sleeping, 1241 father sleeping, 1239 father sleeping, 1239 father sleeping, 1238 father sleeping, 1234 father sleeping, 1234 father sleeping, 1233 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 father sleeping, 1232 while, if I execute cl_scanfile *inside* critical section (comment first, uncomment second), the output is: father sleeping, 219 father sleeping, 177 father sleeping, 173 father sleeping, 133 father sleeping, 110 father sleeping, 110 father sleeping, 110 father sleeping, 110 father sleeping, 103 father sleeping, 87 father sleeping, 71 father sleeping, 52 father sleeping, 42 father sleeping, 42 father sleeping, 23 father sleeping, 23 father sleeping, 23 father sleeping, 10 father sleeping, 3 root [at] asu:/usr/bin# It seems to me that thread-safety is not respected, and threads get locked when cl_scanfile is executed simultaneously. Am I missing anything? Is my code wrong? Do I have to serialize scans? Thank you so much for your support. Regards, Tony. _______________________________________________ http://lurker.clamav.net/list/clamav-devel.html
|