From f6dd5062fe6d2ba9fff0701855e766a987a755c5 Mon Sep 17 00:00:00 2001 From: Marcelo Roberto Jimenez Date: Thu, 27 Dec 2007 02:14:02 +0000 Subject: [PATCH] Merge of trunk into branch-1.6.x. git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@284 119443c7-1b9e-41f8-b6fc-b9c35fce742c --- ChangeLog | 31 +- THANKS | 8 +- configure.ac | 242 +++-- ixml/src/inc/ixmlmembuf.h | 6 +- ixml/src/ixmlparser.c | 32 +- threadutil/Makefile.am | 8 +- threadutil/inc/ThreadPool.h | 171 ++-- threadutil/inc/iasnprintf.h | 66 -- threadutil/src/ThreadPool.c | 1809 +++++++++++++++++------------------ threadutil/src/iasnprintf.c | 153 --- upnp/Makefile.am | 6 +- upnp/sample/Makefile.am | 4 - 12 files changed, 1169 insertions(+), 1367 deletions(-) delete mode 100644 threadutil/inc/iasnprintf.h delete mode 100644 threadutil/src/iasnprintf.c diff --git a/ChangeLog b/ChangeLog index 847618f..0edd3a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +******************************************************************************* +Version 1.6.3 +******************************************************************************* + +2007-12-25 Marcelo Jimenez + * Using pthread flags for the whole project, not just at the places + individually indicated by several Makefile.am files spread all over + the directories. That was too much error prone. + +2007-12-24 Marcelo Jimenez + * Added a configure test to check if pthread_rwlock_t is available. + Define _GNU_SOURCE if needed. The fallback behaviou will only be + implemented if _GNU_SOURCE prooves to be insufficient on some + platforms. Thanks to Jonathan Casiot (no_dice) and Robert Gingher + (robsbox). + +2007-12-17 Marcelo Jimenez + * Removed unused iasnprintf.{c,h} files. + +2007-12-17 Marcelo Jimenez + * Removed STATSONLY() macro from ThreadPool.{c,h}. + * Removed time() usage from ThreadPool.c. + * Fixed STATS = 0 compilation. + +2007-12-16 Marcelo Jimenez + * Library was not compiling on FreeBSD 7. Code now no longer uses + ftime(), using gettimeofday() instead. Thanks to Josh Carroll. + + ******************************************************************************* Version 1.6.2 ******************************************************************************* @@ -358,7 +387,7 @@ Version 1.4.2 2007-01-23 Marcelo Jimenez * SF Tracker [ 1634922 ] Support for large files (>= 2 GiB), part 2 - Submitted By: Jonathan - no_dice + Submitted By: Jonathan Casiot - no_dice Summary: This patch hopefully fixes the remaining types and related code to enable files >= 2 GiB to be streamed. Jonathan claims to have tested this with a patched version of ushare-0.9.8 and a D-Link DSM-520. diff --git a/THANKS b/THANKS index 3a2c575..ec9682e 100644 --- a/THANKS +++ b/THANKS @@ -22,18 +22,20 @@ exempt of errors. - Glen Masgai - Jiri Zouhar - John Dennis -- Jonathan (no_dice) +- Jonathan Casiot (no_dice) +- Josh Carroll - Keith Brindley - Leuk_He - Loigu - Luke Kim - Marcelo Roberto Jimenez (mroberto) - Markus Strobl -- Nektarios K. Papadopoulos +- Nektarios K. Papadopoulos (npapadop) - Oskar Liljeblad -- Michael (Oxy) +- Michael (oxygenic) - Paul Vixie - Rene Hexel +- Robert Gingher (robsbox) - Siva Chandran - Stéphane Corthésy - Steve Bresson diff --git a/configure.ac b/configure.ac index 74b0f82..c8e84d2 100644 --- a/configure.ac +++ b/configure.ac @@ -9,103 +9,115 @@ AC_PREREQ(2.60) -AC_INIT([libupnp], [1.6.2], [mroberto@users.sourceforge.net]) -############################################################################### -# *Independently* of the above libupnp package version, the libtool version -# of the 3 libraries need to be updated whenever there is a change released: -# "current:revision:age" (this is NOT the same as the package version), where: -# - library code modified: revision++ -# - interfaces changed/added/removed: current++ and revision=0 -# - interfaces added: age++ -# - interfaces removed: age=0 -# *please update only once, before a formal release, not for each change* -# -############################################################################### -# Release 1.4.1: -#AC_SUBST([LT_VERSION_IXML], [2:2:0]) -#AC_SUBST([LT_VERSION_THREADUTIL], [2:2:0]) -#AC_SUBST([LT_VERSION_UPNP], [2:2:0]) -# -############################################################################### -# Release 1.4.6: -# "current:revision:age" -# -# - Code has changed in ixml -# revision: 2 -> 3 -# - Code has changed in threadutil -# revision: 2 -> 3 -# - Interface added in threadutil -# current: 2 -> 3 -# revisiion: 3 -> 0 -# age: 0 -> 1 -# - Code has changed in upnp -# revision: 2 -> 3 -# -#AC_SUBST([LT_VERSION_IXML], [2:3:0]) -#AC_SUBST([LT_VERSION_THREADUTIL], [3:0:1]) -#AC_SUBST([LT_VERSION_UPNP], [2:3:0]) -# -############################################################################### -# Release 1.6.0: -# "current:revision:age" -# -# - Code has changed in ixml -# revision: 3 -> 4 -# - Code has changed in threadutil -# revision: 0 -> 1 -# - Code has changed in upnp -# revision: 3 -> 4 -# - Interface changed in upnp -# current: 2 -> 3 -# revision: 4 -> 0 -# - Interface removed in upnp -# age: 0 -> 0 -# -#AC_SUBST([LT_VERSION_IXML], [2:4:0]) -#AC_SUBST([LT_VERSION_THREADUTIL], [3:1:1]) -#AC_SUBST([LT_VERSION_UPNP], [3:0:0]) -# -############################################################################### -# Release 1.6.1: -# "current:revision:age" -# -# - Code has changed in threadutil -# revision: 1 -> 2 -# - Interface added in threadutil -# current: 3 -> 4 -# revision: 2 -> 0 -# - Interface added in threadutil -# age: 1 -> 2 -# - Code has changed in upnp -# revision: 0 -> 1 -# -#AC_SUBST([LT_VERSION_IXML], [2:4:0]) -#AC_SUBST([LT_VERSION_THREADUTIL], [4:0:2]) -#AC_SUBST([LT_VERSION_UPNP], [3:1:0]) -# -############################################################################### -# Release 1.6.2: -# "current:revision:age" -# -# - Code has changed in upnp -# revision: 1 -> 2 -# -#AC_SUBST([LT_VERSION_IXML], [2:4:0]) -#AC_SUBST([LT_VERSION_THREADUTIL], [4:0:2]) -#AC_SUBST([LT_VERSION_UPNP], [3:2:0]) -# -############################################################################### +AC_INIT([libupnp], [1.6.3], [mroberto@users.sourceforge.net]) +dnl ############################################################################ +dnl # *Independently* of the above libupnp package version, the libtool version +dnl # of the 3 libraries need to be updated whenever there is a change released: +dnl # "current:revision:age" (this is NOT the same as the package version), +dnl # where: +dnl # - library code modified: revision++ +dnl # - interfaces changed/added/removed: current++ and revision=0 +dnl # - interfaces added: age++ +dnl # - interfaces removed: age=0 +dnl # *please update only once, before a formal release, not for each change* +dnl # +dnl ############################################################################ +dnl # Release 1.4.1: +dnl #AC_SUBST([LT_VERSION_IXML], [2:2:0]) +dnl #AC_SUBST([LT_VERSION_THREADUTIL], [2:2:0]) +dnl #AC_SUBST([LT_VERSION_UPNP], [2:2:0]) +dnl # +dnl ############################################################################ +dnl # Release 1.4.6: +dnl # "current:revision:age" +dnl # +dnl # - Code has changed in ixml +dnl # revision: 2 -> 3 +dnl # - Code has changed in threadutil +dnl # revision: 2 -> 3 +dnl # - Interface added in threadutil +dnl # current: 2 -> 3 +dnl # revisiion: 3 -> 0 +dnl # age: 0 -> 1 +dnl # - Code has changed in upnp +dnl # revision: 2 -> 3 +dnl # +dnl #AC_SUBST([LT_VERSION_IXML], [2:3:0]) +dnl #AC_SUBST([LT_VERSION_THREADUTIL], [3:0:1]) +dnl #AC_SUBST([LT_VERSION_UPNP], [2:3:0]) +dnl # +dnl ############################################################################ +dnl # Release 1.6.0: +dnl # "current:revision:age" +dnl # +dnl # - Code has changed in ixml +dnl # revision: 3 -> 4 +dnl # - Code has changed in threadutil +dnl # revision: 0 -> 1 +dnl # - Code has changed in upnp +dnl # revision: 3 -> 4 +dnl # - Interface changed in upnp +dnl # current: 2 -> 3 +dnl # revision: 4 -> 0 +dnl # - Interface removed in upnp +dnl # age: 0 -> 0 +dnl # +dnl #AC_SUBST([LT_VERSION_IXML], [2:4:0]) +dnl #AC_SUBST([LT_VERSION_THREADUTIL], [3:1:1]) +dnl #AC_SUBST([LT_VERSION_UPNP], [3:0:0]) +dnl # +dnl ############################################################################ +dnl # Release 1.6.1: +dnl # "current:revision:age" +dnl # +dnl # - Code has changed in threadutil +dnl # revision: 1 -> 2 +dnl # - Interface added in threadutil +dnl # current: 3 -> 4 +dnl # revision: 2 -> 0 +dnl # - Interface added in threadutil +dnl # age: 1 -> 2 +dnl # - Code has changed in upnp +dnl # revision: 0 -> 1 +dnl # +dnl #AC_SUBST([LT_VERSION_IXML], [2:4:0]) +dnl #AC_SUBST([LT_VERSION_THREADUTIL], [4:0:2]) +dnl #AC_SUBST([LT_VERSION_UPNP], [3:1:0]) +dnl # +dnl ############################################################################ +dnl # Release 1.6.2: +dnl # "current:revision:age" +dnl # +dnl # - Code has changed in upnp +dnl # revision: 1 -> 2 +dnl # +dnl #AC_SUBST([LT_VERSION_IXML], [2:4:0]) +dnl #AC_SUBST([LT_VERSION_THREADUTIL], [4:0:2]) +dnl #AC_SUBST([LT_VERSION_UPNP], [3:2:0]) +dnl # +dnl ############################################################################ +dnl # Release 1.6.3: +dnl # "current:revision:age" +dnl # +dnl # - Code has changed in threadutil +dnl # revision: 0 -> 1 +dnl # +dnl #AC_SUBST([LT_VERSION_IXML], [2:4:0]) +dnl #AC_SUBST([LT_VERSION_THREADUTIL], [4:1:2]) +dnl #AC_SUBST([LT_VERSION_UPNP], [3:2:0]) +dnl # +dnl ############################################################################ AC_SUBST([LT_VERSION_IXML], [2:4:0]) -AC_SUBST([LT_VERSION_THREADUTIL], [4:0:2]) +AC_SUBST([LT_VERSION_THREADUTIL], [4:1:2]) AC_SUBST([LT_VERSION_UPNP], [3:2:0]) -############################################################################### -# Repeating the algorithm so that it is closer to the modificatin place: -# - library code modified: revision++ -# - interfaces changed/added/removed: current++ and revision=0 -# - interfaces added: age++ -# - interfaces removed: age=0 -# *please update only once, before a formal release, not for each change* -############################################################################### +dnl ############################################################################ +dnl # Repeating the algorithm to place it closer to the modificatin place: +dnl # - library code modified: revision++ +dnl # - interfaces changed/added/removed: current++ and revision=0 +dnl # - interfaces added: age++ +dnl # - interfaces removed: age=0 +dnl # *please update only once, before a formal release, not for each change* +dnl ############################################################################ AC_CONFIG_AUX_DIR(config.aux) @@ -140,8 +152,7 @@ AC_REVISION([$Revision: 1.11 $]) upnpmaj=`echo "$PACKAGE_VERSION" | sed 's/\..*//' ` upnpmin=[`echo "$PACKAGE_VERSION" | sed 's/^[^.]\.// ; s/[^0-9].*$//' `] upnppatch=[`echo "$PACKAGE_VERSION" | sed 's/^[^.]\.[^.]\.// ; s/[^0-9].*$//' `] -AC_DEFINE_UNQUOTED([UPNP_VERSION_STRING], "$PACKAGE_VERSION", - [see upnpconfig.h]) +AC_DEFINE_UNQUOTED([UPNP_VERSION_STRING], "$PACKAGE_VERSION", [see upnpconfig.h]) AC_DEFINE_UNQUOTED([UPNP_VERSION_MAJOR], $upnpmaj, [see upnpconfig.h]) AC_DEFINE_UNQUOTED([UPNP_VERSION_MINOR], $upnpmin, [see upnpconfig.h]) AC_DEFINE_UNQUOTED([UPNP_VERSION_PATCH], $upnppatch, [see upnpconfig.h]) @@ -163,7 +174,6 @@ fi # # Check for libupnp subsets # - RT_BOOL_ARG_ENABLE([client], [yes], [control point code (client)]) if test "x$enable_client" = xyes ; then AC_DEFINE(UPNP_HAVE_CLIENT, 1, [see upnpconfig.h]) @@ -197,11 +207,13 @@ fi RT_BOOL_ARG_ENABLE([samples], [yes], [compilation of upnp/sample/ code]) +# # doc installation # autoconf >= 2.60 already defines ${docdir}, but we will not use its # default value, which is ${datarootdir}/doc/${PACKAGE_TARNAME}. # That would give us ${datarootdir}/doc/libupnp, and we want the package # version on that. +# docdir="${datadir}/doc/${PACKAGE_NAME}-${PACKAGE_VERSION}" AC_MSG_CHECKING([for documentation directory]) AC_ARG_WITH( @@ -216,7 +228,9 @@ AS_HELP_STRING( [], [with_documentation=no]) +# # If something has been entered after an equal sign, assume it is the directory +# if test x"$with_documentation" != xyes -a x"$with_documentation" != xno; then docdir="$with_documentation" fi @@ -302,7 +316,6 @@ AC_CHECK_HEADERS( # Checks for typedefs, structures, and compiler characteristics # AC_C_CONST -AC_TYPE_SIZE_T TYPE_SOCKLEN_T @@ -317,9 +330,40 @@ AC_CHECK_FUNCS(ftime,, [AC_CHECK_LIB(compat, ftime)]) # # Checks for POSIX Threads # +echo "--------------------------- pthread stuff -------------------------------------" ACX_PTHREAD( [], [AC_MSG_ERROR([POSIX threads are required to build this program])]) +# +# Update environment variables for pthreads +# +CC="$PTHREAD_CC" +CFLAGS="$PTHREAD_CFLAGS $CFLAGS" +LIBS="$PTHREAD_LIBS $LIBS" +# +# Determine if pthread_rwlock_t is available +# +echo "----------------------- pthread_rwlock_t stuff --------------------------------" +AC_MSG_CHECKING([if pthread_rwlock_t is available]) +AC_LANG([C]) +AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#include ], + [pthread_rwlock_t *x;])], + [AC_DEFINE([UPNP_USE_RWLOCK], [1], [Use pthread_rwlock_t]) + AC_MSG_RESULT([yes, supported without any options])], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [#define _GNU_SOURCE + #include ], + [pthread_rwlock_t *x;])], + [AC_DEFINE([UPNP_USE_RWLOCK], [1], [Use pthread_rwlock_t]) + CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" + AC_MSG_RESULT([yes, definition of _GNU_SOURCE required])], + [AC_DEFINE([UPNP_USE_RWLOCK], [0], [Do not use pthread_rwlock_t]) + AC_MSG_RESULT([no, needs to fallback to pthread_mutex]) + AC_MSG_ERROR([pthread_rwlock_t not available])])]) +echo "-------------------------------------------------------------------------------" AC_CONFIG_FILES([ diff --git a/ixml/src/inc/ixmlmembuf.h b/ixml/src/inc/ixmlmembuf.h index ad81ad0..25b7c9f 100644 --- a/ixml/src/inc/ixmlmembuf.h +++ b/ixml/src/inc/ixmlmembuf.h @@ -38,11 +38,7 @@ #define MINVAL( a, b ) ( (a) < (b) ? (a) : (b) ) #define MAXVAL( a, b ) ( (a) > (b) ? (a) : (b) ) -#ifndef WIN32 - #define UPNP_INLINE inline -#endif - -#define MEMBUF_DEF_SIZE_INC 20 +#define MEMBUF_DEF_SIZE_INC 20 typedef struct // ixml_membuf diff --git a/ixml/src/ixmlparser.c b/ixml/src/ixmlparser.c index b0c5fac..585aef2 100644 --- a/ixml/src/ixmlparser.c +++ b/ixml/src/ixmlparser.c @@ -501,17 +501,22 @@ Parser_init( ) } /*================================================================ -* Parser_isValidEndElement -* check if a new node->nodeName matches top of element stack. -* Internal to parser only. -* -*=================================================================*/ + * Parser_isValidEndElement + * check if a new node->nodeName matches top of element stack. + * Internal to parser only. + *=================================================================*/ static int -Parser_isValidEndElement( IN Parser * xmlParser, - IN IXML_Node * newNode ) +Parser_isValidEndElement( + IN Parser * xmlParser, + IN IXML_Node * newNode ) { - return ( strcmp( xmlParser->pCurElement->element, newNode->nodeName ) - == 0 ); + assert( xmlParser ); + assert( xmlParser->pCurElement ); + assert( xmlParser->pCurElement->element ); + assert( newNode ); + assert( newNode->nodeName ); + + return strcmp( xmlParser->pCurElement->element, newNode->nodeName ) == 0; } /*=============================================================== @@ -921,6 +926,8 @@ Parser_parseDocument( OUT IXML_Document ** retDoc, int rc = IXML_SUCCESS; IXML_CDATASection *cdataSecNode = NULL; + // It is important that the node gets initialized here, otherwise things + // can go wrong on the error handler. ixmlNode_init( &newNode ); rc = ixmlDocument_createDocumentEx( &gRootDoc ); @@ -936,7 +943,9 @@ Parser_parseDocument( OUT IXML_Document ** retDoc, } while( bETag == FALSE ) { - // clear the newNode contents + // clear the newNode contents. Redundant on the first iteration, + // but nonetheless, necessary due to the possible calls to + // ErrorHandler above. Currently, this is just a memset to zero. ixmlNode_init( &newNode ); if( Parser_getNextNode( xmlParser, &newNode, &bETag ) == @@ -1030,7 +1039,7 @@ Parser_parseDocument( OUT IXML_Document ** retDoc, Parser_free( xmlParser ); return rc; - ErrorHandler: +ErrorHandler: Parser_freeNodeContent( &newNode ); ixmlDocument_free( gRootDoc ); Parser_free( xmlParser ); @@ -2497,3 +2506,4 @@ Parser_getNextNode( IN Parser * xmlParser, return IXML_SYNTAX_ERR; } + diff --git a/threadutil/Makefile.am b/threadutil/Makefile.am index 1964fc1..52aa56f 100644 --- a/threadutil/Makefile.am +++ b/threadutil/Makefile.am @@ -2,11 +2,10 @@ # # "Makefile.am" for "libupnp/threadutil" # -# (C) Copyright 2005 Rémi Turboult +# (C) Copyright 2005 R�mi Turboult # AM_CPPFLAGS = -I$(srcdir)/inc -I$(srcdir)/src/inc -AM_CFLAGS = $(PTHREAD_CFLAGS) if ENABLE_DEBUG AM_CPPFLAGS += -DDEBUG -DSTATS @@ -21,12 +20,11 @@ libthreadutil_la_LDFLAGS = -version-info $(LT_VERSION_THREADUTIL) libthreadutil_la_SOURCES = \ src/FreeList.c src/LinkedList.c \ - src/ThreadPool.c src/TimerThread.c \ - src/iasnprintf.c + src/ThreadPool.c src/TimerThread.c upnpincludedir = $(includedir)/upnp upnpinclude_HEADERS = \ inc/FreeList.h inc/LinkedList.h \ inc/ThreadPool.h inc/TimerThread.h \ - inc/iasnprintf.h inc/ithread.h + inc/ithread.h diff --git a/threadutil/inc/ThreadPool.h b/threadutil/inc/ThreadPool.h index 8209966..6b20753 100644 --- a/threadutil/inc/ThreadPool.h +++ b/threadutil/inc/ThreadPool.h @@ -32,6 +32,12 @@ #ifndef THREADPOOL_H #define THREADPOOL_H +#ifdef UPNP_USE_MSVCPP + #define UPNP_INLINE +#else + #define UPNP_INLINE inline +#endif + #ifdef __cplusplus extern "C" { #endif @@ -64,32 +70,23 @@ typedef enum priority {LOW_PRIORITY, #define DEFAULT_FREE_ROUTINE NULL /* default free routine used TPJobInit */ #define DEFAULT_MAX_JOBS_TOTAL 100 /* default max jobs used TPAttrInit */ -#define STATS 1 /* always include stats because code change is minimal */ - - /* Statistics */ -#ifdef WIN32 /* TODO: check why STATSONLY fails during compilation */ - #undef STATS -#endif - -#ifdef STATS - #define STATSONLY(x) x -#else - #define STATSONLY(x) -#endif +/* always include stats because code change is minimal */ +#define STATS 1 #ifdef _DEBUG #define DEBUG 1 #endif #include "LinkedList.h" -#include +#include /* for gettimeofday() */ #include "FreeList.h" #include "ithread.h" #include -#include + #define EXPORT + typedef int PolicyType; #define DEFAULT_POLICY SCHED_OTHER #define DEFAULT_SCHED_PARAM 0 /* default priority */ @@ -111,26 +108,28 @@ typedef void (*free_routine)(void *arg); *****************************************************************************/ typedef struct THREADPOOLATTR { - int minThreads; /* minThreads, ThreadPool will always maintain at least - this many threads */ + /* minThreads, ThreadPool will always maintain at least this many threads */ + int minThreads; - int maxThreads; /* maxThreads, ThreadPool will never have more than this - number of threads */ + /* maxThreads, ThreadPool will never have more than this number of threads */ + int maxThreads; - int maxIdleTime; /* maxIdleTime (in milliseconds) - this is the maximum time a thread will remain idle - before dying */ + /* maxIdleTime (in milliseconds) this is the maximum time a thread will + * remain idle before dying */ + int maxIdleTime; - int jobsPerThread; /* jobs per thread to maintain */ + /* jobs per thread to maintain */ + int jobsPerThread; - int maxJobsTotal; /* maximum number of jobs that can be queued totally. */ + /* maximum number of jobs that can be queued totally. */ + int maxJobsTotal; - int starvationTime; /* the time a low priority or med priority - job waits before getting bumped - up a priority (in milliseconds) */ - - PolicyType schedPolicy; /* scheduling policy to use */ + /* the time a low priority or med priority job waits before getting bumped + * up a priority (in milliseconds) */ + int starvationTime; + /* scheduling policy to use */ + PolicyType schedPolicy; } ThreadPoolAttr; /**************************************************************************** @@ -141,12 +140,12 @@ typedef struct THREADPOOLATTR *****************************************************************************/ typedef struct THREADPOOLJOB { - start_routine func; - void *arg; - free_routine free_func; - struct timeb requestTime; - int priority; - int jobId; + start_routine func; + void *arg; + free_routine free_func; + struct timeval requestTime; + int priority; + int jobId; } ThreadPoolJob; /**************************************************************************** @@ -156,32 +155,28 @@ typedef struct THREADPOOLJOB * Structure to hold statistics *****************************************************************************/ -#ifdef STATS - typedef struct TPOOLSTATS { - double totalTimeHQ; - int totalJobsHQ; - double avgWaitHQ; - double totalTimeMQ; - int totalJobsMQ; - double avgWaitMQ; - double totalTimeLQ; - int totalJobsLQ; - double avgWaitLQ; - double totalWorkTime; - double totalIdleTime; - int workerThreads; - int idleThreads; - int persistentThreads; - int totalThreads; - int maxThreads; - int currentJobsHQ; - int currentJobsLQ; - int currentJobsMQ; -}ThreadPoolStats; - -#endif + double totalTimeHQ; + int totalJobsHQ; + double avgWaitHQ; + double totalTimeMQ; + int totalJobsMQ; + double avgWaitMQ; + double totalTimeLQ; + int totalJobsLQ; + double avgWaitLQ; + double totalWorkTime; + double totalIdleTime; + int workerThreads; + int idleThreads; + int persistentThreads; + int totalThreads; + int maxThreads; + int currentJobsHQ; + int currentJobsLQ; + int currentJobsMQ; +} ThreadPoolStats; /**************************************************************************** @@ -206,27 +201,24 @@ 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 */ - -#ifdef STATS - /* statistics */ - ThreadPoolStats stats; -#endif - + 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 */ + + /* statistics */ + ThreadPoolStats stats; } ThreadPool; @@ -267,8 +259,7 @@ typedef struct THREADPOOL * 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); /**************************************************************************** * Function: ThreadPoolAddPersistent @@ -290,9 +281,7 @@ int ThreadPoolInit(ThreadPool *tp, * 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); /**************************************************************************** * Function: ThreadPoolGetAttr @@ -307,8 +296,7 @@ int ThreadPoolAddPersistent (ThreadPool*tp, * 0 on success, nonzero on failure * Always returns 0. *****************************************************************************/ -int ThreadPoolGetAttr(ThreadPool *tp, - ThreadPoolAttr *out); +int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out); /**************************************************************************** * Function: ThreadPoolSetAttr * @@ -322,8 +310,7 @@ int ThreadPoolGetAttr(ThreadPool *tp, * 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); /**************************************************************************** * Function: ThreadPoolAdd @@ -342,9 +329,7 @@ int ThreadPoolSetAttr(ThreadPool *tp, * 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); /**************************************************************************** * Function: ThreadPoolRemove @@ -361,8 +346,7 @@ int ThreadPoolAdd (ThreadPool*tp, * 0 on success, nonzero on failure. * INVALID_JOB_ID if job not found. *****************************************************************************/ -int ThreadPoolRemove(ThreadPool *tp, - int jobId, ThreadPoolJob *out); +int ThreadPoolRemove(ThreadPool *tp, int jobId, ThreadPoolJob *out); @@ -425,7 +409,6 @@ int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority); *****************************************************************************/ int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func); - /**************************************************************************** * Function: TPAttrInit * diff --git a/threadutil/inc/iasnprintf.h b/threadutil/inc/iasnprintf.h deleted file mode 100644 index 041fea8..0000000 --- a/threadutil/inc/iasnprintf.h +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * - * Copyright (c) 2000-2003 Intel Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither name of Intel Corporation nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ******************************************************************************/ - -#include - -#define EXPORT - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Allocates enough memory for the - * Formatted string, up to max - * specified. - * With max set to -1, allocates - * as much size as needed. - * Memory must be freed using free. - */ - -EXPORT int iasnprintf(char **ret, - int incr, - int max, - const char * fmt, ...) -#ifndef SPARC_SOLARIS - #if (__GNUC__ >= 3) - __attribute__((format (__printf__, 4, 5))); - #else - ; - #endif - EXPORT void iasnprintfFree(char *); -#else -; -#endif - -#ifdef __cplusplus -} -#endif diff --git a/threadutil/src/ThreadPool.c b/threadutil/src/ThreadPool.c index 7776489..6734a58 100644 --- a/threadutil/src/ThreadPool.c +++ b/threadutil/src/ThreadPool.c @@ -36,6 +36,146 @@ #include +/**************************************************************************** + * Function: DiffMillis + * + * Description: + * Returns the difference in milliseconds between two + * timeval structures. + * Internal Only. + * Parameters: + * struct timeval *time1, + * struct timeval *time2, + * Returns: + * the difference in milliseconds, time1-time2. + *****************************************************************************/ +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; + + /* convert microseconds to milliseconds and add to temp */ + /* implicit flooring of unsigned long data type */ + temp += (time1->tv_usec - time2->tv_usec) / 1000; + + return temp; +} + +#ifdef STATS +/**************************************************************************** + * Function: StatsInit + * + * Description: + * Initializes the statistics structure. + * Internal Only. + * Parameters: + * ThreadPoolStats *stats must be valid non null stats structure + *****************************************************************************/ +static void StatsInit( ThreadPoolStats *stats ) +{ + assert( stats != NULL ); + + stats->totalIdleTime = 0; + stats->totalJobsHQ = 0; + stats->totalJobsLQ = 0; + stats->totalJobsMQ = 0; + stats->totalTimeHQ = 0; + stats->totalTimeMQ = 0; + stats->totalTimeLQ = 0; + stats->totalWorkTime = 0; + stats->totalIdleTime = 0; + stats->avgWaitHQ = 0; + stats->avgWaitMQ = 0; + stats->avgWaitLQ = 0; + stats->workerThreads = 0; + stats->idleThreads = 0; + stats->persistentThreads = 0; + stats->maxThreads = 0; stats->totalThreads = 0; +} + +static void StatsAccountLQ( ThreadPool *tp, unsigned long diffTime ) +{ + tp->stats.totalJobsLQ++; + tp->stats.totalTimeLQ += diffTime; +} + +static void StatsAccountMQ( ThreadPool *tp, unsigned long diffTime ) +{ + tp->stats.totalJobsMQ++; + tp->stats.totalTimeMQ += diffTime; +} + +static void StatsAccountHQ( ThreadPool *tp, unsigned long diffTime ) +{ + tp->stats.totalJobsHQ++; + tp->stats.totalTimeHQ += diffTime; +} + +/**************************************************************************** + * Function: CalcWaitTime + * + * Description: + * Calculates the time the job has been waiting at the specified + * priority. Adds to the totalTime and totalJobs kept in the + * thread pool statistics structure. + * Internal Only. + * + * Parameters: + * ThreadPool *tp + * ThreadPriority p + * ThreadPoolJob *job + *****************************************************************************/ +static void CalcWaitTime( ThreadPool *tp, ThreadPriority p, ThreadPoolJob *job ) +{ + struct timeval now; + unsigned long diff; + + assert( tp != NULL ); + assert( job != NULL ); + + gettimeofday( &now, NULL ); + diff = DiffMillis( &now, &job->requestTime ); + switch ( p ) { + case LOW_PRIORITY: + StatsAccountLQ( tp, diff ); + break; + case MED_PRIORITY: + StatsAccountMQ( tp, diff ); + break; + case HIGH_PRIORITY: + StatsAccountHQ( tp, diff ); + break; + default: + assert( 0 ); + } +} + +static time_t StatsTime( time_t *t ) +{ + struct timeval tv; + + gettimeofday( &tv, NULL ); + if (t) { + *t = tv.tv_sec; + } + + return tv.tv_sec; +} +#else /* STATS */ +static UPNP_INLINE void StatsInit( ThreadPoolStats *stats ) {} +static UPNP_INLINE void StatsAccountLQ( ThreadPool *tp, unsigned long diffTime ) {} +static UPNP_INLINE void StatsAccountMQ( ThreadPool *tp, unsigned long diffTime ) {} +static UPNP_INLINE void StatsAccountHQ( ThreadPool *tp, unsigned long diffTime ) {} +static UPNP_INLINE void CalcWaitTime( ThreadPool *tp, ThreadPriority p, ThreadPoolJob *job ) {} +static UPNP_INLINE time_t StatsTime( time_t *t ) { return 0; } +#endif /* STATS */ + /**************************************************************************** * Function: CmpThreadPoolJob * @@ -45,16 +185,15 @@ * void * - job A * void * - job B *****************************************************************************/ -static int -CmpThreadPoolJob( void *jobA, - void *jobB ) +static int CmpThreadPoolJob( void *jobA, void *jobB ) { - ThreadPoolJob *a = ( ThreadPoolJob * ) jobA; - ThreadPoolJob *b = ( ThreadPoolJob * ) jobB; + ThreadPoolJob *a = ( ThreadPoolJob *) jobA; + ThreadPoolJob *b = ( ThreadPoolJob *) jobB; - assert( jobA != NULL ); - assert( jobB != NULL ); - return ( a->jobId == b->jobId ); + assert( jobA != NULL ); + assert( jobB != NULL ); + + return ( a->jobId == b->jobId ); } /**************************************************************************** @@ -65,13 +204,11 @@ CmpThreadPoolJob( void *jobA, * Parameters: * ThreadPoolJob *tpj - must be allocated with CreateThreadPoolJob *****************************************************************************/ -static void -FreeThreadPoolJob( ThreadPool * tp, - ThreadPoolJob * tpj ) +static void FreeThreadPoolJob( ThreadPool *tp, ThreadPoolJob *tpj ) { - assert( tp != NULL ); + assert( tp != NULL ); - FreeListFree( &tp->jobFreeList, tpj ); + FreeListFree( &tp->jobFreeList, tpj ); } /**************************************************************************** @@ -87,25 +224,24 @@ FreeThreadPoolJob( ThreadPool * tp, * Returns result of GetLastError() on failure. * *****************************************************************************/ -static int -SetPolicyType( PolicyType in ) +static int SetPolicyType( PolicyType in ) { #ifdef __CYGWIN__ - /* TODO not currently working... */ - return 0; + /* TODO not currently working... */ + return 0; #elif defined(__OSX__) - setpriority(PRIO_PROCESS, 0, 0); - return 0; + setpriority( PRIO_PROCESS, 0, 0 ); + return 0; #elif defined(WIN32) - return sched_setscheduler( 0, in); + return sched_setscheduler( 0, in ); #elif defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING > 0 - struct sched_param current; + struct sched_param current; - sched_getparam( 0, ¤t ); - current.sched_priority = DEFAULT_SCHED_PARAM; - return sched_setscheduler( 0, in, ¤t ); + sched_getparam( 0, ¤t ); + current.sched_priority = DEFAULT_SCHED_PARAM; + return sched_setscheduler( 0, in, ¤t ); #else - return 0; + return 0; #endif } @@ -123,74 +259,42 @@ SetPolicyType( PolicyType in ) * Returns result of GerLastError on failure. * *****************************************************************************/ -static int -SetPriority( ThreadPriority priority ) +static int SetPriority( ThreadPriority priority ) { #if defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING > 0 - int currentPolicy; - int minPriority = 0; - int maxPriority = 0; - int actPriority = 0; - int midPriority = 0; - struct sched_param newPriority; + int currentPolicy; + int minPriority = 0; + int maxPriority = 0; + int actPriority = 0; + int midPriority = 0; + struct sched_param newPriority; - pthread_getschedparam( ithread_self(), ¤tPolicy, - &newPriority ); - minPriority = sched_get_priority_min( currentPolicy ); - maxPriority = sched_get_priority_max( currentPolicy ); - midPriority = ( maxPriority - minPriority ) / 2; - switch ( priority ) { + pthread_getschedparam( ithread_self(), ¤tPolicy, &newPriority ); + minPriority = sched_get_priority_min( currentPolicy ); + maxPriority = sched_get_priority_max( currentPolicy ); + midPriority = ( maxPriority - minPriority ) / 2; + switch ( priority ) { + case LOW_PRIORITY: + actPriority = minPriority; + break; + case MED_PRIORITY: + actPriority = midPriority; + break; + case HIGH_PRIORITY: + actPriority = maxPriority; + break; + default: + return EINVAL; + }; - case LOW_PRIORITY: - actPriority = minPriority; - break; - case MED_PRIORITY: - actPriority = midPriority; - break; - case HIGH_PRIORITY: - actPriority = maxPriority; - break; - default: - return EINVAL; - }; + newPriority.sched_priority = actPriority; - newPriority.sched_priority = actPriority; - - return pthread_setschedparam( ithread_self(), currentPolicy, - &newPriority ); + return pthread_setschedparam(ithread_self(), currentPolicy, &newPriority ); #else - return 0; + return 0; #endif } -/**************************************************************************** - * Function: DiffMillis - * - * Description: - * Returns the difference in milliseconds between two - * timeb structures. - * Internal Only. - * Parameters: - * struct timeb *time1, - * struct timeb *time2, - * Returns: - * the difference in milliseconds, time1-time2. - *****************************************************************************/ -static double -DiffMillis( struct timeb *time1, - struct timeb *time2 ) -{ - double temp = 0; - - assert( time1 != NULL ); - assert( time2 != NULL ); - - temp = ( ( double )( time1->time ) - time2->time ); - temp = temp * 1000; - temp += ( time1->millitm - time2->millitm ); - return temp; -} - /**************************************************************************** * Function: BumpPriority * @@ -203,56 +307,42 @@ DiffMillis( struct timeb *time1, * Parameters: * ThreadPool *tp *****************************************************************************/ -static void -BumpPriority( ThreadPool * tp ) +static void BumpPriority( ThreadPool *tp ) { int done = 0; - struct timeb now; - double diffTime = 0; + struct timeval now; + unsigned long diffTime = 0; ThreadPoolJob *tempJob = NULL; assert( tp != NULL ); - ftime( &now ); + gettimeofday(&now, NULL); while( !done ) { if( tp->medJobQ.size ) { - tempJob = ( ThreadPoolJob * ) tp->medJobQ.head.next->item; + tempJob = ( ThreadPoolJob *) tp->medJobQ.head.next->item; diffTime = DiffMillis( &now, &tempJob->requestTime ); - if( diffTime >= ( tp->attr.starvationTime ) ) { - //If job has waited longer than the - //starvation time - //bump priority (add to higher priority Q) - - STATSONLY( tp->stats.totalJobsMQ++; ) - STATSONLY( tp->stats.totalTimeMQ += diffTime; ) - + // If job has waited longer than the starvation time + // bump priority (add to higher priority Q) + StatsAccountMQ( tp, diffTime ); ListDelNode( &tp->medJobQ, tp->medJobQ.head.next, 0 ); ListAddTail( &tp->highJobQ, tempJob ); continue; } } - if( tp->lowJobQ.size ) { - tempJob = ( ThreadPoolJob * ) tp->lowJobQ.head.next->item; - + tempJob = ( ThreadPoolJob *) tp->lowJobQ.head.next->item; diffTime = DiffMillis( &now, &tempJob->requestTime ); - if( diffTime >= ( tp->attr.maxIdleTime ) ) { - //If job has waited longer than the - //starvation time - //bump priority (add to higher priority Q) - - STATSONLY( tp->stats.totalJobsLQ++; ) - STATSONLY( tp->stats.totalTimeLQ += diffTime; ) - + // If job has waited longer than the starvation time + // bump priority (add to higher priority Q) + StatsAccountLQ( tp, diffTime ); ListDelNode( &tp->lowJobQ, tp->lowJobQ.head.next, 0 ); ListAddTail( &tp->medJobQ, tempJob ); continue; } } - done = 1; } } @@ -268,87 +358,20 @@ BumpPriority( ThreadPool * tp ) * struct timespec *time * int relMillis - milliseconds in the future *****************************************************************************/ -static void -SetRelTimeout( struct timespec *time, - int relMillis ) +static void SetRelTimeout( struct timespec *time, int relMillis ) { - struct timeb now; - int sec = relMillis / 1000; - int milliSeconds = relMillis % 1000; + struct timeval now; + int sec = relMillis / 1000; + int milliSeconds = relMillis % 1000; - assert( time != NULL ); + assert( time != NULL ); - ftime( &now ); + gettimeofday( &now, NULL ); - time->tv_sec = now.time + sec; - time->tv_nsec = ( now.millitm + milliSeconds ) * 1000000; + time->tv_sec = now.tv_sec + sec; + time->tv_nsec = ( (now.tv_usec/1000) + milliSeconds ) * 1000000; } -/**************************************************************************** - * Function: StatsInit - * - * Description: - * Initializes the statistics structure. - * Internal Only. - * Parameters: - * ThreadPoolStats *stats must be valid non null stats structure - *****************************************************************************/ -#ifdef STATS -static void StatsInit( ThreadPoolStats * stats ) -{ - assert( stats != NULL ); - stats->totalIdleTime = 0; - stats->totalJobsHQ = 0; - stats->totalJobsLQ = 0; - stats->totalJobsMQ = 0; - stats->totalTimeHQ = 0; - stats->totalTimeMQ = 0; - stats->totalTimeLQ = 0; - stats->totalWorkTime = 0; - stats->totalIdleTime = 0; - stats->avgWaitHQ = 0; - stats->avgWaitMQ = 0; - stats->avgWaitLQ = 0; - stats->workerThreads = 0; - stats->idleThreads = 0; - stats->persistentThreads = 0; - stats->maxThreads = 0; stats->totalThreads = 0; -} -#endif - -/**************************************************************************** - * Function: CalcWaitTime - * - * Description: - * Calculates the time the job has been waiting at the specified - * priority. Adds to the totalTime and totalJobs kept in the - * thread pool statistics structure. - * Internal Only. - * - * Parameters: - * ThreadPool *tp - * ThreadPriority p - * ThreadPoolJob *job - *****************************************************************************/ -#ifdef STATS -static void CalcWaitTime( ThreadPool * tp, - ThreadPriority p, - ThreadPoolJob * job ) { - struct timeb now; - double diff; - assert( tp != NULL ); - assert( job != NULL ); - ftime( &now ); - diff = DiffMillis( &now, &job->requestTime ); switch ( p ) { -case HIGH_PRIORITY: -tp->stats.totalJobsHQ++; tp->stats.totalTimeHQ += diff; break; case MED_PRIORITY: -tp->stats.totalJobsMQ++; tp->stats.totalTimeMQ += diff; break; case LOW_PRIORITY: -tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default: - assert( 0 );} - } - -#endif - /**************************************************************************** * Function: SetSeed * @@ -359,16 +382,17 @@ tp->stats.totalJobsLQ++; tp->stats.totalTimeLQ += diff; break; default: * Parameters: * *****************************************************************************/ -static void SetSeed() { - struct timeb t; - - ftime( &t ); +static void SetSeed() +{ + struct timeval t; + + gettimeofday(&t, NULL); #if defined(WIN32) - srand( ( unsigned int )t.millitm + (unsigned int)ithread_get_current_thread_id().p ); -#elif defined(__FreeBSD__) || defined(__OSX__) - srand( ( unsigned int )t.millitm + (unsigned int)ithread_get_current_thread_id() ); + srand( ( unsigned int )t.tv_usec + (unsigned int)ithread_get_current_thread_id().p ); +#elif defined(__FreeBSD__) + srand( ( unsigned int )t.tv_usec + (unsigned int)ithread_get_current_thread_id() ); #elif defined(__linux__) - srand( ( unsigned int )t.millitm + 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; @@ -393,192 +417,165 @@ static void SetSeed() { * Parameters: * void * arg -> is cast to ThreadPool * *****************************************************************************/ - static void *WorkerThread( void *arg ) { +static void *WorkerThread( void *arg ) +{ + time_t start = 0; - STATSONLY( time_t start = 0; ) + ThreadPoolJob *job = NULL; + ListNode *head = NULL; - ThreadPoolJob *job = NULL; - ListNode *head = NULL; + 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 ); - struct timespec timeout; - int retCode = 0; - int persistent = -1; - ThreadPool *tp = ( ThreadPool * ) arg; - //leuk_he allow static linking - #ifdef WIN32 - #ifdef PTW32_STATIC_LIB - pthread_win32_thread_attach_np(); - #endif - #endif + // Increment total thread count + ithread_mutex_lock( &tp->mutex ); + tp->totalThreads++; + ithread_cond_broadcast( &tp->start_and_shutdown ); + ithread_mutex_unlock( &tp->mutex ); - assert( tp != NULL ); + SetSeed(); + StatsTime( &start ); + while( 1 ) { + ithread_mutex_lock( &tp->mutex ); + if( job ) { + FreeThreadPoolJob( tp, job ); + job = NULL; + } + retCode = 0; - //Increment total thread count - ithread_mutex_lock( &tp->mutex ); - tp->totalThreads++; - ithread_cond_broadcast( &tp->start_and_shutdown ); - ithread_mutex_unlock( &tp->mutex ); + tp->stats.idleThreads++; + tp->stats.totalWorkTime += ( StatsTime( NULL ) - start ); // work time + StatsTime( &start ); // idle time - SetSeed(); + if( persistent == 1 ) { + // Persistent thread + // becomes a regular thread + tp->persistentThreads--; + } - STATSONLY( time( &start ); ) + if( persistent == 0 ) { + tp->stats.workerThreads--; + } - while( 1 ) { + // 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->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; + } + SetRelTimeout( &timeout, tp->attr.maxIdleTime ); - ithread_mutex_lock( &tp->mutex ); + // wait for a job up to the specified max time + retCode = ithread_cond_timedwait( + &tp->condition, &tp->mutex, &timeout ); + } - if( job ) { + tp->stats.idleThreads--; + tp->stats.totalIdleTime += ( StatsTime( NULL ) - start ); // idle time + StatsTime( &start ); // work time - FreeThreadPoolJob( tp, job ); - job = NULL; + // 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; + } else { + // 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 ); + } 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 ); + } else { + // Should never get here + assert( 0 ); + tp->stats.workerThreads--; + tp->totalThreads--; + ithread_cond_broadcast( &tp->start_and_shutdown ); + ithread_mutex_unlock( &tp->mutex ); - retCode = 0; + return NULL; + } + } + } - STATSONLY( tp->stats.idleThreads++; ) - STATSONLY( tp->stats.totalWorkTime += ( time( NULL ) - start ); ) //work time - STATSONLY( time( &start ); ) // idle time + ithread_mutex_unlock( &tp->mutex ); - if( persistent == 1 ) { - //Persistent thread - //becomes a regular thread - tp->persistentThreads--; - } + if( SetPriority( job->priority ) != 0 ) { + // In the future can log + // info + } else { + // In the future can log + // info + } - STATSONLY( if( persistent == 0 ) tp->stats.workerThreads--; ) + // run the job + job->func( job->arg ); - //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 ) ) ) { - - STATSONLY( tp->stats.idleThreads--; ) - - tp->totalThreads--; - ithread_cond_broadcast( &tp->start_and_shutdown ); - ithread_mutex_unlock( &tp->mutex ); - //leuk_he - #ifdef WIN32 - #ifdef PTW32_STATIC_LIB - pthread_win32_thread_detach_np (); - #endif - #endif - return NULL; - } - - SetRelTimeout( &timeout, tp->attr.maxIdleTime ); - - //wait for a job up to the specified max time - retCode = ithread_cond_timedwait( &tp->condition, - &tp->mutex, &timeout ); - - } - - STATSONLY( tp->stats.idleThreads--; ) - STATSONLY( tp->stats.totalIdleTime += ( time( NULL ) - start ); ) // idle time - STATSONLY( time( &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 ); - //leuk_he - #ifdef WIN32 - #ifdef PTW32_STATIC_LIB - pthread_win32_thread_detach_np (); - #endif - #endif - - return NULL; - } else { - - //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 ); - - } else { - STATSONLY( tp->stats.workerThreads++; ) - persistent = 0; - - //Pick the highest priority job - if( tp->highJobQ.size > 0 ) { - head = ListHead( &tp->highJobQ ); - job = ( ThreadPoolJob * ) head->item; - STATSONLY( CalcWaitTime( tp, HIGH_PRIORITY, job ); ) - ListDelNode( &tp->highJobQ, head, 0 ); - - } else if( tp->medJobQ.size > 0 ) { - head = ListHead( &tp->medJobQ ); - job = ( ThreadPoolJob * ) head->item; - STATSONLY( CalcWaitTime( tp, MED_PRIORITY, job ); ) - ListDelNode( &tp->medJobQ, head, 0 ); - - } else if( tp->lowJobQ.size > 0 ) { - head = ListHead( &tp->lowJobQ ); - job = ( ThreadPoolJob * ) head->item; - STATSONLY( CalcWaitTime( tp, LOW_PRIORITY, job ); ) - ListDelNode( &tp->lowJobQ, head, 0 ); - - } else { - - // Should never get here - assert( 0 ); - STATSONLY( tp->stats.workerThreads--; ) - tp->totalThreads--; - ithread_cond_broadcast( &tp->start_and_shutdown ); - ithread_mutex_unlock( &tp->mutex ); - - return NULL; - } - - } - } - - ithread_mutex_unlock( &tp->mutex ); - - if( SetPriority( job->priority ) != 0 ) { - // In the future can log - // info - } else { - // In the future can log - // info - } - - //run the job - - job->func( job->arg ); - - //return to Normal - SetPriority( DEFAULT_PRIORITY ); - - } - } + // return to Normal + SetPriority( DEFAULT_PRIORITY ); + } +} /**************************************************************************** * Function: CreateThreadPoolJob @@ -587,30 +584,28 @@ static void SetSeed() { * Creates a Thread Pool Job. (Dynamically allocated) * Internal to thread pool. * Parameters: - * ThreadPoolJob * job - job is copied + * ThreadPoolJob *job - job is copied * id - id of job * * Returns: - * ThreadPoolJob * on success, NULL on failure. + * 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; - ThreadPoolJob *newJob = NULL; + assert( job != NULL ); + assert( tp != NULL ); - assert( job != NULL ); - assert( tp != NULL ); + newJob = (ThreadPoolJob *)FreeListAlloc( &tp->jobFreeList ); + if( newJob ) { + *newJob = *job; + newJob->jobId = id; + gettimeofday( &newJob->requestTime, NULL ); + } - newJob = ( ThreadPoolJob * ) FreeListAlloc( &tp->jobFreeList ); - - if( newJob ) { - ( *newJob ) = ( *job ); - newJob->jobId = id; - ftime( &newJob->requestTime ); - } - return newJob; - } + return newJob; +} /**************************************************************************** * Function: CreateWorker @@ -628,40 +623,33 @@ static void SetSeed() { * EAGAIN if system can not create thread * *****************************************************************************/ - static int CreateWorker( ThreadPool * tp ) { - ithread_t temp; - int rc = 0; - int currentThreads = tp->totalThreads + 1; +static int CreateWorker( ThreadPool *tp ) +{ + ithread_t temp; + int rc = 0; + int currentThreads = tp->totalThreads + 1; - assert( tp != NULL ); + assert( tp != NULL ); - if( ( tp->attr.maxThreads != INFINITE_THREADS ) - && ( currentThreads > tp->attr.maxThreads ) ) { - return EMAXTHREADS; - } + if ( tp->attr.maxThreads != INFINITE_THREADS && + currentThreads > tp->attr.maxThreads ) { + return EMAXTHREADS; + } - rc = ithread_create( &temp, NULL, WorkerThread, tp ); + 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( rc == 0 ) { + if( tp->stats.maxThreads < tp->totalThreads ) { + tp->stats.maxThreads = tp->totalThreads; + } - rc = ithread_detach( temp ); - - while( tp->totalThreads < currentThreads ) { - - ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex ); - - } - - } - -#ifdef STATS - if( tp->stats.maxThreads < tp->totalThreads ) { - tp->stats.maxThreads = tp->totalThreads; - } -#endif - - return rc; - } + return rc; +} /**************************************************************************** * Function: AddWorker @@ -675,25 +663,22 @@ static void SetSeed() { * ThreadPool* tp * *****************************************************************************/ - static void AddWorker( ThreadPool * tp ) { - int jobs = 0; - int threads = 0; +static void AddWorker( ThreadPool *tp ) +{ + int jobs = 0; + int threads = 0; - assert( tp != NULL ); + 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 ) ) { - - if( CreateWorker( tp ) != 0 ) - return; - threads++; - } - - } + 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 ) { + return; + } + threads++; + } +} /**************************************************************************** * Function: ThreadPoolInit @@ -727,96 +712,90 @@ static void SetSeed() { * INVALID_POLICY if schedPolicy can't be set * EMAXTHREADS if minimum threads is greater than maximum threads *****************************************************************************/ - int ThreadPoolInit( ThreadPool * tp, - ThreadPoolAttr * attr ) { - int retCode = 0; - int i = 0; +int ThreadPoolInit( ThreadPool *tp, ThreadPoolAttr *attr ) +{ + int retCode = 0; + int i = 0; - assert( tp != NULL ); + assert( tp != NULL ); + if( tp == NULL ) { + return EINVAL; + } +#ifdef WIN32 +#ifdef PTW32_STATIC_LIB + pthread_win32_process_attach_np(); +#endif +#endif - if( tp == NULL ) { - return EINVAL; - } - //leuk_he - #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 ); - assert( retCode == 0 ); + retCode += ithread_mutex_lock( &tp->mutex ); + assert( retCode == 0 ); - retCode += ithread_mutex_lock( &tp->mutex ); - assert( retCode == 0 ); + retCode += ithread_cond_init( &tp->condition, NULL ); + 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 ); - retCode += ithread_cond_init( &tp->start_and_shutdown, NULL ); - assert( retCode == 0 ); + if( retCode != 0 ) { + return EAGAIN; + } - if( retCode != 0 ) { - return EAGAIN; - } + if( attr ) { + tp->attr = ( *attr ); + } else { + TPAttrInit( &tp->attr ); + } - if( attr ) { - tp->attr = ( *attr ); - } else { - 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 ); + return INVALID_POLICY; + } - 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 ); - retCode += FreeListInit( &tp->jobFreeList, sizeof( ThreadPoolJob ), - JOBFREELISTSIZE ); - assert( retCode == 0 ); + StatsInit( &tp->stats ); - STATSONLY( StatsInit( &tp->stats ); ) + retCode += ListInit( &tp->highJobQ, CmpThreadPoolJob, NULL ); + assert( retCode == 0 ); - retCode += ListInit( &tp->highJobQ, CmpThreadPoolJob, NULL ); - assert( retCode == 0 ); + retCode += ListInit( &tp->medJobQ, CmpThreadPoolJob, NULL ); + assert( retCode == 0 ); - retCode += ListInit( &tp->medJobQ, CmpThreadPoolJob, NULL ); - assert( retCode == 0 ); + retCode += ListInit( &tp->lowJobQ, CmpThreadPoolJob, NULL ); + assert( retCode == 0 ); - retCode += ListInit( &tp->lowJobQ, CmpThreadPoolJob, NULL ); - assert( retCode == 0 ); + if( retCode != 0 ) { + retCode = EAGAIN; + } else { + tp->persistentJob = NULL; + tp->lastJobId = 0; + tp->shutdown = 0; + tp->totalThreads = 0; + tp->persistentThreads = 0; + for( i = 0; i < tp->attr.minThreads; ++i ) { + if( ( retCode = CreateWorker( tp ) ) != 0 ) { + break; + } + } + } - if( retCode != 0 ) { - retCode = EAGAIN; - } else { + ithread_mutex_unlock( &tp->mutex ); - tp->persistentJob = NULL; - tp->lastJobId = 0; - tp->shutdown = 0; - tp->totalThreads = 0; - tp->persistentThreads = 0; + if( retCode != 0 ) { + // clean up if the min threads could not be created + ThreadPoolShutdown( tp ); + } - for( i = 0; i < tp->attr.minThreads; i++ ) { - - if( ( retCode = CreateWorker( tp ) ) != 0 ) { - break; - } - } - } - - ithread_mutex_unlock( &tp->mutex ); - - if( retCode != 0 ) { - //clean up if the min threads could - //not be created - ThreadPoolShutdown( tp ); - } - - return retCode; - } + return retCode; +} /**************************************************************************** * Function: ThreadPoolAddPersistent @@ -837,65 +816,62 @@ static void SetSeed() { * EOUTOFMEM not enough memory to add job. * EMAXTHREADS not enough threads to add persistent job. *****************************************************************************/ - int ThreadPoolAddPersistent( ThreadPool * tp, - ThreadPoolJob * job, - int *jobId ) { - int tempId = -1; +int ThreadPoolAddPersistent( ThreadPool *tp, ThreadPoolJob *job, int *jobId ) +{ + int tempId = -1; + ThreadPoolJob *temp = NULL; - ThreadPoolJob *temp = NULL; + assert( tp != NULL ); + assert( job != NULL ); + if( ( tp == NULL ) || ( job == NULL ) ) { + return EINVAL; + } - assert( tp != NULL ); - assert( job != NULL ); + if( jobId == NULL ) { + jobId = &tempId; + } - if( ( tp == NULL ) || ( job == NULL ) ) { - return EINVAL; - } + *jobId = INVALID_JOB_ID; - if( jobId == NULL ) - jobId = &tempId; + ithread_mutex_lock( &tp->mutex ); - ( *jobId ) = INVALID_JOB_ID; + assert( job->priority == LOW_PRIORITY || + job->priority == MED_PRIORITY || + job->priority == HIGH_PRIORITY ); - ithread_mutex_lock( &tp->mutex ); + // 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; + } + } - assert( ( job->priority == LOW_PRIORITY ) - || ( job->priority == MED_PRIORITY ) - || ( job->priority == HIGH_PRIORITY ) ); + temp = CreateThreadPoolJob( job, tp->lastJobId, tp ); + if( temp == NULL ) { + ithread_mutex_unlock( &tp->mutex ); + return EOUTOFMEM; + } - //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; - } - } + tp->persistentJob = temp; - temp = CreateThreadPoolJob( job, tp->lastJobId, tp ); + // Notify a waiting thread + ithread_cond_signal( &tp->condition ); - if( temp == NULL ) { - ithread_mutex_unlock( &tp->mutex ); - return EOUTOFMEM; - } + // wait until long job has been picked up + while( tp->persistentJob != NULL ) { + ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex ); + } - tp->persistentJob = temp; + *jobId = tp->lastJobId++; + ithread_mutex_unlock( &tp->mutex ); - //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 ); - } - - ( *jobId ) = tp->lastJobId++; - ithread_mutex_unlock( &tp->mutex ); - return 0; - } + return 0; +} /**************************************************************************** * Function: ThreadPoolAdd @@ -915,75 +891,75 @@ static void SetSeed() { * 0 on success, nonzero on failure * EOUTOFMEM if not enough memory to add job. *****************************************************************************/ - int ThreadPoolAdd( ThreadPool * tp, - ThreadPoolJob * job, - int *jobId ) { - int rc = EOUTOFMEM; +int ThreadPoolAdd( ThreadPool *tp, ThreadPoolJob *job, int *jobId ) +{ + int rc = EOUTOFMEM; - int tempId = -1; - int totalJobs; + int tempId = -1; + int totalJobs; - ThreadPoolJob *temp = NULL; + ThreadPoolJob *temp = NULL; - assert( tp != NULL ); - assert( job != NULL ); + assert( tp != NULL ); + assert( job != NULL ); + if( ( tp == NULL ) || ( job == NULL ) ) { + return EINVAL; + } - if( ( tp == NULL ) || ( job == NULL ) ) { - return EINVAL; - } + ithread_mutex_lock( &tp->mutex ); - ithread_mutex_lock( &tp->mutex ); + assert( job->priority == LOW_PRIORITY || + job->priority == MED_PRIORITY || + job->priority == HIGH_PRIORITY ); - assert( ( job->priority == LOW_PRIORITY ) - || ( job->priority == MED_PRIORITY ) - || ( job->priority == HIGH_PRIORITY ) ); + 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; + } - 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; - } + if( jobId == NULL ) { + jobId = &tempId; + } + *jobId = INVALID_JOB_ID; - if( jobId == NULL ) - jobId = &tempId; + temp = CreateThreadPoolJob( job, tp->lastJobId, tp ); + if( temp == NULL ) { + ithread_mutex_unlock( &tp->mutex ); + return rc; + } - ( *jobId ) = INVALID_JOB_ID; + if( job->priority == HIGH_PRIORITY ) { + if( ListAddTail( &tp->highJobQ, temp ) ) { + rc = 0; + } + } else if( job->priority == MED_PRIORITY ) { + if( ListAddTail( &tp->medJobQ, temp ) ) { + rc = 0; + } + } else { + if( ListAddTail( &tp->lowJobQ, temp ) ) { + rc = 0; + } + } - temp = CreateThreadPoolJob( job, tp->lastJobId, tp ); + // AddWorker if appropriate + AddWorker( tp ); - if( temp == NULL ) { - ithread_mutex_unlock( &tp->mutex ); - return rc; - } + // Notify a waiting thread + if( rc == 0 ) { + ithread_cond_signal( &tp->condition ); + } else { + FreeThreadPoolJob( tp, temp ); + } - if( job->priority == HIGH_PRIORITY ) { - if( ListAddTail( &tp->highJobQ, temp ) ) - rc = 0; - } else if( job->priority == MED_PRIORITY ) { - if( ListAddTail( &tp->medJobQ, temp ) ) - rc = 0; - } else { - if( ListAddTail( &tp->lowJobQ, temp ) ) - rc = 0; - } + *jobId = tp->lastJobId++; - //AddWorker if appropriate - AddWorker( tp ); + ithread_mutex_unlock( &tp->mutex ); - //Notify a waiting thread - if( rc == 0 ) { - ithread_cond_signal( &tp->condition ); - - } else { - FreeThreadPoolJob( tp, temp ); - } - - ( *jobId ) = tp->lastJobId++; - - ithread_mutex_unlock( &tp->mutex ); - return rc; - } + return rc; +} /**************************************************************************** * Function: ThreadPoolRemove @@ -1001,73 +977,72 @@ static void SetSeed() { * Returns: * 0 on success. INVALID_JOB_ID on failure. *****************************************************************************/ - int ThreadPoolRemove( ThreadPool * tp, - int jobId, - ThreadPoolJob * out ) { - ThreadPoolJob *temp = NULL; - int ret = INVALID_JOB_ID; - ListNode *tempNode = NULL; - ThreadPoolJob dummy; +int ThreadPoolRemove( ThreadPool *tp, int jobId, ThreadPoolJob *out ) +{ + ThreadPoolJob *temp = NULL; + int ret = INVALID_JOB_ID; + ListNode *tempNode = NULL; + ThreadPoolJob dummy; - assert( tp != NULL ); + assert( tp != NULL ); + if( tp == NULL ) { + return EINVAL; + } - if( tp == NULL ) { - return EINVAL; - } + if( out == NULL ) { + out = &dummy; + } - if( out == NULL ) { - out = &dummy; - } + dummy.jobId = jobId; - dummy.jobId = jobId; + ithread_mutex_lock( &tp->mutex ); - ithread_mutex_lock( &tp->mutex ); + 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 ); - tempNode = ListFind( &tp->highJobQ, NULL, &dummy ); + return 0; + } - if( tempNode ) { - temp = ( ThreadPoolJob * ) tempNode->item; - ( *out ) = ( *temp ); - ListDelNode( &tp->highJobQ, tempNode, 0 ); - FreeThreadPoolJob( tp, temp ); - ithread_mutex_unlock( &tp->mutex ); - return 0; - } + 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 ); - tempNode = ListFind( &tp->medJobQ, NULL, &dummy ); + return 0; + } - if( tempNode ) { - temp = ( ThreadPoolJob * ) tempNode->item; - ( *out ) = ( *temp ); - ListDelNode( &tp->medJobQ, tempNode, 0 ); - FreeThreadPoolJob( tp, temp ); - ithread_mutex_unlock( &tp->mutex ); - return 0; - } + 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 ); - tempNode = ListFind( &tp->lowJobQ, NULL, &dummy ); + return 0; + } - if( tempNode ) { - temp = ( ThreadPoolJob * ) tempNode->item; - ( *out ) = ( *temp ); - ListDelNode( &tp->lowJobQ, tempNode, 0 ); - FreeThreadPoolJob( tp, temp ); - ithread_mutex_unlock( &tp->mutex ); - return 0; - } + if( tp->persistentJob && tp->persistentJob->jobId == jobId ) { + *out = *tp->persistentJob; + FreeThreadPoolJob( tp, tp->persistentJob ); + tp->persistentJob = NULL; + ithread_mutex_unlock( &tp->mutex ); - if( ( tp->persistentJob ) - && ( tp->persistentJob->jobId == jobId ) ) { - ( *out ) = ( *tp->persistentJob ); - FreeThreadPoolJob( tp, tp->persistentJob ); - tp->persistentJob = NULL; - ithread_mutex_unlock( &tp->mutex ); - return 0; - } + return 0; + } - ithread_mutex_unlock( &tp->mutex ); - return ret; - } + ithread_mutex_unlock( &tp->mutex ); + + return ret; +} /**************************************************************************** * Function: ThreadPoolGetAttr @@ -1082,28 +1057,26 @@ static void SetSeed() { * 0 on success, nonzero on failure * Always returns 0. *****************************************************************************/ - int ThreadPoolGetAttr( ThreadPool * tp, - ThreadPoolAttr * out ) { - assert( tp != NULL ); +int ThreadPoolGetAttr( ThreadPool *tp, ThreadPoolAttr *out ) +{ + assert( tp != NULL ); + assert( out != NULL ); + if( tp == NULL || out == NULL ) { + return EINVAL; + } - assert( out != NULL ); + if( !tp->shutdown ) { + ithread_mutex_lock( &tp->mutex ); + } - if( ( tp == NULL ) || ( out == NULL ) ) { - return EINVAL; - } + *out = tp->attr; - if( !tp->shutdown ) { - ithread_mutex_lock( &tp->mutex ); - } + if( !tp->shutdown ) { + ithread_mutex_unlock( &tp->mutex ); + } - ( *out ) = tp->attr; - - if( !tp->shutdown ) { - ithread_mutex_unlock( &tp->mutex ); - } - - return 0; - } + return 0; +} /**************************************************************************** * Function: ThreadPoolSetAttr @@ -1118,54 +1091,53 @@ static void SetSeed() { * 0 on success, nonzero on failure * Returns INVALID_POLICY if policy can not be set. *****************************************************************************/ - int ThreadPoolSetAttr( ThreadPool * tp, - ThreadPoolAttr * attr ) { - int retCode = 0; - ThreadPoolAttr temp; - int i = 0; +int ThreadPoolSetAttr( ThreadPool *tp, ThreadPoolAttr *attr ) +{ + int retCode = 0; + ThreadPoolAttr temp; + int i = 0; - assert( tp != NULL ); + assert( tp != NULL ); + if( tp == NULL ) { + return EINVAL; + } + ithread_mutex_lock( &tp->mutex ); - if( tp == NULL ) { - return EINVAL; - } - ithread_mutex_lock( &tp->mutex ); + if( attr != NULL ) { + temp = ( *attr ); + } else { + TPAttrInit( &temp ); + } - if( attr != NULL ) { - temp = ( *attr ); - } else { - 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; - } + return INVALID_POLICY; + } - tp->attr = ( temp ); + tp->attr = ( temp ); - if( tp->totalThreads < tp->attr.minThreads ) //add threads - { - for( i = tp->totalThreads; i < tp->attr.minThreads; i++ ) { + // add threads + if( tp->totalThreads < tp->attr.minThreads ) + { + for( i = tp->totalThreads; i < tp->attr.minThreads; i++ ) { + if( ( retCode = CreateWorker( tp ) ) != 0 ) { + break; + } + } + } - if( ( retCode = CreateWorker( tp ) ) != 0 ) { - break; - } - } - } + // signal changes + ithread_cond_signal( &tp->condition ); + ithread_mutex_unlock( &tp->mutex ); - ithread_cond_signal( &tp->condition ); //signal changes + if( retCode != 0 ) { + // clean up if the min threads could not be created + ThreadPoolShutdown( tp ); + } - ithread_mutex_unlock( &tp->mutex ); - - if( retCode != 0 ) { - //clean up if the min threads could - //not be created - ThreadPoolShutdown( tp ); - } - - return retCode; - } + return retCode; +} /**************************************************************************** * Function: ThreadPoolShutdown @@ -1181,90 +1153,89 @@ static void SetSeed() { * 0 on success, nonzero on failure * Always returns 0. *****************************************************************************/ - int ThreadPoolShutdown( ThreadPool * tp ) { +int ThreadPoolShutdown( ThreadPool *tp ) +{ + ListNode *head = NULL; + ThreadPoolJob *temp = NULL; - ListNode *head = NULL; - ThreadPoolJob *temp = NULL; + assert( tp != NULL ); + if( tp == NULL ) { + return EINVAL; + } - assert( tp != NULL ); + ithread_mutex_lock( &tp->mutex ); - if( tp == NULL ) { - return EINVAL; - } + // 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 ); + } + ListDestroy( &tp->highJobQ, 0 ); - ithread_mutex_lock( &tp->mutex ); + // 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 ); + } + ListDestroy( &tp->medJobQ, 0 ); - //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 ); - } + // 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 ); + } + ListDestroy( &tp->lowJobQ, 0 ); - ListDestroy( &tp->highJobQ, 0 ); + // clean up long term job + if( tp->persistentJob ) { + temp = tp->persistentJob; + if( temp->free_func ) { + temp->free_func( temp->arg ); + } + FreeThreadPoolJob( tp, temp ); + tp->persistentJob = NULL; + } - //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 ); - } + // signal shutdown + tp->shutdown = 1; + ithread_cond_broadcast( &tp->condition ); - ListDestroy( &tp->medJobQ, 0 ); + // wait for all threads to finish + while( tp->totalThreads > 0 ) { + ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex ); + } - //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 ); - } + // destroy condition + while( ithread_cond_destroy( &tp->condition ) != 0 ) { + } + while( ithread_cond_destroy( &tp->start_and_shutdown ) != 0 ) { + } - ListDestroy( &tp->lowJobQ, 0 ); + FreeListDestroy( &tp->jobFreeList ); - //clean up long term job - if( tp->persistentJob ) { - temp = tp->persistentJob; - if( temp->free_func ) - temp->free_func( temp->arg ); - FreeThreadPoolJob( tp, temp ); - tp->persistentJob = NULL; - } + ithread_mutex_unlock( &tp->mutex ); - tp->shutdown = 1; - ithread_cond_broadcast( &tp->condition ); //signal shutdown + // destroy mutex + while( ithread_mutex_destroy( &tp->mutex ) != 0 ) { + } - //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 ) { - } - - while( ithread_cond_destroy( &tp->start_and_shutdown ) != 0 ) { - } - - FreeListDestroy( &tp->jobFreeList ); - - ithread_mutex_unlock( &tp->mutex ); - - //destroy mutex - while( ithread_mutex_destroy( &tp->mutex ) != 0 ) { - } - - return 0; - } + return 0; +} /**************************************************************************** * Function: TPAttrInit @@ -1277,22 +1248,23 @@ static void SetSeed() { * Returns: * Always returns 0. *****************************************************************************/ - int TPAttrInit( ThreadPoolAttr * attr ) { - assert( attr != NULL ); +int TPAttrInit( ThreadPoolAttr *attr ) +{ + assert( attr != NULL ); + if( attr == NULL ) { + return EINVAL; + } - if( attr == NULL ) { - return EINVAL; - } + attr->jobsPerThread = DEFAULT_JOBS_PER_THREAD; + attr->maxIdleTime = DEFAULT_IDLE_TIME; + attr->maxThreads = DEFAULT_MAX_THREADS; + attr->minThreads = DEFAULT_MIN_THREADS; + attr->schedPolicy = DEFAULT_POLICY; + attr->starvationTime = DEFAULT_STARVATION_TIME; + attr->maxJobsTotal = DEFAULT_MAX_JOBS_TOTAL; - attr->jobsPerThread = DEFAULT_JOBS_PER_THREAD; - attr->maxIdleTime = DEFAULT_IDLE_TIME; - attr->maxThreads = DEFAULT_MAX_THREADS; - attr->minThreads = DEFAULT_MIN_THREADS; - attr->schedPolicy = DEFAULT_POLICY; - attr->starvationTime = DEFAULT_STARVATION_TIME; - attr->maxJobsTotal = DEFAULT_MAX_JOBS_TOTAL; - return 0; - } + return 0; +} /**************************************************************************** * Function: TPJobInit @@ -1308,22 +1280,21 @@ static void SetSeed() { * Returns: * Always returns 0. *****************************************************************************/ - int TPJobInit( ThreadPoolJob * job, - start_routine func, - void *arg ) { - assert( job != NULL ); - assert( func != NULL ); +int TPJobInit( ThreadPoolJob *job, start_routine func, void *arg ) +{ + assert( job != NULL ); + assert( func != NULL ); + if( job == NULL || func == NULL ) { + return EINVAL; + } - if( ( job == NULL ) || ( func == NULL ) ) { - return EINVAL; - } + job->func = func; + job->arg = arg; + job->priority = DEFAULT_PRIORITY; + job->free_func = DEFAULT_FREE_ROUTINE; - job->func = func; - job->arg = arg; - job->priority = DEFAULT_PRIORITY; - job->free_func = DEFAULT_FREE_ROUTINE; - return 0; - } + return 0; +} /**************************************************************************** * Function: TPJobSetPriority @@ -1337,22 +1308,22 @@ static void SetSeed() { * Returns 0 on success nonzero on failure. * Returns EINVAL if invalid priority. *****************************************************************************/ - int TPJobSetPriority( ThreadPoolJob * job, - ThreadPriority priority ) { - assert( job != NULL ); +int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority ) +{ + assert( job != NULL ); + if( job == NULL ) { + return EINVAL; + } - if( job == NULL ) { - return EINVAL; - } - - if( priority == LOW_PRIORITY || priority == MED_PRIORITY || - priority == HIGH_PRIORITY ) { - job->priority = priority; - return 0; - } else { - return EINVAL; - } - } + if( priority == LOW_PRIORITY || + priority == MED_PRIORITY || + priority == HIGH_PRIORITY ) { + job->priority = priority; + return 0; + } else { + return EINVAL; + } +} /**************************************************************************** * Function: TPJobSetFreeFunction @@ -1365,17 +1336,17 @@ static void SetSeed() { * Returns: * Always returns 0. *****************************************************************************/ - int TPJobSetFreeFunction( ThreadPoolJob * job, - free_routine func ) { - assert( job != NULL ); +int TPJobSetFreeFunction( ThreadPoolJob *job, free_routine func ) +{ + assert( job != NULL ); + if( job == NULL ) { + return EINVAL; + } - if( job == NULL ) { - return EINVAL; - } + job->free_func = func; - job->free_func = func; - return 0; - } + return 0; +} /**************************************************************************** * Function: TPAttrSetMaxThreads @@ -1388,17 +1359,17 @@ static void SetSeed() { * Returns: * Always returns 0. *****************************************************************************/ - int TPAttrSetMaxThreads( ThreadPoolAttr * attr, - int maxThreads ) { - assert( attr != NULL ); +int TPAttrSetMaxThreads( ThreadPoolAttr *attr, int maxThreads ) +{ + assert( attr != NULL ); + if( attr == NULL ) { + return EINVAL; + } - if( attr == NULL ) { - return EINVAL; - } + attr->maxThreads = maxThreads; - attr->maxThreads = maxThreads; - return 0; - } + return 0; +} /**************************************************************************** * Function: TPAttrSetMinThreads @@ -1411,17 +1382,17 @@ static void SetSeed() { * Returns: * Always returns 0. *****************************************************************************/ - int TPAttrSetMinThreads( ThreadPoolAttr * attr, - int minThreads ) { - assert( attr != NULL ); +int TPAttrSetMinThreads( ThreadPoolAttr *attr, int minThreads ) +{ + assert( attr != NULL ); + if( attr == NULL ) { + return EINVAL; + } - if( attr == NULL ) { - return EINVAL; - } + attr->minThreads = minThreads; - attr->minThreads = minThreads; - return 0; - } + return 0; +} /**************************************************************************** * Function: TPAttrSetIdleTime @@ -1433,17 +1404,17 @@ static void SetSeed() { * Returns: * Always returns 0. *****************************************************************************/ - int TPAttrSetIdleTime( ThreadPoolAttr * attr, - int idleTime ) { - assert( attr != NULL ); +int TPAttrSetIdleTime( ThreadPoolAttr *attr, int idleTime ) +{ + assert( attr != NULL ); + if( attr == NULL ) { + return EINVAL; + } - if( attr == NULL ) { - return EINVAL; - } + attr->maxIdleTime = idleTime; - attr->maxIdleTime = idleTime; - return 0; - } + return 0; +} /**************************************************************************** * Function: TPAttrSetJobsPerThread @@ -1455,17 +1426,17 @@ static void SetSeed() { * Returns: * Always returns 0. *****************************************************************************/ - int TPAttrSetJobsPerThread( ThreadPoolAttr * attr, - int jobsPerThread ) { - assert( attr != NULL ); +int TPAttrSetJobsPerThread( ThreadPoolAttr *attr, int jobsPerThread ) +{ + assert( attr != NULL ); + if( attr == NULL ) { + return EINVAL; + } - if( attr == NULL ) { - return EINVAL; - } + attr->jobsPerThread = jobsPerThread; - attr->jobsPerThread = jobsPerThread; - return 0; - } + return 0; +} /**************************************************************************** * Function: TPAttrSetStarvationTime @@ -1477,17 +1448,17 @@ static void SetSeed() { * Returns: * Always returns 0. *****************************************************************************/ - int TPAttrSetStarvationTime( ThreadPoolAttr * attr, - int starvationTime ) { - assert( attr != NULL ); +int TPAttrSetStarvationTime( ThreadPoolAttr *attr, int starvationTime ) +{ + assert( attr != NULL ); + if( attr == NULL ) { + return EINVAL; + } - if( attr == NULL ) { - return EINVAL; - } + attr->starvationTime = starvationTime; - attr->starvationTime = starvationTime; - return 0; - } + return 0; +} /**************************************************************************** * Function: TPAttrSetSchedPolicy @@ -1500,18 +1471,43 @@ static void SetSeed() { * Returns: * Always returns 0. *****************************************************************************/ - int TPAttrSetSchedPolicy( ThreadPoolAttr * attr, - PolicyType schedPolicy ) { - assert( attr != NULL ); - if( attr == NULL ) { - return EINVAL; - } - attr->schedPolicy = schedPolicy; - return 0; - } +int TPAttrSetSchedPolicy( ThreadPoolAttr *attr, PolicyType schedPolicy ) +{ + assert( attr != NULL ); + if( attr == NULL ) { + return EINVAL; + } + + attr->schedPolicy = schedPolicy; + + return 0; +} + +/**************************************************************************** + * Function: TPAttrSetMaxJobsTotal + * + * Description: + * Sets the maximum number jobs that can be qeued totally. + * Parameters: + * attr - must be valid thread pool attributes. + * maxJobsTotal - maximum number of jobs + * Returns: + * Always returns 0. + *****************************************************************************/ +int TPAttrSetMaxJobsTotal( ThreadPoolAttr *attr, int maxJobsTotal ) +{ + assert( attr != NULL ); + if( attr == NULL ) { + return EINVAL; + } + + attr->maxJobsTotal = maxJobsTotal; + + return 0; +} #ifdef STATS -void ThreadPoolPrintStats(ThreadPoolStats * stats) +void ThreadPoolPrintStats(ThreadPoolStats *stats) { assert( stats != NULL ); if (stats == NULL) { @@ -1519,9 +1515,9 @@ void ThreadPoolPrintStats(ThreadPoolStats * stats) } #ifdef __FreeBSD__ - printf("ThreadPoolStats at Time: %d\n", time(NULL)); + printf("ThreadPoolStats at Time: %d\n", StatsTime(NULL)); #else /* __FreeBSD__ */ - printf("ThreadPoolStats at Time: %ld\n", time(NULL)); + printf("ThreadPoolStats at Time: %ld\n", StatsTime(NULL)); #endif /* __FreeBSD__ */ printf("High Jobs pending: %d\n", stats->currentJobsHQ); printf("Med Jobs Pending: %d\n", stats->currentJobsMQ); @@ -1539,31 +1535,6 @@ void ThreadPoolPrintStats(ThreadPoolStats * stats) } #endif /* STATS */ - /**************************************************************************** - * Function: TPAttrSetMaxJobsTotal - * - * Description: - * Sets the maximum number jobs that can be qeued totally. - * Parameters: - * attr - must be valid thread pool attributes. - * maxJobsTotal - maximum number of jobs - * Returns: - * Always returns 0. - *****************************************************************************/ -int TPAttrSetMaxJobsTotal( - ThreadPoolAttr * attr, - int maxJobsTotal ) -{ - assert( attr != NULL ); - - if( attr == NULL ) { - return EINVAL; - } - - attr->maxJobsTotal = maxJobsTotal; - return 0; -} - /**************************************************************************** * Function: ThreadPoolGetStats * @@ -1578,14 +1549,10 @@ int TPAttrSetMaxJobsTotal( * 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; } diff --git a/threadutil/src/iasnprintf.c b/threadutil/src/iasnprintf.c deleted file mode 100644 index ff5470f..0000000 --- a/threadutil/src/iasnprintf.c +++ /dev/null @@ -1,153 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// -// Copyright (c) 2000-2003 Intel Corporation -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither name of Intel Corporation nor the names of its contributors -// may be used to endorse or promote products derived from this software -// without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -/////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#if (defined(BSD) && BSD >= 199306) || defined(__OSX__) -#include -#else -#include -#endif -#include -#include "iasnprintf.h" - -#ifndef NULL -#define NULL 0 -#endif - -#ifdef WIN32 - #define vsnprintf _vsnprintf -#endif - -/** - * Allocates enough memory for the - * Formatted string, up to max - * specified. - * With max set to -1, it allocates as - * much size as needed. - * Memory must be freed using free. - */ - -int -iasnprintf( char **ret, - int incr, - int max, - const char *fmt, - ... ) -{ - int size = incr; - int retc = 0; - va_list ap; - char *temp = NULL; - - assert( ret ); - assert( fmt ); - ( *ret ) = ( char * )malloc( incr ); - - if( ( *ret ) == NULL ) return -1; - - while( 1 ) { - va_start( ap, fmt ); - retc = vsnprintf( ( *ret ), size, fmt, ap ); - va_end( ap ); - - if( retc < 0 ) { - //size not big enough - //and vsnprintf does NOT return the - //necessary number of bytes - if( ( max != -1 ) && ( size == max ) ) //max reached - { - break; - } - - incr *= 2; //increase increment - //increase size and try again - if( ( max != -1 ) && ( ( size + incr ) > max ) ) { - incr = ( max - size ); - } - - temp = ( char * )realloc( ( *ret ), size + incr ); - if( temp == NULL ) { - break; - } - size += incr; - ( *ret ) = temp; - - } else { - if( ( retc + 1 ) > size ) { - //size not big enough - //and vsnprintf - //returns the necessary - //number of bytes - if( ( max != -1 ) && ( retc + 1 > max ) ) { - retc = -1; - break; - } - - temp = ( char * )realloc( ( *ret ), retc + 1 ); - if( temp == NULL ) { - retc = -1; - break; - } - size = retc + 1; - ( *ret ) = temp; //size increased try again - } else if( ( retc + 1 ) < size ) { - //size is bigger than needed - //try and reallocate smaller - - temp = ( char * )realloc( ( *ret ), retc + 1 ); - if( temp != NULL ) { - ( *ret ) = temp; - } - break; - } else //size is just right, exit - { - break; - } - - } - } - - if( retc < 0 ) { - free( ( *ret ) ); - ( *ret ) = NULL; - } - - return retc; -} - -void -iasnprintfFree( char *fChar ) -{ - free( fChar ); - fChar = NULL; -} diff --git a/upnp/Makefile.am b/upnp/Makefile.am index 85bacad..a031186 100644 --- a/upnp/Makefile.am +++ b/upnp/Makefile.am @@ -1,7 +1,7 @@ # # "Makefile.am" for "libupnp/upnp" # -# Copyright (C) 2005 Rémi Turboult +# Copyright (C) 2005 R�mi Turboult # SUBDIRS = doc . sample @@ -11,10 +11,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/threadutil/inc \ -I$(top_srcdir)/ixml/inc -AM_CFLAGS = $(PTHREAD_CFLAGS) - -AM_LDFLAGS = $(PTHREAD_LIBS) - LDADD = \ libupnp.la \ $(top_builddir)/threadutil/libthreadutil.la \ diff --git a/upnp/sample/Makefile.am b/upnp/sample/Makefile.am index 590a5e3..2a7b0b8 100644 --- a/upnp/sample/Makefile.am +++ b/upnp/sample/Makefile.am @@ -9,10 +9,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/threadutil/inc \ -I$(top_srcdir)/ixml/inc -AM_CFLAGS = $(PTHREAD_CFLAGS) - -AM_LDFLAGS = $(PTHREAD_LIBS) - LDADD = \ $(top_builddir)/upnp/libupnp.la \ $(top_builddir)/threadutil/libthreadutil.la \