[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Dotgnu-pnet-commits] CVS: pnet/support thread.c,1.11,1.12 thr_defs.h,1
From: |
Thong Nguyen <address@hidden> |
Subject: |
[Dotgnu-pnet-commits] CVS: pnet/support thread.c,1.11,1.12 thr_defs.h,1.6,1.7 |
Date: |
Mon, 07 Jul 2003 15:44:07 -0400 |
Update of /cvsroot/dotgnu-pnet/pnet/support
In directory subversions:/tmp/cvs-serv29847/support
Modified Files:
thread.c thr_defs.h
Log Message:
Added support for thread cleanup handlers and fixed
race condition in ILThreadJoin()
Index: thread.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/support/thread.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -r1.11 -r1.12
*** thread.c 6 Jul 2003 05:18:11 -0000 1.11
--- thread.c 7 Jul 2003 19:44:05 -0000 1.12
***************
*** 4,7 ****
--- 4,9 ----
* Copyright (C) 2002 Southern Storm Software, Pty Ltd.
*
+ * Contributions from Thong Nguyen (tum) address@hidden
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
***************
*** 574,641 ****
else
{
! /* Add ourselves to the foreign thread's join queue */
! if(!_ILWakeupQueueAdd(&(thread->joinQueue), &(self->wakeup),
self))
{
! result = IL_JOIN_MEMORY;
}
else
! {
! /* Unlock the foreign thread */
! _ILMutexUnlock(&(thread->lock));
!
! /* Put ourselves into the "wait/sleep/join" state */
! _ILMutexLock(&(self->lock));
! if((self->state & (IL_TS_ABORTED |
IL_TS_ABORT_REQUESTED)) != 0)
! {
! /* The current thread is aborted */
! _ILMutexUnlock(&(self->lock));
! _ILMutexLock(&(thread->lock));
! _ILWakeupQueueRemove(&(thread->joinQueue),
&(self->wakeup));
! _ILMutexUnlock(&(thread->lock));
! return IL_JOIN_ABORTED;
! }
! self->state |= IL_TS_WAIT_SLEEP_JOIN;
! _ILMutexUnlock(&(self->lock));
!
! /* Wait until we are woken or a timeout occurs */
! if(_ILWakeupSetLimit(&(self->wakeup), 1))
{
! result = _ILWakeupWait(&(self->wakeup), ms,
(void **)0);
}
else
{
! result = -1;
! }
! if(result < 0)
! {
! /* The wakeup was interrupted. It may be
either an
! "interrupt" or an "abort request". We
assume abort
! for now until we can inspect "self->state"
below */
! result = IL_JOIN_ABORTED;
! }
! else if(result > 0)
! {
! result = IL_JOIN_OK;
! }
! else
! {
! result = IL_JOIN_TIMEOUT;
! }
! /* Remove ourselves from the "wait/sleep/join" state,
! and check for a pending interrupt */
! _ILMutexLock(&(self->lock));
! if((self->state & IL_TS_INTERRUPTED) != 0)
! {
! result = IL_JOIN_INTERRUPTED;
! }
! self->state &= ~(IL_TS_WAIT_SLEEP_JOIN |
IL_TS_INTERRUPTED);
! _ILMutexUnlock(&(self->lock));
! /* Lock down the foreign thread again */
! _ILMutexLock(&(thread->lock));
! /* Remove ourselves from the foreign thread's join
queue */
! _ILWakeupQueueRemove(&(thread->joinQueue),
&(self->wakeup));
}
}
--- 576,651 ----
else
{
! /* Note: We must set our wait limit before adding ourselves to
any wait queues.
! Failure to do so may mean we may miss some signals because
they will be
! aborted by the signal invoker (which reads us as having
a null wait limit).
! In this specific case, the order doesn't actually
matter because we have locked
! the queue owner (the thread) but both operations must
be performed before we
! unlock the thread - Tum */
!
! /* Set our wait limit to 1 */
! if(!_ILWakeupSetLimit(&(self->wakeup), 1))
{
! result = -1;
}
else
! {
! /* Add ourselves to the foreign thread's join queue */
! if(!_ILWakeupQueueAdd(&(thread->joinQueue),
&(self->wakeup), self))
{
! result = IL_JOIN_MEMORY;
}
else
{
! /* Unlock the foreign thread */
! _ILMutexUnlock(&(thread->lock));
! /* Put ourselves into the "wait/sleep/join"
state */
! _ILMutexLock(&(self->lock));
! if((self->state & (IL_TS_ABORTED |
IL_TS_ABORT_REQUESTED)) != 0)
! {
! /* The current thread is aborted */
! _ILMutexUnlock(&(self->lock));
! _ILMutexLock(&(thread->lock));
!
_ILWakeupQueueRemove(&(thread->joinQueue), &(self->wakeup));
! _ILMutexUnlock(&(thread->lock));
! return IL_JOIN_ABORTED;
! }
! self->state |= IL_TS_WAIT_SLEEP_JOIN;
! _ILMutexUnlock(&(self->lock));
! result = _ILWakeupWait(&(self->wakeup), ms,
(void **)0);
!
! if(result < 0)
! {
! /* The wakeup was interrupted. It may
be either an
! "interrupt" or an "abort request". We
assume abort
! for now until we can inspect
"self->state" below */
! result = IL_JOIN_ABORTED;
! }
! else if(result > 0)
! {
! result = IL_JOIN_OK;
! }
! else
! {
! result = IL_JOIN_TIMEOUT;
! }
!
! /* Remove ourselves from the "wait/sleep/join"
state,
! and check for a pending interrupt */
! _ILMutexLock(&(self->lock));
! if((self->state & IL_TS_INTERRUPTED) != 0)
! {
! result = IL_JOIN_INTERRUPTED;
! }
! self->state &= ~(IL_TS_WAIT_SLEEP_JOIN |
IL_TS_INTERRUPTED);
! _ILMutexUnlock(&(self->lock));
! /* Lock down the foreign thread again */
! _ILMutexLock(&(thread->lock));
!
! /* Remove ourselves from the foreign thread's
join queue */
! _ILWakeupQueueRemove(&(thread->joinQueue),
&(self->wakeup));
! }
}
}
Index: thr_defs.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/support/thr_defs.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** thr_defs.h 7 Dec 2002 10:46:55 -0000 1.6
--- thr_defs.h 7 Jul 2003 19:44:05 -0000 1.7
***************
*** 85,88 ****
--- 85,99 ----
/*
+ * Supports linked lists of cleanup functions.
+ */
+ typedef struct _tagILThreadCleanupEntry ILThreadCleanupEntry;
+
+ struct _tagILThreadCleanupEntry
+ {
+ ILThreadCleanupFunc cleanup;
+ ILThreadCleanupEntry *next;
+ };
+
+ /*
* Internal structure of a thread descriptor.
*/
***************
*** 102,106 ****
_ILWakeup wakeup;
_ILWakeupQueue joinQueue;
!
};
--- 113,118 ----
_ILWakeup wakeup;
_ILWakeupQueue joinQueue;
! ILThreadCleanupEntry *firstCleanupEntry;
! ILThreadCleanupEntry *lastCleanupEntry;
};
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Dotgnu-pnet-commits] CVS: pnet/support thread.c,1.11,1.12 thr_defs.h,1.6,1.7,
Thong Nguyen <address@hidden> <=