From bf169e434c843f1ef55d260a288e43471d2d45e2 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Sun, 21 Mar 2010 19:47:19 +0000 Subject: [PATCH] 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. git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@514 119443c7-1b9e-41f8-b6fc-b9c35fce742c --- ChangeLog | 12 ++++++++++++ threadutil/inc/ThreadPool.h | 29 ++++++++++++++--------------- threadutil/src/ThreadPool.c | 11 ++++++++--- 3 files changed, 34 insertions(+), 18 deletions(-) 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 ) {