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
This commit is contained in:
Marcelo Roberto Jimenez 2010-03-21 19:47:19 +00:00
parent b26fe55772
commit bf169e434c
3 changed files with 34 additions and 18 deletions

View File

@ -193,6 +193,18 @@ Version 1.8.0
Version 1.6.7
*******************************************************************************
2010-03-21 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* 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 <mroberto(at)users.sourceforge.net>
* SF Patch Tracker [ 2964973 ] install: will not overwrite just-created
...blah... with...

View File

@ -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;

View File

@ -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 ) {