diff --git a/ChangeLog b/ChangeLog index 76a4fdc..911b5c6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,7 +2,48 @@ Version 1.8.0 ******************************************************************************* -2010-03-21 Marcelo Jimenez +2010-03-27 Marcelo Jimenez + * Added API to ithread, created the following functions: + - int ithread_initialize_library(void); + - int ithread_cleanup_library(void); + - int ithread_initialize_thread(void); + - int ithread_cleanup_thread(void); + * SF Bug Tracker [ 2876374 ] Access Violation when compiling with Visual Studio 2008 + Submitted: Stulle ( stulleamgym ) - 2009-10-10 19:05 + + Hi, + + I am one of the devs of the MorphXT project and I use this lib in some + other of my projects, too. When I tried to upgrade the lib earlier for one + of my projects I had to realise that something did not work at first and + while most of the things were reasonably ease to be fixed. Now, the last + thing I encountered was not so easy to fix and I am uncertain if my fix is + any good so I'll just post it here and wait for some comments. + + The problem was that I got an Access Violation when calling "UpnpInit". It + would call "ithread_rwlock_init(&GlobalHndRWLock, NULL)" which eventually + led to calling "pthread_cond_init" and I got the error notice at + "EnterCriticalSection (&ptw32_cond_list_lock);". It appeared that + "ptw32_cond_list_lock" was NULL. Now, I found two ways to fix this. Firstly + moving the whole block after at least one of the "ThreadPoolInit" calls + will fix the issue. Secondly, you could add: + #ifdef WIN32 + #ifdef PTW32_STATIC_LIB + // to get the following working we need this... is it a good patch or + not... I do not know! + pthread_win32_process_attach_np(); + #endif + #endif + right before "ithread_rwlock_init(&GlobalHndRWLock, NULL)". + + Just so you know, I am using libupnp 1.6.6 and libpthreads 2.8.0 and both + are linked static into the binaries. I am currently using Visual Studio + 2008 for development with Windows being the target OS. Any comment at your + end? + + Regards, Stulle + +2010-03-27 Marcelo Jimenez * Forward port of svn revision 505: SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage. Submitted By: zephyrus ( zephyrus00jp ) diff --git a/configure.ac b/configure.ac index 0de4272..f4259ba 100644 --- a/configure.ac +++ b/configure.ac @@ -154,14 +154,19 @@ dnl # current: 3 -> 4 dnl # revision: 6 -> 0 dnl # - Interface has been removed in upnp dnl # age = 0 +dnl # - Code has changed in threadutil +dnl # revision: 3 -> 4 +dnl # - Interfaces have been changed, added and removed in upnp +dnl # current: 4 -> 5 +dnl # revision: 4 -> 0 dnl # dnl #AC_SUBST([LT_VERSION_IXML], [2:4:0]) -dnl #AC_SUBST([LT_VERSION_THREADUTIL], [4:3:2]) +dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2]) dnl #AC_SUBST([LT_VERSION_UPNP], [4:0:0]) dnl # dnl ############################################################################ AC_SUBST([LT_VERSION_IXML], [2:4:0]) -AC_SUBST([LT_VERSION_THREADUTIL], [4:3:2]) +AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2]) AC_SUBST([LT_VERSION_UPNP], [4:0:0]) dnl ############################################################################ dnl # Repeating the algorithm to place it closer to the modificatin place: diff --git a/threadutil/inc/ithread.h b/threadutil/inc/ithread.h index 7d2aa28..4488e70 100644 --- a/threadutil/inc/ithread.h +++ b/threadutil/inc/ithread.h @@ -30,19 +30,21 @@ ******************************************************************************/ -#ifndef ITHREADH -#define ITHREADH +#ifndef ITHREAD_H +#define ITHREAD_H /*! * \file */ -#if ! defined(WIN32) + +#if !defined(WIN32) #include #endif -#include "UpnpGlobal.h" /* For EXPORT_SPEC */ + +#include "UpnpGlobal.h" /* For UPNP_INLINE, EXPORT_SPEC */ #ifdef __cplusplus @@ -92,7 +94,8 @@ extern "C" { * typedef to pthread_t. * Internal Use Only. ***************************************************************************/ -typedef pthread_t ithread_t; +typedef pthread_t ithread_t; + /**************************************************************************** * Name: ithread_attr_t @@ -112,7 +115,7 @@ typedef pthread_attr_t ithread_attr_t; * Thread start routine * Internal Use Only. ***************************************************************************/ -typedef void * (*start_routine) (void *arg); +typedef void *(*start_routine)(void *arg); /**************************************************************************** @@ -179,7 +182,96 @@ typedef pthread_rwlockattr_t ithread_rwlockattr_t; * typedef to pthread_rwlock_t * Internal Use Only ***************************************************************************/ -typedef pthread_rwlock_t ithread_rwlock_t; +typedef pthread_rwlock_t ithread_rwlock_t; + + +/**************************************************************************** + * Function: ithread_initialize_library + * + * Description: + * Initializes the library. Does nothing in all implementations, except + * when statically linked for WIN32. + * Parameters: + * none. + * Returns: + * 0 on success, Nonzero on failure. + ***************************************************************************/ +static UPNP_INLINE int ithread_initialize_library(void) { + int ret = 0; + +#if defined(WIN32) && defined(PTW32_STATIC_LIB) + ret = !pthread_win32_process_attach_np(); +#endif + + return ret; +} + + +/**************************************************************************** + * Function: ithread_cleanup_library + * + * Description: + * Clean up library resources. Does nothing in all implementations, except + * when statically linked for WIN32. + * Parameters: + * none. + * Returns: + * 0 on success, Nonzero on failure. + ***************************************************************************/ +static UPNP_INLINE int ithread_cleanup_library(void) { + int ret = 0; + +#if defined(WIN32) && defined(PTW32_STATIC_LIB) + ret = !pthread_win32_process_detach_np(); +#endif + + return ret; +} + + +/**************************************************************************** + * Function: ithread_initialize_thread + * + * Description: + * Initializes the thread. Does nothing in all implementations, except + * when statically linked for WIN32. + * Parameters: + * none. + * Returns: + * 0 on success, Nonzero on failure. + ***************************************************************************/ +static UPNP_INLINE int ithread_initialize_thread(void) { + int ret = 0; + +#if defined(WIN32) && defined(PTW32_STATIC_LIB) + ret = !pthread_win32_thread_attach_np(); +#endif + + return ret; +} + + +/**************************************************************************** + * Function: ithread_cleanup_thread + * + * Description: + * Clean up thread resources. Does nothing in all implementations, except + * when statically linked for WIN32. + * Parameters: + * none. + * Returns: + * 0 on success, Nonzero on failure. + ***************************************************************************/ +static UPNP_INLINE int ithread_cleanup_thread(void) { + int ret = 0; + +#if defined(WIN32) && defined(PTW32_STATIC_LIB) + ret = !pthread_win32_thread_detach_np(); +#endif + + return ret; +} + /**************************************************************************** * Function: ithread_mutexattr_init @@ -420,8 +512,8 @@ typedef pthread_rwlock_t ithread_rwlock_t; * Must be called before use. * * Parameters: - * ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t) - * const ithread_rwlockattr_t * rwlock_attr + * ithread_rwlock_t *rwlock (must be valid non NULL pointer to pthread_rwlock_t) + * const ithread_rwlockattr_t *rwlock_attr * Returns: * 0 on success, Nonzero on failure. * Always returns 0. @@ -436,7 +528,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; * Description: * Locks rwlock for reading. * Parameters: - * ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t) + * ithread_rwlock_t *rwlock (must be valid non NULL pointer to pthread_rwlock_t) * rwlock must be initialized. * * Returns: @@ -453,7 +545,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; * Description: * Locks rwlock for writting. * Parameters: - * ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t) + * ithread_rwlock_t *rwlock (must be valid non NULL pointer to pthread_rwlock_t) * rwlock must be initialized. * * Returns: @@ -471,7 +563,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; * Unlocks rwlock. * * Parameters: - * ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t) + * ithread_rwlock_t *rwlock (must be valid non NULL pointer to pthread_rwlock_t) * rwlock must be initialized. * * Returns: @@ -491,7 +583,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; * rwlock is only destroyed when there are no longer any threads waiting on it. * rwlock cannot be destroyed if it is locked. * Parameters: - * ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t) + * ithread_rwlock_t *rwlock (must be valid non NULL pointer to pthread_rwlock_t) * rwlock must be initialized. * Returns: * 0 on success. Nonzero on failure. @@ -508,8 +600,8 @@ typedef pthread_rwlock_t ithread_rwlock_t; * Initializes condition variable. * Must be called before use. * Parameters: - * ithread_cond_t * cond (must be valid non NULL pointer to pthread_cond_t) - * const ithread_condattr_t * cond_attr (ignored) + * ithread_cond_t *cond (must be valid non NULL pointer to pthread_cond_t) + * const ithread_condattr_t *cond_attr (ignored) * Returns: * 0 on success, Nonzero on failure. * See man page for pthread_cond_init @@ -517,7 +609,6 @@ typedef pthread_rwlock_t ithread_rwlock_t; #define ithread_cond_init pthread_cond_init - /**************************************************************************** * Function: ithread_cond_signal * @@ -525,7 +616,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; * Wakes up exactly one thread waiting on condition. * Associated mutex MUST be locked by thread before entering this call. * Parameters: - * ithread_cond_t * cond (must be valid non NULL pointer to + * ithread_cond_t *cond (must be valid non NULL pointer to * ithread_cond_t) * cond must be initialized * Returns: @@ -542,7 +633,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; * Wakes up all threads waiting on condition. * Associated mutex MUST be locked by thread before entering this call. * Parameters: - * ithread_cond_t * cond (must be valid non NULL pointer to + * ithread_cond_t *cond (must be valid non NULL pointer to * ithread_cond_t) * cond must be initialized * Returns: @@ -560,7 +651,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; * Associated mutex MUST be locked by thread before entering this call. * Mutex is reacquired when call returns. * Parameters: - * ithread_cond_t * cond (must be valid non NULL pointer to + * ithread_cond_t *cond (must be valid non NULL pointer to * ithread_cond_t) * cond must be initialized * ithread_mutex_t *mutex (must be valid non NULL pointer to @@ -576,23 +667,19 @@ typedef pthread_rwlock_t ithread_rwlock_t; /**************************************************************************** * Function: pthread_cond_timedwait * - * Description: - * Atomically releases the associated mutex and waits on the condition. - * If the condition is not signaled in the specified time - * than the - * call times out and returns. - * Associated mutex MUST be locked by thread before entering - * this call. - * Mutex is reacquired when call returns. + * Description: + * Atomically releases the associated mutex and waits on the + * condition. + * If the condition is not signaled in the specified time than the + * call times out and returns. + * Associated mutex MUST be locked by thread before entering this call. + * Mutex is reacquired when call returns. * Parameters: - * ithread_cond_t * cond (must be valid non NULL pointer to - * ithread_cond_t) - * cond must be initialized - * ithread_mutex_t *mutex (must be valid non NULL pointer to - * ithread_mutex_t) - * Mutex must be locked. - * const struct timespec *abstime (absolute time, measured - * from Jan 1, 1970) + * ithread_cond_t *cond (must be valid non NULL pointer to ithread_cond_t) + * cond must be initialized + * ithread_mutex_t *mutex (must be valid non NULL pointer to ithread_mutex_t) + * Mutex must be locked. + * const struct timespec *abstime (absolute time, measured from Jan 1, 1970) * Returns: * 0 on success. ETIMEDOUT on timeout. Nonzero on failure. * See man page for pthread_cond_timedwait @@ -608,7 +695,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; * Releases any resources held by the condition variable. * Condition variable can no longer be used after this call. * Parameters: - * ithread_cond_t * cond (must be valid non NULL pointer to + * ithread_cond_t *cond (must be valid non NULL pointer to * ithread_cond_t) * cond must be initialized. * Returns: @@ -664,6 +751,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; ***************************************************************************/ #define ithread_exit pthread_exit + /**************************************************************************** * Function: ithread_get_current_thread_id * @@ -687,6 +775,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; ***************************************************************************/ #define ithread_self pthread_self + /**************************************************************************** * Function: ithread_detach * @@ -700,6 +789,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; ***************************************************************************/ #define ithread_detach pthread_detach + /**************************************************************************** * Function: ithread_join * @@ -719,7 +809,6 @@ typedef pthread_rwlock_t ithread_rwlock_t; #define ithread_join pthread_join - /**************************************************************************** * Function: isleep * @@ -739,6 +828,7 @@ typedef pthread_rwlock_t ithread_rwlock_t; #define isleep sleep #endif + /**************************************************************************** * Function: isleep * @@ -764,9 +854,11 @@ typedef pthread_rwlock_t ithread_rwlock_t; EXPORT_SPEC int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind); #endif + #ifdef __cplusplus } #endif -#endif /* ITHREADH */ + +#endif /* ITHREAD_H */ diff --git a/threadutil/src/ThreadPool.c b/threadutil/src/ThreadPool.c index 35ceb7d..d44a39b 100644 --- a/threadutil/src/ThreadPool.c +++ b/threadutil/src/ThreadPool.c @@ -35,7 +35,7 @@ */ -#if ! defined(WIN32) +#if !defined(WIN32) #include #endif @@ -68,9 +68,6 @@ static unsigned long DiffMillis(struct timeval *time1, struct timeval *time2) { double temp = 0; - assert(time1 != NULL); - assert(time2 != NULL); - temp = time1->tv_sec - time2->tv_sec; /* convert to milliseconds */ temp *= 1000; @@ -94,8 +91,6 @@ static unsigned long DiffMillis(struct timeval *time1, struct timeval *time2) *****************************************************************************/ static void StatsInit(ThreadPoolStats *stats) { - assert(stats != NULL); - stats->totalIdleTime = 0; stats->totalJobsHQ = 0; stats->totalJobsLQ = 0; @@ -202,11 +197,8 @@ static UPNP_INLINE time_t StatsTime(time_t *t) { return 0; } *****************************************************************************/ static int CmpThreadPoolJob(void *jobA, void *jobB) { - ThreadPoolJob *a = (ThreadPoolJob *) jobA; - ThreadPoolJob *b = (ThreadPoolJob *) jobB; - - assert(jobA != NULL); - assert(jobB != NULL); + ThreadPoolJob *a = (ThreadPoolJob *)jobA; + ThreadPoolJob *b = (ThreadPoolJob *)jobB; return a->jobId == b->jobId; } @@ -221,8 +213,6 @@ static int CmpThreadPoolJob(void *jobA, void *jobB) *****************************************************************************/ static void FreeThreadPoolJob(ThreadPool *tp, ThreadPoolJob *tpj) { - assert(tp != NULL); - FreeListFree(&tp->jobFreeList, tpj); } @@ -340,8 +330,6 @@ static void BumpPriority(ThreadPool *tp) unsigned long diffTime = 0; ThreadPoolJob *tempJob = NULL; - assert(tp != NULL); - gettimeofday(&now, NULL); while (!done) { if (tp->medJobQ.size) { @@ -389,12 +377,9 @@ static void SetRelTimeout( struct timespec *time, int relMillis ) int sec = relMillis / 1000; int milliSeconds = relMillis % 1000; - assert( time != NULL ); - - gettimeofday( &now, NULL ); - + gettimeofday(&now, NULL); time->tv_sec = now.tv_sec + sec; - time->tv_nsec = ( (now.tv_usec/1000) + milliSeconds ) * 1000000; + time->tv_nsec = (now.tv_usec / 1000 + milliSeconds) * 1000000; } /**************************************************************************** @@ -413,17 +398,20 @@ static void SetSeed() gettimeofday(&t, NULL); #if defined(WIN32) - srand( ( unsigned int )t.tv_usec + (unsigned int)ithread_get_current_thread_id().p ); + srand((unsigned int)t.tv_usec + (unsigned int)ithread_get_current_thread_id().p); #elif defined(BSD) || defined(__OSX__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) - srand( ( unsigned int )t.tv_usec + (unsigned int)ithread_get_current_thread_id() ); + srand((unsigned int)t.tv_usec + (unsigned int)ithread_get_current_thread_id()); #elif defined(__linux__) || defined(__sun) || defined(__CYGWIN__) || defined(__GLIBC__) - srand( ( unsigned int )t.tv_usec + ithread_get_current_thread_id() ); + srand((unsigned int)t.tv_usec + ithread_get_current_thread_id()); #else { - volatile union { volatile pthread_t tid; volatile unsigned i; } idu; + volatile union { + volatile pthread_t tid; + volatile unsigned i; + } idu; idu.tid = ithread_get_current_thread_id(); - srand( ( unsigned int )t.millitm + idu.i ); + srand((unsigned int)t.millitm + idu.i); } #endif } @@ -442,7 +430,7 @@ static void SetSeed() * Parameters: * void * arg -> is cast to ThreadPool * *****************************************************************************/ -static void *WorkerThread( void *arg ) +static void *WorkerThread(void *arg) { time_t start = 0; @@ -452,28 +440,23 @@ static void *WorkerThread( void *arg ) struct timespec timeout; int retCode = 0; int persistent = -1; - ThreadPool *tp = ( ThreadPool *) arg; - // allow static linking -#ifdef WIN32 -#ifdef PTW32_STATIC_LIB - pthread_win32_thread_attach_np(); -#endif -#endif - assert( tp != NULL ); + ThreadPool *tp = (ThreadPool *) arg; - // Increment total thread count - ithread_mutex_lock( &tp->mutex ); + ithread_initialize_thread(); + + /* Increment total thread count */ + ithread_mutex_lock(&tp->mutex); tp->totalThreads++; - ithread_cond_broadcast( &tp->start_and_shutdown ); - ithread_mutex_unlock( &tp->mutex ); + ithread_cond_broadcast(&tp->start_and_shutdown); + ithread_mutex_unlock(&tp->mutex); SetSeed(); - StatsTime( &start ); - while( 1 ) { - ithread_mutex_lock( &tp->mutex ); - if( job ) { + StatsTime(&start); + while (1) { + ithread_mutex_lock(&tp->mutex); + if (job) { tp->busyThreads--; - FreeThreadPoolJob( tp, job ); + FreeThreadPoolJob(tp, job); job = NULL; } retCode = 0; @@ -482,126 +465,100 @@ static void *WorkerThread( void *arg ) tp->stats.totalWorkTime += ( StatsTime( NULL ) - start ); // work time StatsTime( &start ); // idle time - if( persistent == 1 ) { - // Persistent thread - // becomes a regular thread + if (persistent == 0) { + tp->stats.workerThreads--; + } else if (persistent == 1) { + /* Persistent thread becomes a regular thread */ tp->persistentThreads--; } - if( persistent == 0 ) { - tp->stats.workerThreads--; - } - - // Check for a job or shutdown - while( tp->lowJobQ.size == 0 && + /* Check for a job or shutdown */ + while (tp->lowJobQ.size == 0 && tp->medJobQ.size == 0 && tp->highJobQ.size == 0 && - !tp->persistentJob && - !tp->shutdown ) { - // If wait timed out - // and we currently have more than the - // min threads, or if we have more than the max threads - // (only possible if the attributes have been reset) - // let this thread die. - if( ( retCode == ETIMEDOUT && - tp->totalThreads > tp->attr.minThreads ) || - ( tp->attr.maxThreads != -1 && - tp->totalThreads > tp->attr.maxThreads ) ) { + !tp->persistentJob && !tp->shutdown) { + /* If wait timed out and we currently have more than the + * min threads, or if we have more than the max threads + * (only possible if the attributes have been reset) + * let this thread die. */ + if ((retCode == ETIMEDOUT && + tp->totalThreads > tp->attr.minThreads) || + (tp->attr.maxThreads != -1 && + tp->totalThreads > tp->attr.maxThreads)) { tp->stats.idleThreads--; - tp->totalThreads--; - ithread_cond_broadcast( &tp->start_and_shutdown ); - ithread_mutex_unlock( &tp->mutex ); -#ifdef WIN32 -#ifdef PTW32_STATIC_LIB - // allow static linking - pthread_win32_thread_detach_np (); -#endif -#endif - return NULL; + goto exit_function; } - SetRelTimeout( &timeout, tp->attr.maxIdleTime ); + SetRelTimeout(&timeout, tp->attr.maxIdleTime); - // wait for a job up to the specified max time + /* wait for a job up to the specified max time */ retCode = ithread_cond_timedwait( - &tp->condition, &tp->mutex, &timeout ); + &tp->condition, &tp->mutex, &timeout); } - tp->stats.idleThreads--; - tp->stats.totalIdleTime += ( StatsTime( NULL ) - start ); // idle time - StatsTime( &start ); // work time - - // bump priority of starved jobs - BumpPriority( tp ); - - // if shutdown then stop - if( tp->shutdown ) { - tp->totalThreads--; - ithread_cond_broadcast( &tp->start_and_shutdown ); - ithread_mutex_unlock( &tp->mutex ); -#ifdef WIN32 -#ifdef PTW32_STATIC_LIB - // allow static linking - pthread_win32_thread_detach_np (); -#endif -#endif - return NULL; + /* idle time */ + tp->stats.totalIdleTime += StatsTime(NULL) - start; + /* work time */ + StatsTime(&start); + /* bump priority of starved jobs */ + BumpPriority(tp); + /* if shutdown then stop */ + if (tp->shutdown) { + goto exit_function; } else { - // Pick up persistent job if available - if( tp->persistentJob ) { + /* Pick up persistent job if available */ + if (tp->persistentJob) { job = tp->persistentJob; tp->persistentJob = NULL; tp->persistentThreads++; persistent = 1; - ithread_cond_broadcast( &tp->start_and_shutdown ); + ithread_cond_broadcast(&tp->start_and_shutdown); } else { tp->stats.workerThreads++; persistent = 0; - // Pick the highest priority job - if( tp->highJobQ.size > 0 ) { - head = ListHead( &tp->highJobQ ); - job = ( ThreadPoolJob *) head->item; - CalcWaitTime( tp, HIGH_PRIORITY, job ); - ListDelNode( &tp->highJobQ, head, 0 ); - } else if( tp->medJobQ.size > 0 ) { - head = ListHead( &tp->medJobQ ); - job = ( ThreadPoolJob *) head->item; - CalcWaitTime( tp, MED_PRIORITY, job ); - ListDelNode( &tp->medJobQ, head, 0 ); - } else if( tp->lowJobQ.size > 0 ) { - head = ListHead( &tp->lowJobQ ); - job = ( ThreadPoolJob *) head->item; - CalcWaitTime( tp, LOW_PRIORITY, job ); - ListDelNode( &tp->lowJobQ, head, 0 ); + /* Pick the highest priority job */ + if (tp->highJobQ.size > 0) { + head = ListHead(&tp->highJobQ); + job = (ThreadPoolJob *) head->item; + CalcWaitTime(tp, HIGH_PRIORITY, job); + ListDelNode(&tp->highJobQ, head, 0); + } else if (tp->medJobQ.size > 0) { + head = ListHead(&tp->medJobQ); + job = (ThreadPoolJob *) head->item; + CalcWaitTime(tp, MED_PRIORITY, job); + ListDelNode(&tp->medJobQ, head, 0); + } else if (tp->lowJobQ.size > 0) { + head = ListHead(&tp->lowJobQ); + job = (ThreadPoolJob *) head->item; + CalcWaitTime(tp, LOW_PRIORITY, job); + ListDelNode(&tp->lowJobQ, head, 0); } else { - // Should never get here - assert( 0 ); + /* Should never get here */ tp->stats.workerThreads--; - tp->totalThreads--; - ithread_cond_broadcast( &tp->start_and_shutdown ); - ithread_mutex_unlock( &tp->mutex ); - - return NULL; + goto exit_function; } } } tp->busyThreads++; - ithread_mutex_unlock( &tp->mutex ); + ithread_mutex_unlock(&tp->mutex); - if( SetPriority( job->priority ) != 0 ) { - // In the future can log - // info + /* In the future can log info */ + if (SetPriority(job->priority) != 0) { } else { - // In the future can log - // info } - - // run the job - job->func( job->arg ); - - // return to Normal - SetPriority( DEFAULT_PRIORITY ); + /* run the job */ + job->func(job->arg); + /* return to Normal */ + SetPriority(DEFAULT_PRIORITY); } + +exit_function: + tp->totalThreads--; + ithread_cond_broadcast(&tp->start_and_shutdown); + ithread_mutex_unlock(&tp->mutex); + ithread_cleanup_thread(); + + return NULL; } /**************************************************************************** @@ -617,18 +574,15 @@ static void *WorkerThread( void *arg ) * Returns: * ThreadPoolJob *on success, NULL on failure. *****************************************************************************/ -static ThreadPoolJob *CreateThreadPoolJob( ThreadPoolJob *job, int id, ThreadPool *tp ) +static ThreadPoolJob *CreateThreadPoolJob(ThreadPoolJob *job, int id, ThreadPool *tp) { ThreadPoolJob *newJob = NULL; - assert( job != NULL ); - assert( tp != NULL ); - - newJob = (ThreadPoolJob *)FreeListAlloc( &tp->jobFreeList ); - if( newJob ) { + newJob = (ThreadPoolJob *)FreeListAlloc(&tp->jobFreeList); + if (newJob) { *newJob = *job; newJob->jobId = id; - gettimeofday( &newJob->requestTime, NULL ); + gettimeofday(&newJob->requestTime, NULL); } return newJob; @@ -650,28 +604,24 @@ static ThreadPoolJob *CreateThreadPoolJob( ThreadPoolJob *job, int id, ThreadPoo * EAGAIN if system can not create thread * *****************************************************************************/ -static int CreateWorker( ThreadPool *tp ) +static int CreateWorker(ThreadPool *tp) { ithread_t temp; int rc = 0; int currentThreads = tp->totalThreads + 1; - assert( tp != NULL ); - - if ( tp->attr.maxThreads != INFINITE_THREADS && - currentThreads > tp->attr.maxThreads ) { + if (tp->attr.maxThreads != INFINITE_THREADS && + currentThreads > tp->attr.maxThreads) { return EMAXTHREADS; } - - rc = ithread_create( &temp, NULL, WorkerThread, tp ); - if( rc == 0 ) { - rc = ithread_detach( temp ); - while( tp->totalThreads < currentThreads ) { - ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex ); + rc = ithread_create(&temp, NULL, WorkerThread, tp); + if (rc == 0) { + rc = ithread_detach(temp); + while (tp->totalThreads < currentThreads) { + ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex); } } - - if( tp->stats.maxThreads < tp->totalThreads ) { + if (tp->stats.maxThreads < tp->totalThreads) { tp->stats.maxThreads = tp->totalThreads; } @@ -695,13 +645,11 @@ static void AddWorker(ThreadPool *tp) int jobs = 0; int threads = 0; - assert( tp != NULL ); - jobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size; threads = tp->totalThreads - tp->persistentThreads; - while (threads == 0 || - (jobs / threads) >= tp->attr.jobsPerThread || - (tp->totalThreads == tp->busyThreads) ) { + while (threads == 0 || + (jobs / threads) >= tp->attr.jobsPerThread || + (tp->totalThreads == tp->busyThreads) ) { if (CreateWorker(tp) != 0) { return; } @@ -741,67 +689,43 @@ static void AddWorker(ThreadPool *tp) * INVALID_POLICY if schedPolicy can't be set * EMAXTHREADS if minimum threads is greater than maximum threads *****************************************************************************/ -int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr ) +int ThreadPoolInit(ThreadPool *tp, ThreadPoolAttr *attr) { int retCode = 0; int i = 0; - assert( tp != NULL ); - if( tp == NULL ) { + if (!tp) { return EINVAL; } -#ifdef WIN32 -#ifdef PTW32_STATIC_LIB - pthread_win32_process_attach_np(); -#endif -#endif - retCode += ithread_mutex_init( &tp->mutex, NULL ); - assert( retCode == 0 ); + retCode += ithread_mutex_init(&tp->mutex, NULL); + retCode += ithread_mutex_lock(&tp->mutex); - retCode += ithread_mutex_lock( &tp->mutex ); - assert( retCode == 0 ); - - retCode += ithread_cond_init( &tp->condition, NULL ); - assert( retCode == 0 ); - - retCode += ithread_cond_init( &tp->start_and_shutdown, NULL ); - assert( retCode == 0 ); - - if( retCode != 0 ) { + retCode += ithread_cond_init(&tp->condition, NULL); + retCode += ithread_cond_init(&tp->start_and_shutdown, NULL); + if (retCode) { return EAGAIN; } - - if( attr ) { - tp->attr = ( *attr ); + if (attr) { + tp->attr = *attr; } else { - TPAttrInit( &tp->attr ); + TPAttrInit(&tp->attr); } + if (SetPolicyType(tp->attr.schedPolicy) != 0) { + ithread_mutex_unlock(&tp->mutex); + ithread_mutex_destroy(&tp->mutex); + ithread_cond_destroy(&tp->condition); + ithread_cond_destroy(&tp->start_and_shutdown); - if( SetPolicyType( tp->attr.schedPolicy ) != 0 ) { - ithread_mutex_unlock( &tp->mutex ); - ithread_mutex_destroy( &tp->mutex ); - ithread_cond_destroy( &tp->condition ); - ithread_cond_destroy( &tp->start_and_shutdown ); return INVALID_POLICY; } - retCode += FreeListInit( - &tp->jobFreeList, sizeof( ThreadPoolJob ), JOBFREELISTSIZE ); - assert( retCode == 0 ); - - StatsInit( &tp->stats ); - - retCode += ListInit( &tp->highJobQ, CmpThreadPoolJob, NULL ); - assert( retCode == 0 ); - - retCode += ListInit( &tp->medJobQ, CmpThreadPoolJob, NULL ); - assert( retCode == 0 ); - - retCode += ListInit( &tp->lowJobQ, CmpThreadPoolJob, NULL ); - assert( retCode == 0 ); - - if( retCode != 0 ) { + &tp->jobFreeList, sizeof(ThreadPoolJob), JOBFREELISTSIZE); + StatsInit(&tp->stats); + retCode += ListInit(&tp->highJobQ, CmpThreadPoolJob, NULL); + retCode += ListInit(&tp->medJobQ, CmpThreadPoolJob, NULL); + retCode += ListInit(&tp->lowJobQ, CmpThreadPoolJob, NULL); + if (retCode) { retCode = EAGAIN; } else { tp->persistentJob = NULL; @@ -810,18 +734,19 @@ int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr ) tp->totalThreads = 0; tp->busyThreads = 0; tp->persistentThreads = 0; - for( i = 0; i < tp->attr.minThreads; ++i ) { - if( ( retCode = CreateWorker( tp ) ) != 0 ) { + for (i = 0; i < tp->attr.minThreads; ++i) { + retCode = CreateWorker(tp); + if (retCode) { break; } } } - ithread_mutex_unlock( &tp->mutex ); + ithread_mutex_unlock(&tp->mutex); - if( retCode != 0 ) { - // clean up if the min threads could not be created - ThreadPoolShutdown( tp ); + if (retCode) { + /* clean up if the min threads could not be created */ + ThreadPoolShutdown(tp); } return retCode; @@ -846,61 +771,53 @@ int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr ) * EOUTOFMEM not enough memory to add job. * EMAXTHREADS not enough threads to add persistent job. *****************************************************************************/ -int ThreadPoolAddPersistent( ThreadPool *tp, ThreadPoolJob *job, int *jobId ) +int ThreadPoolAddPersistent(ThreadPool *tp, ThreadPoolJob *job, int *jobId) { + int ret = 0; int tempId = -1; ThreadPoolJob *temp = NULL; - assert( tp != NULL ); - assert( job != NULL ); - if( ( tp == NULL ) || ( job == NULL ) ) { + if (!tp || !job) { return EINVAL; } - - if( jobId == NULL ) { + if (!jobId) { jobId = &tempId; } - *jobId = INVALID_JOB_ID; - ithread_mutex_lock( &tp->mutex ); + ithread_mutex_lock(&tp->mutex); - assert( job->priority == LOW_PRIORITY || - job->priority == MED_PRIORITY || - job->priority == HIGH_PRIORITY ); - - // Create A worker if less than max threads running - if( tp->totalThreads < tp->attr.maxThreads ) { - CreateWorker( tp ); + /* Create A worker if less than max threads running */ + if (tp->totalThreads < tp->attr.maxThreads) { + CreateWorker(tp); } else { - // if there is more than one worker thread - // available then schedule job, otherwise fail - if( tp->totalThreads - tp->persistentThreads - 1 == 0 ) { - ithread_mutex_unlock( &tp->mutex ); - return EMAXTHREADS; + /* if there is more than one worker thread + * available then schedule job, otherwise fail */ + if (tp->totalThreads - tp->persistentThreads - 1 == 0) { + ret = EMAXTHREADS; + goto exit_function; } } - - temp = CreateThreadPoolJob( job, tp->lastJobId, tp ); - if( temp == NULL ) { - ithread_mutex_unlock( &tp->mutex ); - return EOUTOFMEM; + temp = CreateThreadPoolJob(job, tp->lastJobId, tp); + if (!temp) { + ret = EOUTOFMEM; + goto exit_function; } - tp->persistentJob = temp; - // Notify a waiting thread - ithread_cond_signal( &tp->condition ); + /* Notify a waiting thread */ + ithread_cond_signal(&tp->condition); - // wait until long job has been picked up - while( tp->persistentJob != NULL ) { - ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex ); + /* wait until long job has been picked up */ + while (tp->persistentJob) { + ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex); } - *jobId = tp->lastJobId++; - ithread_mutex_unlock( &tp->mutex ); - return 0; +exit_function: + ithread_mutex_unlock(&tp->mutex); + + return ret; } /**************************************************************************** @@ -921,72 +838,60 @@ int ThreadPoolAddPersistent( ThreadPool *tp, ThreadPoolJob *job, int *jobId ) * 0 on success, nonzero on failure * EOUTOFMEM if not enough memory to add job. *****************************************************************************/ -int ThreadPoolAdd( ThreadPool *tp, ThreadPoolJob *job, int *jobId ) +int ThreadPoolAdd(ThreadPool *tp, ThreadPoolJob *job, int *jobId) { int rc = EOUTOFMEM; - int tempId = -1; int totalJobs; - ThreadPoolJob *temp = NULL; - assert( tp != NULL ); - assert( job != NULL ); - if( ( tp == NULL ) || ( job == NULL ) ) { + if (!tp || !job) { return EINVAL; } - ithread_mutex_lock( &tp->mutex ); - - assert( job->priority == LOW_PRIORITY || - job->priority == MED_PRIORITY || - job->priority == HIGH_PRIORITY ); + ithread_mutex_lock(&tp->mutex); totalJobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size; if (totalJobs >= tp->attr.maxJobsTotal) { fprintf(stderr, "total jobs = %d, too many jobs", totalJobs); - ithread_mutex_unlock( &tp->mutex ); - return rc; + goto exit_function; } - - if( jobId == NULL ) { + if (!jobId) { jobId = &tempId; } *jobId = INVALID_JOB_ID; - - temp = CreateThreadPoolJob( job, tp->lastJobId, tp ); - if( temp == NULL ) { - ithread_mutex_unlock( &tp->mutex ); - return rc; + temp = CreateThreadPoolJob(job, tp->lastJobId, tp); + if (!temp) { + goto exit_function; } - - if( job->priority == HIGH_PRIORITY ) { - if( ListAddTail( &tp->highJobQ, temp ) ) { + if (job->priority == HIGH_PRIORITY) { + if (ListAddTail(&tp->highJobQ, temp)) { rc = 0; } - } else if( job->priority == MED_PRIORITY ) { - if( ListAddTail( &tp->medJobQ, temp ) ) { + } else if (job->priority == MED_PRIORITY) { + if (ListAddTail(&tp->medJobQ, temp)) { rc = 0; } } else { - if( ListAddTail( &tp->lowJobQ, temp ) ) { + if (ListAddTail(&tp->lowJobQ, temp)) { rc = 0; } } - // AddWorker if appropriate - AddWorker( tp ); + /* AddWorker if appropriate */ + AddWorker(tp); - // Notify a waiting thread - if( rc == 0 ) { - ithread_cond_signal( &tp->condition ); + /* Notify a waiting thread */ + if (rc == 0) { + ithread_cond_signal(&tp->condition); } else { - FreeThreadPoolJob( tp, temp ); + FreeThreadPoolJob(tp, temp); } *jobId = tp->lastJobId++; - ithread_mutex_unlock( &tp->mutex ); +exit_function: + ithread_mutex_unlock(&tp->mutex); return rc; } @@ -1007,69 +912,61 @@ int ThreadPoolAdd( ThreadPool *tp, ThreadPoolJob *job, int *jobId ) * Returns: * 0 on success. INVALID_JOB_ID on failure. *****************************************************************************/ -int ThreadPoolRemove( ThreadPool *tp, int jobId, ThreadPoolJob *out ) +int ThreadPoolRemove(ThreadPool *tp, int jobId, ThreadPoolJob *out) { - ThreadPoolJob *temp = NULL; int ret = INVALID_JOB_ID; + ThreadPoolJob *temp = NULL; ListNode *tempNode = NULL; ThreadPoolJob dummy; - assert( tp != NULL ); - if( tp == NULL ) { + if (!tp) { return EINVAL; } - - if( out == NULL ) { + if (!out) { out = &dummy; } - dummy.jobId = jobId; - ithread_mutex_lock( &tp->mutex ); + ithread_mutex_lock(&tp->mutex); - tempNode = ListFind( &tp->highJobQ, NULL, &dummy ); - if( tempNode ) { + tempNode = ListFind(&tp->highJobQ, NULL, &dummy); + if (tempNode) { temp = (ThreadPoolJob *)tempNode->item; *out = *temp; - ListDelNode( &tp->highJobQ, tempNode, 0 ); - FreeThreadPoolJob( tp, temp ); - ithread_mutex_unlock( &tp->mutex ); - - return 0; + ListDelNode(&tp->highJobQ, tempNode, 0); + FreeThreadPoolJob(tp, temp); + ret = 0; + goto exit_function; } - tempNode = ListFind( &tp->medJobQ, NULL, &dummy ); - if( tempNode ) { + tempNode = ListFind(&tp->medJobQ, NULL, &dummy); + if (tempNode) { temp = (ThreadPoolJob *)tempNode->item; *out = *temp; - ListDelNode( &tp->medJobQ, tempNode, 0 ); - FreeThreadPoolJob( tp, temp ); - ithread_mutex_unlock( &tp->mutex ); - - return 0; + ListDelNode(&tp->medJobQ, tempNode, 0); + FreeThreadPoolJob(tp, temp); + ret = 0; + goto exit_function; } - - tempNode = ListFind( &tp->lowJobQ, NULL, &dummy ); - if( tempNode ) { + tempNode = ListFind(&tp->lowJobQ, NULL, &dummy); + if (tempNode) { temp = (ThreadPoolJob *)tempNode->item; *out = *temp; - ListDelNode( &tp->lowJobQ, tempNode, 0 ); - FreeThreadPoolJob( tp, temp ); - ithread_mutex_unlock( &tp->mutex ); - - return 0; + ListDelNode(&tp->lowJobQ, tempNode, 0); + FreeThreadPoolJob(tp, temp); + ret = 0; + goto exit_function; } - - if( tp->persistentJob && tp->persistentJob->jobId == jobId ) { + if (tp->persistentJob && tp->persistentJob->jobId == jobId) { *out = *tp->persistentJob; - FreeThreadPoolJob( tp, tp->persistentJob ); + FreeThreadPoolJob(tp, tp->persistentJob); tp->persistentJob = NULL; - ithread_mutex_unlock( &tp->mutex ); - - return 0; + ret = 0; + goto exit_function; } - ithread_mutex_unlock( &tp->mutex ); +exit_function: + ithread_mutex_unlock(&tp->mutex); return ret; } @@ -1087,22 +984,17 @@ int ThreadPoolRemove( ThreadPool *tp, int jobId, ThreadPoolJob *out ) * 0 on success, nonzero on failure * Always returns 0. *****************************************************************************/ -int ThreadPoolGetAttr( ThreadPool *tp, ThreadPoolAttr *out ) +int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out) { - assert( tp != NULL ); - assert( out != NULL ); - if( tp == NULL || out == NULL ) { + if (!tp || !out) { return EINVAL; } - - if( !tp->shutdown ) { - ithread_mutex_lock( &tp->mutex ); + if (!tp->shutdown) { + ithread_mutex_lock(&tp->mutex); } - *out = tp->attr; - - if( !tp->shutdown ) { - ithread_mutex_unlock( &tp->mutex ); + if (!tp->shutdown) { + ithread_mutex_unlock(&tp->mutex); } return 0; @@ -1121,49 +1013,46 @@ int ThreadPoolGetAttr( ThreadPool *tp, ThreadPoolAttr *out ) * 0 on success, nonzero on failure * Returns INVALID_POLICY if policy can not be set. *****************************************************************************/ -int ThreadPoolSetAttr( ThreadPool *tp, ThreadPoolAttr *attr ) +int ThreadPoolSetAttr(ThreadPool *tp, ThreadPoolAttr *attr) { int retCode = 0; ThreadPoolAttr temp; int i = 0; - assert( tp != NULL ); - if( tp == NULL ) { + if (!tp) { return EINVAL; } - ithread_mutex_lock( &tp->mutex ); - if( attr != NULL ) { - temp = ( *attr ); + ithread_mutex_lock(&tp->mutex); + + if (attr) { + temp = *attr; } else { - TPAttrInit( &temp ); + TPAttrInit(&temp); } - - if( SetPolicyType( temp.schedPolicy ) != 0 ) { - ithread_mutex_unlock( &tp->mutex ); + if (SetPolicyType(temp.schedPolicy) != 0) { + ithread_mutex_unlock(&tp->mutex); return INVALID_POLICY; } - - tp->attr = ( temp ); - - // add threads - if( tp->totalThreads < tp->attr.minThreads ) - { - for( i = tp->totalThreads; i < tp->attr.minThreads; i++ ) { - if( ( retCode = CreateWorker( tp ) ) != 0 ) { + tp->attr = temp; + /* add threads */ + if (tp->totalThreads < tp->attr.minThreads) { + for (i = tp->totalThreads; i < tp->attr.minThreads; i++) { + retCode = CreateWorker(tp); + if (retCode != 0) { break; } } } + /* signal changes */ + ithread_cond_signal(&tp->condition); - // signal changes - ithread_cond_signal( &tp->condition ); - ithread_mutex_unlock( &tp->mutex ); + ithread_mutex_unlock(&tp->mutex); - if( retCode != 0 ) { - // clean up if the min threads could not be created - ThreadPoolShutdown( tp ); + if (retCode != 0) { + /* clean up if the min threads could not be created */ + ThreadPoolShutdown(tp); } return retCode; @@ -1183,85 +1072,83 @@ int ThreadPoolSetAttr( ThreadPool *tp, ThreadPoolAttr *attr ) * 0 on success, nonzero on failure * Always returns 0. *****************************************************************************/ -int ThreadPoolShutdown( ThreadPool *tp ) +int ThreadPoolShutdown(ThreadPool *tp) { ListNode *head = NULL; ThreadPoolJob *temp = NULL; - assert( tp != NULL ); - if( tp == NULL ) { + if (!tp) { return EINVAL; } - ithread_mutex_lock( &tp->mutex ); + ithread_mutex_lock(&tp->mutex); - // clean up high priority jobs - while( tp->highJobQ.size ) { - head = ListHead( &tp->highJobQ ); - temp = ( ThreadPoolJob *) head->item; - if( temp->free_func ) { - temp->free_func( temp->arg ); + /* clean up high priority jobs */ + while (tp->highJobQ.size) { + head = ListHead(&tp->highJobQ); + temp = (ThreadPoolJob *)head->item; + if (temp->free_func) { + temp->free_func(temp->arg); } - FreeThreadPoolJob( tp, temp ); - ListDelNode( &tp->highJobQ, head, 0 ); + FreeThreadPoolJob(tp, temp); + ListDelNode(&tp->highJobQ, head, 0); } - ListDestroy( &tp->highJobQ, 0 ); + ListDestroy(&tp->highJobQ, 0); - // clean up med priority jobs - while( tp->medJobQ.size ) { - head = ListHead( &tp->medJobQ ); - temp = ( ThreadPoolJob *) head->item; - if( temp->free_func ) { - temp->free_func( temp->arg ); + /* clean up med priority jobs */ + while (tp->medJobQ.size) { + head = ListHead(&tp->medJobQ); + temp = (ThreadPoolJob *)head->item; + if (temp->free_func) { + temp->free_func(temp->arg); } - FreeThreadPoolJob( tp, temp ); - ListDelNode( &tp->medJobQ, head, 0 ); + FreeThreadPoolJob(tp, temp); + ListDelNode(&tp->medJobQ, head, 0); } - ListDestroy( &tp->medJobQ, 0 ); + ListDestroy(&tp->medJobQ, 0); - // clean up low priority jobs - while( tp->lowJobQ.size ) { - head = ListHead( &tp->lowJobQ ); - temp = ( ThreadPoolJob *) head->item; - if( temp->free_func ) { - temp->free_func( temp->arg ); + /* clean up low priority jobs */ + while (tp->lowJobQ.size) { + head = ListHead(&tp->lowJobQ); + temp = (ThreadPoolJob *)head->item; + if (temp->free_func) { + temp->free_func(temp->arg); } - FreeThreadPoolJob( tp, temp ); - ListDelNode( &tp->lowJobQ, head, 0 ); + FreeThreadPoolJob(tp, temp); + ListDelNode(&tp->lowJobQ, head, 0); } - ListDestroy( &tp->lowJobQ, 0 ); + ListDestroy(&tp->lowJobQ, 0); - // clean up long term job - if( tp->persistentJob ) { + /* clean up long term job */ + if (tp->persistentJob) { temp = tp->persistentJob; - if( temp->free_func ) { - temp->free_func( temp->arg ); + if (temp->free_func) { + temp->free_func(temp->arg); } - FreeThreadPoolJob( tp, temp ); + FreeThreadPoolJob(tp, temp); tp->persistentJob = NULL; } - - // signal shutdown + /* signal shutdown */ tp->shutdown = 1; - ithread_cond_broadcast( &tp->condition ); - - // wait for all threads to finish - while( tp->totalThreads > 0 ) { - ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex ); + ithread_cond_broadcast(&tp->condition); + /* wait for all threads to finish */ + while (tp->totalThreads > 0) { + ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex); } - - // destroy condition - while( ithread_cond_destroy( &tp->condition ) != 0 ) { + /* destroy condition */ + while (ithread_cond_destroy(&tp->condition) != 0) { + /**/ } - while( ithread_cond_destroy( &tp->start_and_shutdown ) != 0 ) { + while (ithread_cond_destroy(&tp->start_and_shutdown) != 0) { + /**/ } + FreeListDestroy(&tp->jobFreeList); - FreeListDestroy( &tp->jobFreeList ); + ithread_mutex_unlock(&tp->mutex); - ithread_mutex_unlock( &tp->mutex ); - - // destroy mutex - while( ithread_mutex_destroy( &tp->mutex ) != 0 ) { + /* destroy mutex */ + while (ithread_mutex_destroy(&tp->mutex) != 0) { + /**/ } return 0; @@ -1278,13 +1165,11 @@ int ThreadPoolShutdown( ThreadPool *tp ) * Returns: * Always returns 0. *****************************************************************************/ -int TPAttrInit( ThreadPoolAttr *attr ) +int TPAttrInit(ThreadPoolAttr *attr) { - assert( attr != NULL ); - if( attr == NULL ) { + if (!attr) { return EINVAL; } - attr->jobsPerThread = DEFAULT_JOBS_PER_THREAD; attr->maxIdleTime = DEFAULT_IDLE_TIME; attr->maxThreads = DEFAULT_MAX_THREADS; @@ -1310,14 +1195,11 @@ int TPAttrInit( ThreadPoolAttr *attr ) * Returns: * Always returns 0. *****************************************************************************/ -int TPJobInit( ThreadPoolJob *job, start_routine func, void *arg ) +int TPJobInit(ThreadPoolJob *job, start_routine func, void *arg) { - assert( job != NULL ); - assert( func != NULL ); - if( job == NULL || func == NULL ) { + if (!job || !func) { return EINVAL; } - job->func = func; job->arg = arg; job->priority = DEFAULT_PRIORITY; @@ -1338,16 +1220,14 @@ int TPJobInit( ThreadPoolJob *job, start_routine func, void *arg ) * Returns 0 on success nonzero on failure. * Returns EINVAL if invalid priority. *****************************************************************************/ -int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority ) +int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority) { - assert( job != NULL ); - if( job == NULL ) { + if (!job) { return EINVAL; } - - if( priority == LOW_PRIORITY || + if (priority == LOW_PRIORITY || priority == MED_PRIORITY || - priority == HIGH_PRIORITY ) { + priority == HIGH_PRIORITY) { job->priority = priority; return 0; } else { @@ -1366,13 +1246,11 @@ int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority ) * Returns: * Always returns 0. *****************************************************************************/ -int TPJobSetFreeFunction( ThreadPoolJob *job, free_routine func ) +int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func) { - assert( job != NULL ); - if( job == NULL ) { + if(!job) { return EINVAL; } - job->free_func = func; return 0; @@ -1389,13 +1267,11 @@ int TPJobSetFreeFunction( ThreadPoolJob *job, free_routine func ) * Returns: * Always returns 0. *****************************************************************************/ -int TPAttrSetMaxThreads( ThreadPoolAttr *attr, int maxThreads ) +int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads) { - assert( attr != NULL ); - if( attr == NULL ) { + if (!attr) { return EINVAL; } - attr->maxThreads = maxThreads; return 0; @@ -1412,13 +1288,11 @@ int TPAttrSetMaxThreads( ThreadPoolAttr *attr, int maxThreads ) * Returns: * Always returns 0. *****************************************************************************/ -int TPAttrSetMinThreads( ThreadPoolAttr *attr, int minThreads ) +int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads) { - assert( attr != NULL ); - if( attr == NULL ) { + if (!attr) { return EINVAL; } - attr->minThreads = minThreads; return 0; @@ -1434,13 +1308,11 @@ int TPAttrSetMinThreads( ThreadPoolAttr *attr, int minThreads ) * Returns: * Always returns 0. *****************************************************************************/ -int TPAttrSetIdleTime( ThreadPoolAttr *attr, int idleTime ) +int TPAttrSetIdleTime(ThreadPoolAttr *attr, int idleTime) { - assert( attr != NULL ); - if( attr == NULL ) { + if (!attr) { return EINVAL; } - attr->maxIdleTime = idleTime; return 0; @@ -1456,13 +1328,11 @@ int TPAttrSetIdleTime( ThreadPoolAttr *attr, int idleTime ) * Returns: * Always returns 0. *****************************************************************************/ -int TPAttrSetJobsPerThread( ThreadPoolAttr *attr, int jobsPerThread ) +int TPAttrSetJobsPerThread(ThreadPoolAttr *attr, int jobsPerThread) { - assert( attr != NULL ); - if( attr == NULL ) { + if (!attr) { return EINVAL; } - attr->jobsPerThread = jobsPerThread; return 0; @@ -1478,13 +1348,11 @@ int TPAttrSetJobsPerThread( ThreadPoolAttr *attr, int jobsPerThread ) * Returns: * Always returns 0. *****************************************************************************/ -int TPAttrSetStarvationTime( ThreadPoolAttr *attr, int starvationTime ) +int TPAttrSetStarvationTime(ThreadPoolAttr *attr, int starvationTime) { - assert( attr != NULL ); - if( attr == NULL ) { + if (!attr) { return EINVAL; } - attr->starvationTime = starvationTime; return 0; @@ -1501,13 +1369,11 @@ int TPAttrSetStarvationTime( ThreadPoolAttr *attr, int starvationTime ) * Returns: * Always returns 0. *****************************************************************************/ -int TPAttrSetSchedPolicy( ThreadPoolAttr *attr, PolicyType schedPolicy ) +int TPAttrSetSchedPolicy(ThreadPoolAttr *attr, PolicyType schedPolicy) { - assert( attr != NULL ); - if( attr == NULL ) { + if (!attr) { return EINVAL; } - attr->schedPolicy = schedPolicy; return 0; @@ -1524,13 +1390,11 @@ int TPAttrSetSchedPolicy( ThreadPoolAttr *attr, PolicyType schedPolicy ) * Returns: * Always returns 0. *****************************************************************************/ -int TPAttrSetMaxJobsTotal( ThreadPoolAttr *attr, int maxJobsTotal ) +int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal) { - assert( attr != NULL ); - if( attr == NULL ) { + if (!attr) { return EINVAL; } - attr->maxJobsTotal = maxJobsTotal; return 0; @@ -1540,11 +1404,9 @@ int TPAttrSetMaxJobsTotal( ThreadPoolAttr *attr, int maxJobsTotal ) #ifdef STATS void ThreadPoolPrintStats(ThreadPoolStats *stats) { - assert( stats != NULL ); - if (stats == NULL) { + if (!stats) { return; } - /* some OSses time_t length may depending on platform, promote it to long for safety */ printf("ThreadPoolStats at Time: %ld\n", (long)StatsTime(NULL)); printf("High Jobs pending: %d\n", stats->currentJobsHQ); @@ -1578,15 +1440,13 @@ void ThreadPoolPrintStats(ThreadPoolStats *stats) * Always returns 0. *****************************************************************************/ #ifdef STATS -int ThreadPoolGetStats( ThreadPool *tp, ThreadPoolStats *stats ) +int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats) { - assert(tp != NULL); - assert(stats != NULL); if (tp == NULL || stats == NULL) { return EINVAL; } - //if not shutdown then acquire mutex + /* if not shutdown then acquire mutex */ if (!tp->shutdown) { ithread_mutex_lock(&tp->mutex); } @@ -1597,28 +1457,24 @@ int ThreadPoolGetStats( ThreadPool *tp, ThreadPoolStats *stats ) } else { stats->avgWaitHQ = 0; } - - if( stats->totalJobsMQ > 0 ) { + if (stats->totalJobsMQ > 0) { stats->avgWaitMQ = stats->totalTimeMQ / stats->totalJobsMQ; } else { stats->avgWaitMQ = 0; } - - if( stats->totalJobsLQ > 0 ) { + if (stats->totalJobsLQ > 0) { stats->avgWaitLQ = stats->totalTimeLQ / stats->totalJobsLQ; } else { stats->avgWaitLQ = 0; } - stats->totalThreads = tp->totalThreads; stats->persistentThreads = tp->persistentThreads; stats->currentJobsHQ = ListSize( &tp->highJobQ ); stats->currentJobsLQ = ListSize( &tp->lowJobQ ); stats->currentJobsMQ = ListSize( &tp->medJobQ ); - - //if not shutdown then release mutex - if( !tp->shutdown ) { - ithread_mutex_unlock( &tp->mutex ); + /* if not shutdown then release mutex */ + if (!tp->shutdown) { + ithread_mutex_unlock(&tp->mutex); } return 0; @@ -1628,44 +1484,42 @@ int ThreadPoolGetStats( ThreadPool *tp, ThreadPoolStats *stats ) #ifdef WIN32 + #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 #else #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL #endif - + int gettimeofday(struct timeval *tv, struct timezone *tz) { - FILETIME ft; - unsigned __int64 tmpres = 0; - static int tzflag; + FILETIME ft; + unsigned __int64 tmpres = 0; + static int tzflag; - if (NULL != tv) - { - GetSystemTimeAsFileTime(&ft); + if (tv) { + GetSystemTimeAsFileTime(&ft); - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; + tmpres |= ft.dwHighDateTime; + tmpres <<= 32; + tmpres |= ft.dwLowDateTime; - /*converting file time to unix epoch*/ - tmpres /= 10; /*convert into microseconds*/ - tmpres -= DELTA_EPOCH_IN_MICROSECS; - tv->tv_sec = (long)(tmpres / 1000000UL); - tv->tv_usec = (long)(tmpres % 1000000UL); - } + /*converting file time to unix epoch*/ + tmpres /= 10; /*convert into microseconds*/ + tmpres -= DELTA_EPOCH_IN_MICROSECS; + tv->tv_sec = (long)(tmpres / 1000000UL); + tv->tv_usec = (long)(tmpres % 1000000UL); + } + if (tz) { + if (!tzflag) { + _tzset(); + tzflag++; + } + tz->tz_minuteswest = _timezone / 60; + tz->tz_dsttime = _daylight; + } - if (NULL != tz) - { - if (!tzflag) - { - _tzset(); - tzflag++; - } - tz->tz_minuteswest = _timezone / 60; - tz->tz_dsttime = _daylight; - } - - return 0; + return 0; } #endif /* WIN32 */ + diff --git a/upnp/src/api/upnpapi.c b/upnp/src/api/upnpapi.c index 4814816..f8ff706 100644 --- a/upnp/src/api/upnpapi.c +++ b/upnp/src/api/upnpapi.c @@ -204,6 +204,9 @@ int UpnpInit(const char *HostIP, unsigned short DestPort) { int retVal = UPNP_E_SUCCESS; + /* Initializes the ithread library */ + ithread_initialize_library(); + ithread_mutex_lock(&gSDKInitMutex); /* Check if we're already initialized. */ @@ -257,6 +260,9 @@ int UpnpInit2(const char *IfName, unsigned short DestPort) { int retVal; + /* Initializes the ithread library */ + ithread_initialize_library(); + ithread_mutex_lock(&gSDKInitMutex); /* Check if we're already initialized. */ @@ -308,10 +314,6 @@ int UpnpFinish(void) #endif struct Handle_Info *temp; -#ifdef WIN32 - /*WSACleanup();*/ -#endif - if( UpnpSdkInit != 1 ) { return UPNP_E_FINISH; } @@ -361,19 +363,15 @@ int UpnpFinish(void) ithread_rwlock_destroy(&GlobalHndRWLock); ithread_mutex_destroy(&gUUIDMutex); - // remove all virtual dirs + /* remove all virtual dirs */ UpnpRemoveAllVirtualDirs(); - // allow static linking -#ifdef WIN32 -#ifdef PTW32_STATIC_LIB - pthread_win32_thread_detach_np(); -#endif -#endif + /* Clean-up ithread library resources */ + ithread_cleanup_library(); UpnpSdkInit = 0; UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, - "Exiting UpnpFinish : UpnpSdkInit is :%d:\n", UpnpSdkInit); + "Exiting UpnpFinish: UpnpSdkInit is :%d:\n", UpnpSdkInit); UpnpCloseLog(); return UPNP_E_SUCCESS;