Removing unnecessary additional directory level.

git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@29 119443c7-1b9e-41f8-b6fc-b9c35fce742c
This commit is contained in:
Marcelo Roberto Jimenez
2006-07-04 02:44:17 +00:00
parent 90c3db2a96
commit 89e7a40fcc
185 changed files with 0 additions and 0 deletions

177
threadutil/src/FreeList.c Normal file
View File

@@ -0,0 +1,177 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "FreeList.h"
#include <assert.h>
#include <stdlib.h>
/****************************************************************************
* Function: FreeListInit
*
* Description:
* Initializes Free List. Must be called first.
* And only once for FreeList.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* size_t - size of elements to store in free list
* maxFreeListSize - max size that the free list can grow to
* before returning memory to O.S.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int
FreeListInit( FreeList * free_list,
size_t elementSize,
int maxFreeListLength )
{
assert( free_list != NULL );
if( free_list == NULL )
return EINVAL;
free_list->element_size = elementSize;
free_list->maxFreeListLength = maxFreeListLength;
free_list->head = NULL;
free_list->freeListLength = 0;
return 0;
}
/****************************************************************************
* Function: FreeListAlloc
*
* Description:
* Allocates chunk of set size.
* If a free item is available in the list, returnes the stored item.
* Otherwise calls the O.S. to allocate memory.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* Returns:
* Non NULL on success. NULL on failure.
*****************************************************************************/
void *
FreeListAlloc( FreeList * free_list )
{
FreeListNode *ret = NULL;
assert( free_list != NULL );
if( free_list == NULL )
return NULL;
if( free_list->head ) {
ret = free_list->head;
free_list->head = free_list->head->next;
free_list->freeListLength--;
} else {
ret = malloc( free_list->element_size );
}
return ret;
}
/****************************************************************************
* Function: FreeListFree
*
* Description:
* Returns an item to the Free List.
* If the free list is smaller than the max size than
* adds the item to the free list.
* Otherwise returns the item to the O.S.
* Parameters:
* free_list - must be valid, non null, pointer to a free list.
* element - must be a pointer allocated by FreeListAlloc
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int
FreeListFree( FreeList * free_list,
void *element )
{
FreeListNode *temp = NULL;
assert( free_list != NULL );
if( free_list == NULL )
return EINVAL;
if( ( element != NULL ) &&
( ( free_list->freeListLength + 1 ) <
free_list->maxFreeListLength ) ) {
free_list->freeListLength++;
temp = ( FreeListNode * ) element;
temp->next = free_list->head;
free_list->head = temp;
} else {
free( element );
}
return 0;
}
/****************************************************************************
* Function: FreeListDestroy
*
* Description:
* Releases the resources stored with the free list.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int
FreeListDestroy( FreeList * free_list )
{
FreeListNode *temp = NULL;
int i = 0;
assert( free_list != NULL );
if( free_list == NULL )
return EINVAL;
while( free_list->head ) {
i++;
temp = free_list->head->next;
free( free_list->head );
free_list->head = temp;
}
free_list->freeListLength = 0;
return 0;
}

533
threadutil/src/LinkedList.c Normal file
View File

@@ -0,0 +1,533 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "LinkedList.h"
#ifdef __FreeBSD__
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#include <assert.h>
static int
freeListNode( ListNode * node,
LinkedList * list )
{
assert( list != NULL );
return FreeListFree( &list->freeNodeList, node );
}
/****************************************************************************
* Function: CreateListNode
*
* Description:
* Creates a list node. Dynamically.
*
* Parameters:
* void * item - the item to store
* Returns:
* The new node, NULL on failure.
*****************************************************************************/
static ListNode *
CreateListNode( void *item,
LinkedList * list )
{
ListNode *temp = NULL;
assert( list != NULL );
temp = ( ListNode * ) FreeListAlloc( &list->freeNodeList );
if( temp ) {
temp->prev = NULL;
temp->next = NULL;
temp->item = item;
}
return temp;
}
/****************************************************************************
* Function: ListInit
*
* Description:
* Initializes LinkedList. Must be called first.
* And only once for List.
* Parameters:
* list - must be valid, non null, pointer to a linked list.
* cmp_func - function used to compare items. (May be NULL)
* free_func - function used to free items. (May be NULL)
* Returns:
* 0 on success, EOUTOFMEM on failure.
*****************************************************************************/
int
ListInit( LinkedList * list,
cmp_routine cmp_func,
free_function free_func )
{
int retCode = 0;
assert( list != NULL );
if( list == NULL )
return EINVAL;
list->size = 0;
list->cmp_func = cmp_func;
list->free_func = free_func;
retCode =
FreeListInit( &list->freeNodeList, sizeof( ListNode ),
FREELISTSIZE );
assert( retCode == 0 );
list->head.item = NULL;
list->head.next = &list->tail;
list->head.prev = NULL;
list->tail.item = NULL;
list->tail.prev = &list->head;
list->tail.next = NULL;
return 0;
}
/****************************************************************************
* Function: ListAddHead
*
* Description:
* Adds a node to the head of the list.
* Node gets immediately after list.head.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddHead( LinkedList * list,
void *item )
{
assert( list != NULL );
if( list == NULL )
return NULL;
return ListAddAfter( list, item, &list->head );
}
/****************************************************************************
* Function: ListAddTail
*
* Description:
* Adds a node to the tail of the list.
* Node gets added immediately before list.tail.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddTail( LinkedList * list,
void *item )
{
assert( list != NULL );
if( list == NULL )
return NULL;
return ListAddBefore( list, item, &list->tail );
}
/****************************************************************************
* Function: ListAddAfter
*
* Description:
* Adds a node after the specified node.
* Node gets added immediately after bnode.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* ListNode * bnode - node to add after
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddAfter( LinkedList * list,
void *item,
ListNode * bnode )
{
ListNode *newNode = NULL;
assert( list != NULL );
if( ( list == NULL ) || ( bnode == NULL ) )
return NULL;
newNode = CreateListNode( item, list );
if( newNode ) {
ListNode *temp = bnode->next;
bnode->next = newNode;
newNode->prev = bnode;
newNode->next = temp;
temp->prev = newNode;
list->size++;
return newNode;
}
return NULL;
}
/****************************************************************************
* Function: ListAddBefore
*
* Description:
* Adds a node before the specified node.
* Node gets added immediately before anode.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode * anode - node to add the in front of.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddBefore( LinkedList * list,
void *item,
ListNode * anode )
{
ListNode *newNode = NULL;
assert( list != NULL );
if( ( list == NULL ) || ( anode == NULL ) )
return NULL;
newNode = CreateListNode( item, list );
if( newNode ) {
ListNode *temp = anode->prev;
anode->prev = newNode;
newNode->next = anode;
newNode->prev = temp;
temp->next = newNode;
list->size++;
return newNode;
}
return NULL;
}
/****************************************************************************
* Function: ListDelNode
*
* Description:
* Removes a node from the list
* The memory for the node is freed but the
* the memory for the items are not.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode *dnode - done to delete.
* Returns:
* The pointer to the item stored in node on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
void *
ListDelNode( LinkedList * list,
ListNode * dnode,
int freeItem )
{
void *temp;
assert( list != NULL );
assert( dnode != &list->head );
assert( dnode != &list->tail );
if( ( list == NULL ) ||
( dnode == &list->head ) ||
( dnode == &list->tail ) || ( dnode == NULL ) ) {
return NULL;
}
temp = dnode->item;
dnode->prev->next = dnode->next;
dnode->next->prev = dnode->prev;
freeListNode( dnode, list );
list->size--;
if( freeItem && list->free_func ) {
list->free_func( temp );
temp = NULL;
}
return temp;
}
/****************************************************************************
* Function: ListDestroy
*
* Description:
* Removes all memory associated with list nodes.
* Does not free LinkedList *list.
* Items stored in the list are not freed, only nodes are.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
* Precondition:
* The list has been initialized.
*****************************************************************************/
int
ListDestroy( LinkedList * list,
int freeItem )
{
ListNode *dnode = NULL;
ListNode *temp = NULL;
if( list == NULL )
return EINVAL;
for( dnode = list->head.next; dnode != &list->tail; ) {
temp = dnode->next;
ListDelNode( list, dnode, freeItem );
dnode = temp;
}
list->size = 0;
FreeListDestroy( &list->freeNodeList );
return 0;
}
/****************************************************************************
* Function: ListHead
*
* Description:
* Returns the head of the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The head of the list. NULL if list is empty.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListHead( LinkedList * list )
{
assert( list != NULL );
if( list == NULL )
return NULL;
if( list->size == 0 )
return NULL;
else
return list->head.next;
}
/****************************************************************************
* Function: ListTail
*
* Description:
* Returns the tail of the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The tail of the list. NULL if list is empty.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListTail( LinkedList * list )
{
assert( list != NULL );
if( list == NULL )
return NULL;
if( list->size == 0 )
return NULL;
else
return list->tail.prev;
}
/****************************************************************************
* Function: ListNext
*
* Description:
* Returns the next item in the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The next item in the list. NULL if there are no more items in list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListNext( LinkedList * list,
ListNode * node )
{
assert( list != NULL );
assert( node != NULL );
if( ( list == NULL ) || ( node == NULL ) )
return NULL;
if( node->next == &list->tail )
return NULL;
else
return node->next;
}
/****************************************************************************
* Function: ListPrev
*
* Description:
* Returns the previous item in the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The previous item in the list. NULL if there are no more items in list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListPrev( LinkedList * list,
ListNode * node )
{
assert( list != NULL );
assert( node != NULL );
if( ( list == NULL ) || ( node == NULL ) )
return NULL;
if( node->prev == &list->head )
return NULL;
else
return node->prev;
}
/****************************************************************************
* Function: ListFind
*
* Description:
* Finds the specified item in the list.
* Uses the compare function specified in ListInit. If compare function
* is NULL then compares items as pointers.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode *start - the node to start from, NULL if to start from
* beginning.
* void * item - the item to search for.
* Returns:
* The node containing the item. NULL if no node contains the item.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListFind( LinkedList * list,
ListNode * start,
void *item )
{
ListNode *finger = NULL;
if( list == NULL )
return NULL;
if( start == NULL )
start = &list->head;
assert( start );
finger = start->next;
assert( finger );
while( finger != &list->tail ) {
if( list->cmp_func ) {
if( list->cmp_func( item, finger->item ) )
return finger;
} else {
if( item == finger->item )
return finger;
}
finger = finger->next;
}
return NULL;
}
/****************************************************************************
* Function: ListSize
*
* Description:
* Returns the size of the list.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* Returns:
* The number of items in the list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
int
ListSize( LinkedList * list )
{
assert( list != NULL );
if( list == NULL )
return EINVAL;
return list->size;
}

1545
threadutil/src/ThreadPool.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,519 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 "TimerThread.h"
#include <assert.h>
/****************************************************************************
* Function: FreeTimerEvent
*
* Description:
* Deallocates a dynamically allocated TimerEvent.
* Parameters:
* TimerEvent *event - must be allocated with CreateTimerEvent
*****************************************************************************/
static void
FreeTimerEvent( TimerThread * timer,
TimerEvent * event )
{
assert( timer != NULL );
FreeListFree( &timer->freeEvents, event );
}
/****************************************************************************
* Function: TimerThreadWorker
*
* Description:
* Implements timer thread.
* Waits for next event to occur and schedules
* associated job into threadpool.
* Internal Only.
* Parameters:
* void * arg -> is cast to TimerThread *
*****************************************************************************/
static void *
TimerThreadWorker( void *arg )
{
TimerThread *timer = ( TimerThread * ) arg;
ListNode *head = NULL;
TimerEvent *nextEvent = NULL;
time_t currentTime = 0;
time_t nextEventTime = 0;
struct timespec timeToWait;
int tempId;
assert( timer != NULL );
ithread_mutex_lock( &timer->mutex );
while( 1 )
{
//mutex should always be locked at top of loop
//Check for shutdown
if( timer->shutdown )
{
timer->shutdown = 0;
ithread_cond_signal( &timer->condition );
ithread_mutex_unlock( &timer->mutex );
return NULL;
}
nextEvent = NULL;
//Get the next event if possible
if( timer->eventQ.size > 0 )
{
head = ListHead( &timer->eventQ );
nextEvent = ( TimerEvent * ) head->item;
nextEventTime = nextEvent->eventTime;
}
currentTime = time( NULL );
//If time has elapsed, schedule job
if( ( nextEvent != NULL ) && ( currentTime >= nextEventTime ) )
{
if( nextEvent->persistent ) {
ThreadPoolAddPersistent( timer->tp, &nextEvent->job,
&tempId );
} else {
ThreadPoolAdd( timer->tp, &nextEvent->job, &tempId );
}
ListDelNode( &timer->eventQ, head, 0 );
FreeTimerEvent( timer, nextEvent );
continue;
}
if( nextEvent != NULL ) {
timeToWait.tv_nsec = 0;
timeToWait.tv_sec = nextEvent->eventTime;
ithread_cond_timedwait( &timer->condition, &timer->mutex,
&timeToWait );
} else {
ithread_cond_wait( &timer->condition, &timer->mutex );
}
}
}
/****************************************************************************
* Function: CalculateEventTime
*
* Description:
* Calculates the appropriate timeout in absolute seconds since
* Jan 1, 1970
* Internal Only.
* Parameters:
* time_t *timeout - timeout
*
*****************************************************************************/
static int
CalculateEventTime( time_t * timeout,
TimeoutType type )
{
time_t now;
assert( timeout != NULL );
if( type == ABS_SEC )
return 0;
else if( type == REL_SEC ) {
time( &now );
( *timeout ) += now;
return 0;
}
return -1;
}
/****************************************************************************
* Function: CreateTimerEvent
*
* Description:
* Creates a Timer Event. (Dynamically allocated)
* Internal to timer thread.
* Parameters:
* func - thread function to run.
* arg - argument to function.
* priority - priority of job.
* eventTime - the absoule time of the event
* in seconds from Jan, 1970
* id - id of job
*
* Returns:
* TimerEvent * on success, NULL on failure.
****************************************************************************/
static TimerEvent *
CreateTimerEvent( TimerThread * timer,
ThreadPoolJob * job,
Duration persistent,
time_t eventTime,
int id )
{
TimerEvent *temp = NULL;
assert( timer != NULL );
assert( job != NULL );
temp = ( TimerEvent * ) FreeListAlloc( &timer->freeEvents );
if( temp == NULL )
return temp;
temp->job = ( *job );
temp->persistent = persistent;
temp->eventTime = eventTime;
temp->id = id;
return temp;
}
/************************************************************************
* Function: TimerThreadInit
*
* Description:
* Initializes and starts timer thread.
*
* Parameters:
* timer - valid timer thread pointer.
* tp - valid thread pool to use. Must be
* started. Must be valid for lifetime
* of timer. Timer must be shutdown
* BEFORE thread pool.
* Return:
* 0 on success, nonzero on failure
* Returns error from ThreadPoolAddPersistent if failure.
************************************************************************/
int
TimerThreadInit( TimerThread * timer,
ThreadPool * tp )
{
int rc = 0;
ThreadPoolJob timerThreadWorker;
assert( timer != NULL );
assert( tp != NULL );
if( ( timer == NULL ) || ( tp == NULL ) ) {
return EINVAL;
}
rc += ithread_mutex_init( &timer->mutex, NULL );
assert( rc == 0 );
rc += ithread_mutex_lock( &timer->mutex );
assert( rc == 0 );
rc += ithread_cond_init( &timer->condition, NULL );
assert( rc == 0 );
rc += FreeListInit( &timer->freeEvents, sizeof( TimerEvent ), 100 );
assert( rc == 0 );
timer->shutdown = 0;
timer->tp = tp;
timer->lastEventId = 0;
rc += ListInit( &timer->eventQ, NULL, NULL );
assert( rc == 0 );
if( rc != 0 ) {
rc = EAGAIN;
} else {
TPJobInit( &timerThreadWorker, TimerThreadWorker, timer );
TPJobSetPriority( &timerThreadWorker, HIGH_PRIORITY );
rc = ThreadPoolAddPersistent( tp, &timerThreadWorker, NULL );
}
ithread_mutex_unlock( &timer->mutex );
if( rc != 0 ) {
ithread_cond_destroy( &timer->condition );
ithread_mutex_destroy( &timer->mutex );
FreeListDestroy( &timer->freeEvents );
ListDestroy( &timer->eventQ, 0 );
}
return rc;
}
/************************************************************************
* Function: TimerThreadSchedule
*
* Description:
* Schedules an event to run at a specified time.
*
* Parameters:
* timer - valid timer thread pointer.
* time_t - time of event.
* either in absolute seconds,
* or relative seconds in the future.
* timeoutType - either ABS_SEC, or REL_SEC.
* if REL_SEC, then the event
* will be scheduled at the
* current time + REL_SEC.
*
* func - function to schedule
* arg - argument to function
* priority - priority of job.
* id - id of timer event. (out)
* Return:
* 0 on success, nonzero on failure
* EOUTOFMEM if not enough memory to schedule job
************************************************************************/
int
TimerThreadSchedule( TimerThread * timer,
time_t timeout,
TimeoutType type,
ThreadPoolJob * job,
Duration duration,
int *id )
{
int rc = EOUTOFMEM;
int found = 0;
int tempId = 0;
ListNode *tempNode = NULL;
TimerEvent *temp = NULL;
TimerEvent *newEvent = NULL;
assert( timer != NULL );
assert( job != NULL );
if( ( timer == NULL ) || ( job == NULL ) ) {
return EINVAL;
}
CalculateEventTime( &timeout, type );
ithread_mutex_lock( &timer->mutex );
if( id == NULL )
id = &tempId;
( *id ) = INVALID_EVENT_ID;
newEvent = CreateTimerEvent( timer, job, duration, timeout,
timer->lastEventId );
if( newEvent == NULL ) {
ithread_mutex_unlock( &timer->mutex );
return rc;
}
tempNode = ListHead( &timer->eventQ );
//add job to Q
//Q is ordered by eventTime
//with the head of the Q being the next event
while( tempNode != NULL ) {
temp = ( TimerEvent * ) tempNode->item;
if( temp->eventTime >= timeout )
{
if( ListAddBefore( &timer->eventQ, newEvent, tempNode ) !=
NULL )
rc = 0;
found = 1;
break;
}
tempNode = ListNext( &timer->eventQ, tempNode );
}
//add to the end of Q
if( !found ) {
if( ListAddTail( &timer->eventQ, newEvent ) != NULL )
rc = 0;
}
//signal change in Q
if( rc == 0 ) {
ithread_cond_signal( &timer->condition );
} else {
FreeTimerEvent( timer, newEvent );
}
( *id ) = timer->lastEventId++;
ithread_mutex_unlock( &timer->mutex );
return rc;
}
/************************************************************************
* Function: TimerThreadRemove
*
* Description:
* Removes an event from the timer Q.
* Events can only be removed
* before they have been placed in the
* thread pool.
*
* Parameters:
* timer - valid timer thread pointer.
* id - id of event to remove.
* out - space for returned job (Can be NULL)
* Return:
* 0 on success.
* INVALID_EVENT_ID on error.
*
************************************************************************/
int
TimerThreadRemove( TimerThread * timer,
int id,
ThreadPoolJob * out )
{
int rc = INVALID_EVENT_ID;
ListNode *tempNode = NULL;
TimerEvent *temp = NULL;
assert( timer != NULL );
if( timer == NULL ) {
return EINVAL;
}
ithread_mutex_lock( &timer->mutex );
tempNode = ListHead( &timer->eventQ );
while( tempNode != NULL ) {
temp = ( TimerEvent * ) tempNode->item;
if( temp->id == id )
{
ListDelNode( &timer->eventQ, tempNode, 0 );
if( out != NULL )
( *out ) = temp->job;
FreeTimerEvent( timer, temp );
rc = 0;
break;
}
tempNode = ListNext( &timer->eventQ, tempNode );
}
ithread_mutex_unlock( &timer->mutex );
return rc;
}
/************************************************************************
* Function: TimerThreadShutdown
*
* Description:
* Shutdown the timer thread
* Events scheduled in the future will NOT be run.
* Timer thread should be shutdown BEFORE it's associated
* thread pool.
* Returns:
* returns 0 if succesfull,
* nonzero otherwise.
* Always returns 0.
***********************************************************************/
int
TimerThreadShutdown( TimerThread * timer )
{
ListNode *tempNode2 = NULL;
ListNode *tempNode = NULL;
assert( timer != NULL );
if( timer == NULL ) {
return EINVAL;
}
ithread_mutex_lock( &timer->mutex );
timer->shutdown = 1;
tempNode = ListHead( &timer->eventQ );
//Delete nodes in Q
//call registered free function
//on argument
while( tempNode != NULL ) {
TimerEvent *temp = ( TimerEvent * ) tempNode->item;
tempNode2 = ListNext( &timer->eventQ, tempNode );
ListDelNode( &timer->eventQ, tempNode, 0 );
if( temp->job.free_func ) {
temp->job.free_func( temp->job.arg );
}
FreeTimerEvent( timer, temp );
tempNode = tempNode2;
}
ListDestroy( &timer->eventQ, 0 );
FreeListDestroy( &timer->freeEvents );
ithread_cond_broadcast( &timer->condition );
while( timer->shutdown ) //wait for timer thread to shutdown
{
ithread_cond_wait( &timer->condition, &timer->mutex );
}
ithread_mutex_unlock( &timer->mutex );
//destroy condition
while( ithread_cond_destroy( &timer->condition ) != 0 ) {
}
//destroy mutex
while( ithread_mutex_destroy( &timer->mutex ) != 0 ) {
}
return 0;
}

152
threadutil/src/iasnprintf.c Normal file
View File

@@ -0,0 +1,152 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <stdarg.h>
#include <assert.h>
#ifdef __FreeBSD__
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#include <stdio.h>
#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;
}