version 1.12, 2002/03/18 11:34:28
|
version 1.13, 2002/03/18 15:38:18
|
|
|
if(pool == 0 ) | if(pool == 0 ) |
throw NullPointer(); | throw NullPointer(); |
Semaphore *sleep_sem = 0; | Semaphore *sleep_sem = 0; |
|
Semaphore *blocking_sem = 0; |
|
|
struct timeval *deadlock_timer = 0; | struct timeval *deadlock_timer = 0; |
| |
try | try |
|
|
myself->dereference_tsd(); | myself->dereference_tsd(); |
parm = myself->reference_tsd("work parm"); | parm = myself->reference_tsd("work parm"); |
myself->dereference_tsd(); | myself->dereference_tsd(); |
|
blocking_sem = (Semaphore *)myself->reference_tsd("blocking sem"); |
|
myself->dereference_tsd(); |
|
|
} | } |
catch(IPCException &) | catch(IPCException &) |
{ | { |
|
|
gettimeofday(deadlock_timer, NULL); | gettimeofday(deadlock_timer, NULL); |
_work(parm); | _work(parm); |
| |
|
if( blocking_sem != 0 ) |
|
blocking_sem->signal(); |
|
|
// put myself back onto the available list | // put myself back onto the available list |
try | try |
{ | { |
|
|
return((PEGASUS_THREAD_RETURN)0); | return((PEGASUS_THREAD_RETURN)0); |
} | } |
| |
|
|
void ThreadPool::allocate_and_awaken(void *parm, | void ThreadPool::allocate_and_awaken(void *parm, |
PEGASUS_THREAD_RETURN \ | PEGASUS_THREAD_RETURN \ |
(PEGASUS_THREAD_CDECL *work)(void *)) |
(PEGASUS_THREAD_CDECL *work)(void *), |
|
Semaphore *blocking) |
|
|
throw(IPCException) | throw(IPCException) |
{ | { |
struct timeval start; | struct timeval start; |
|
|
(void *)work); | (void *)work); |
th->remove_tsd("work parm"); | th->remove_tsd("work parm"); |
th->put_tsd("work parm", NULL, sizeof(void *), parm); | th->put_tsd("work parm", NULL, sizeof(void *), parm); |
|
th->remove_tsd("blocking sem"); |
|
if(blocking != 0 ) |
|
th->put_tsd("blocking sem", NULL, sizeof(Semaphore *), blocking); |
| |
// put the thread on the running list | // put the thread on the running list |
_running.insert_first(th); | _running.insert_first(th); |
|
|
| |
if(sleep_sem == 0) | if(sleep_sem == 0) |
{ | { |
|
|
th->dereference_tsd(); | th->dereference_tsd(); |
throw NullPointer(); | throw NullPointer(); |
} | } |
|
|
{ | { |
// if we are deallocating from the pool, escape if we are | // if we are deallocating from the pool, escape if we are |
// down to the minimum thread count | // down to the minimum thread count |
|
_current_threads--; |
if( _current_threads.value() <= (Uint32)_min_threads ) | if( _current_threads.value() <= (Uint32)_min_threads ) |
{ | { |
if( i == 1) |
if( i == 0) |
{ | { |
|
_current_threads++; |
th = q->next(th); | th = q->next(th); |
continue; | continue; |
} | } |
|
|
_dead.insert_first(th); | _dead.insert_first(th); |
bodies++; | bodies++; |
sleep_sem->signal(); | sleep_sem->signal(); |
|
|
th->dereference_tsd(); | th->dereference_tsd(); |
th = 0; | th = 0; |
} | } |
|
|
} | } |
| |
| |
// inline int timeval_subtract (struct timeval *result, |
|
// struct timeval *x, |
|
// struct timeval *y) |
|
// { |
|
// /* Perform the carry for the later subtraction by updating Y. */ |
|
// if (x->tv_usec < y->tv_usec) { |
|
// int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1; |
|
// y->tv_usec -= 1000000 * nsec; |
|
// y->tv_sec += nsec; |
|
// } |
|
// if (x->tv_usec - y->tv_usec > 1000000) { |
|
// int nsec = (x->tv_usec - y->tv_usec) / 1000000; |
|
// y->tv_usec += 1000000 * nsec; |
|
// y->tv_sec -= nsec; |
|
// } |
|
|
|
// /* Compute the time remaining to wait. |
|
// `tv_usec' is certainly positive. */ |
|
// result->tv_sec = x->tv_sec - y->tv_sec; |
|
// result->tv_usec = x->tv_usec - y->tv_usec; |
|
|
|
// /* Return 1 if result is negative. */ |
|
// return x->tv_sec < y->tv_sec; |
|
// } |
|
|
|
Boolean ThreadPool::check_time(struct timeval *start, struct timeval *interval) | Boolean ThreadPool::check_time(struct timeval *start, struct timeval *interval) |
{ | { |
struct timeval now; |
struct timeval now, finish, remaining; |
|
Uint32 usec; |
gettimeofday(&now, NULL); | gettimeofday(&now, NULL); |
start->tv_sec += interval->tv_sec; |
|
start->tv_usec += interval->tv_usec; |
|
start->tv_sec += start->tv_usec / 1000000; |
|
start->tv_usec %= 1000000; |
|
struct timeval remaining; |
|
| |
if ( timeval_subtract(&remaining, start, &now) ) |
finish.tv_sec = start->tv_sec + interval->tv_sec; |
|
usec = start->tv_usec + interval->tv_usec; |
|
finish.tv_sec += (usec / 1000000); |
|
usec %= 1000000; |
|
finish.tv_usec = usec; |
|
|
|
if ( timeval_subtract(&remaining, &finish, &now) ) |
return true; | return true; |
else | else |
return false; | return false; |