diff --git a/ChangeLog b/ChangeLog index 838f8d6..c33ba48 100644 --- a/ChangeLog +++ b/ChangeLog @@ -193,6 +193,18 @@ Version 1.8.0 Version 1.6.7 ******************************************************************************* +2010-03-21 Marcelo Jimenez + * libupnp and multi-flows scenario patch + Submited by Carlo Parata from STMicroelectronics. +Hi Roberto and Nektarios, +after an analysis of the problem of libupnp with a multi-flows scenario, I +noticed that the only cause of the freezed system is the ThreadPool +management. There are not mutex problems. In practise, if all threads in the +thread pool are busy executing jobs, a new worker thread should be created if +a job is scheduled (I inspired to tombupnp library). So I solved the problem +with a little patch in threadutil library that you can find attached in this +e-mail. I hope to have helped you. + 2010-03-21 Marcelo Jimenez * SF Patch Tracker [ 2964973 ] install: will not overwrite just-created ...blah... with... diff --git a/threadutil/inc/ThreadPool.h b/threadutil/inc/ThreadPool.h index bbca16a..efabd91 100644 --- a/threadutil/inc/ThreadPool.h +++ b/threadutil/inc/ThreadPool.h @@ -265,21 +265,20 @@ typedef struct TPOOLSTATS */ typedef struct THREADPOOL { - ithread_mutex_t mutex; /* mutex to protect job qs */ - ithread_cond_t condition; /* condition variable to signal Q */ - ithread_cond_t start_and_shutdown; /* condition variable for start - and stop */ - int lastJobId; /* ids for jobs */ - int shutdown; /* whether or not we are shutting down */ - int totalThreads; /* total number of threads */ - int persistentThreads; /* number of persistent threads */ - FreeList jobFreeList; /* free list of jobs */ - LinkedList lowJobQ; /* low priority job Q */ - LinkedList medJobQ; /* med priority job Q */ - LinkedList highJobQ; /* high priority job Q */ - ThreadPoolJob *persistentJob; /* persistent job */ - - ThreadPoolAttr attr; /* thread pool attributes */ + ithread_mutex_t mutex; /* mutex to protect job qs */ + ithread_cond_t condition; /* condition variable to signal Q */ + ithread_cond_t start_and_shutdown; /* condition variable for start and stop */ + int lastJobId; /* ids for jobs */ + int shutdown; /* whether or not we are shutting down */ + int totalThreads; /* total number of threads */ + int busyThreads; /* number of threads that are currently executing jobs */ + int persistentThreads; /* number of persistent threads */ + FreeList jobFreeList; /* free list of jobs */ + LinkedList lowJobQ; /* low priority job Q */ + LinkedList medJobQ; /* med priority job Q */ + LinkedList highJobQ; /* high priority job Q */ + ThreadPoolJob *persistentJob; /* persistent job */ + ThreadPoolAttr attr; /* thread pool attributes */ /* statistics */ ThreadPoolStats stats; diff --git a/threadutil/src/ThreadPool.c b/threadutil/src/ThreadPool.c index 3d3608b..35ceb7d 100644 --- a/threadutil/src/ThreadPool.c +++ b/threadutil/src/ThreadPool.c @@ -472,6 +472,7 @@ static void *WorkerThread( void *arg ) while( 1 ) { ithread_mutex_lock( &tp->mutex ); if( job ) { + tp->busyThreads--; FreeThreadPoolJob( tp, job ); job = NULL; } @@ -584,6 +585,7 @@ static void *WorkerThread( void *arg ) } } + tp->busyThreads++; ithread_mutex_unlock( &tp->mutex ); if( SetPriority( job->priority ) != 0 ) { @@ -688,7 +690,7 @@ static int CreateWorker( ThreadPool *tp ) * ThreadPool* tp * *****************************************************************************/ -static void AddWorker( ThreadPool *tp ) +static void AddWorker(ThreadPool *tp) { int jobs = 0; int threads = 0; @@ -697,8 +699,10 @@ static void AddWorker( ThreadPool *tp ) jobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size; threads = tp->totalThreads - tp->persistentThreads; - while( threads == 0 || (jobs / threads) >= tp->attr.jobsPerThread ) { - if( CreateWorker( tp ) != 0 ) { + while (threads == 0 || + (jobs / threads) >= tp->attr.jobsPerThread || + (tp->totalThreads == tp->busyThreads) ) { + if (CreateWorker(tp) != 0) { return; } threads++; @@ -804,6 +808,7 @@ int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr ) tp->lastJobId = 0; tp->shutdown = 0; tp->totalThreads = 0; + tp->busyThreads = 0; tp->persistentThreads = 0; for( i = 0; i < tp->attr.minThreads; ++i ) { if( ( retCode = CreateWorker( tp ) ) != 0 ) {