dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and to


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and tools (pnet) branch, master, updated. 59d694189026098b4cb888a445254a8b49b91d3e
Date: Sun, 06 Sep 2009 14:19:21 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "DotGNU Portable.NET engine, compilers and tools (pnet)".

The branch, master has been updated
       via  59d694189026098b4cb888a445254a8b49b91d3e (commit)
      from  32a1e14a66dc8e6426b26662573fb1278403140b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/pnet.git/commit/?id=59d694189026098b4cb888a445254a8b49b91d3e

commit 59d694189026098b4cb888a445254a8b49b91d3e
Author: Klaus Treichel <address@hidden>
Date:   Sun Sep 6 16:14:15 2009 +0200

    Optimize the memory usage for waithandles by moving the members that are
    identical for all waithandles of one kind to a vtable and adding
    a reference to the vtable instead.
    Optimize the places where the thread's state is changed.

diff --git a/ChangeLog b/ChangeLog
index e104ba1..2cfd26a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,34 @@
+2009-09-06  Klaus Treichel  <address@hidden>
+
+       * support/thr_defs.h: Add note for how to change a thread's state.
+       Add IL_THREAD_ERR_ABORTED to the threading error codes.
+       Change the member state in the ILThread to ILUInt16.
+       Add IL_TS_INTERRUPTED_OR_ABORT_REQUESTED to the thread state masks.
+       Add the ILWaitHandleVtable sructure to hold the members common to all
+       waithandles of one kind.
+       Replace the members common to waithandles of one kind with a reference
+       to a ILWaitHandleVtable sructure.
+       Add macros for accessing the members of a ILWaitHandle.
+
+       * support/thread.c: Change the thread's state modification according
+       to the new note in support/thr_defs.h.
+
+       * support/wait.c: Change the thread's state modification according
+       to the new note in support/thr_defs.h.
+       Use the new macros for accessing the waithandle members now.
+
+       * support/wait_event.c: Define the waithandle vtable for events and
+       store a reference in the new event's waithandle vtable.
+
+       * support/wait_mutex.c: Define the waithandle vtables for wait mutexes,
+       named wait mutexes and wait monitors and store a reference to the
+       corresponding vtable in the new waithandle's vtable.
+       Use the new macros for accessing the waithandle members now.
+
+       * support/wait_mutex.h: Change the thread's state modification according
+       to the new note in support/thr_defs.h.
+       Use the new macros for accessing the waithandle members now.
+
 2009-09-05  Klaus Treichel  <address@hidden>
 
        * engine/convert.c (ConvertMethod): Unlock the metadata here if the
diff --git a/support/thr_defs.h b/support/thr_defs.h
index 541f212..e511cad 100755
--- a/support/thr_defs.h
+++ b/support/thr_defs.h
@@ -23,6 +23,29 @@
 #define        _THR_DEFS_H
 
 /*
+ * NOTE: For modifying a thread's state
+ * If the thread's state is going to be modified do it the following way:
+ * 1. lock the thread
+ * 2. load the thread's state to a local variable
+ * 3. do what you want to do with the thread's state with the local variable
+ * 4. store the local variable to the thread's state
+ * 5. unlock the thread
+ *
+ * This is done this way to be able to query the current thread's state
+ * without having to lock the thread.
+ * The reader will read the consistent state before the thread was locked
+ * until all changes are done.
+ * Additionally the compiler is able to hold the thread's state in a
+ * register instead of having to read and write the volatile state multiple
+ * times.
+ */
+
+/*
+ * Define IL_THREAD_DEBUG for enabling threading debug features.
+ */
+/* #define IL_TRHEAD_DEBUG */
+
+/*
  * Predicate function for the _ILMonitorWait functions.
  * The function has to return 0 if the predicate is not true so that the
  * wait has to be called again and != 0 otherwise.
@@ -38,8 +61,9 @@ typedef int (*ILMonitorPredicate)(void *);
 #define IL_THREAD_ERR_INTERRUPT                                0x80131519
 #define IL_THREAD_ERR_INVALID_TIMEOUT          0x80131502
 #define IL_THREAD_ERR_SYNCLOCK                         0x80131518
+#define IL_THREAD_ERR_ABORTED                          0xFFFFFFFC
 #define IL_THREAD_ERR_INVALID_RELEASECOUNT     0xFFFFFFFD
-#define IL_THREAD_ERR_IN_USE                           0xFFFFFFFE
+#define IL_THREAD_ERR_OUTOFMEMORY                      0xFFFFFFFE
 #define IL_THREAD_ERR_UNKNOWN                          0xFFFFFFFF
 
 /*
@@ -127,7 +151,7 @@ struct _tagILThread
        _ILMutex                                                lock;
        _ILThreadHandle         volatile        handle;
        _ILThreadIdentifier     volatile        identifier;
-       unsigned short          volatile        state;
+       ILUInt16                volatile        state;
        unsigned char           volatile        resumeRequested;
        unsigned char           volatile        suspendRequested;
        unsigned int            volatile        numLocksHeld;
@@ -154,6 +178,8 @@ struct _tagILThread
 #define        IL_TS_PUBLIC_FLAGS              0x01FF
 #define        IL_TS_SUSPENDED_SELF    0x0200
 #define        IL_TS_INTERRUPTED               0x0400
+#define IL_TS_INTERRUPTED_OR_ABORT_REQUESTED \
+               (IL_TS_INTERRUPTED | IL_TS_ABORT_REQUESTED)
 
 /*
  * Wait handle kinds.
@@ -199,20 +225,35 @@ typedef void (*ILWaitUnregisterFunc)(ILWaitHandle 
*handle, _ILWakeup *wakeup,
 
 typedef int (*ILWaitSignalFunc)(ILWaitHandle *handle);
 
+typedef struct _tagILWaitHandleVtable _ILWaitHandleVtable;
+struct _tagILWaitHandleVtable
+{
+       const int                                       kind;
+       const ILWaitCloseFunc           closeFunc;
+       const ILWaitRegisterFunc        registerFunc;
+       const ILWaitUnregisterFunc      unregisterFunc;
+       const ILWaitSignalFunc          signalFunc;
+};
+
 /*
  * Internal structure of a wait handle.
  */
 struct _tagILWaitHandle
 {
-       _ILMutex                                      lock;
-       int                                      volatile kind;
-       ILWaitCloseFunc          volatile closeFunc;
-       ILWaitRegisterFunc       volatile registerFunc;
-       ILWaitUnregisterFunc volatile unregisterFunc;
-    ILWaitSignalFunc            volatile signalFunc;
+       const _ILWaitHandleVtable  *vtable;
+       _ILMutex                                        lock;
 };
 
 /*
+ * Some macros for accessing the waithandle members
+ */
+#define _ILWaitHandle_kind(handle)                             
((handle)->vtable->kind)
+#define _ILWaitHandle_closeFunc(handle)                        
((handle)->vtable->closeFunc)
+#define _ILWaitHandle_registerFunc(handle)             
((handle)->vtable->registerFunc)
+#define _ILWaitHandle_unregisterFunc(handle)   
((handle)->vtable->unregisterFunc)
+#define _ILWaitHandle_signalFunc(handle)               
((handle)->vtable->signalFunc)
+
+/*
  * Internal structure of a wait event handle.
  */
 typedef struct
@@ -269,7 +310,7 @@ typedef struct
 typedef struct _tagILMonitor ILMonitor;
 
 /*
- * Pool used ba the monitor.
+ * Pool used by the monitor.
  */
 typedef struct _tagILMonitorPool ILMonitorPool;
 struct _tagILMonitorPool
diff --git a/support/thread.c b/support/thread.c
index 06837fc..a72cc1f 100644
--- a/support/thread.c
+++ b/support/thread.c
@@ -186,6 +186,8 @@ static void _ILThreadRunAndFreeCleanups(ILThread *thread)
 
 static void _ILPrivateThreadDestroy(ILThread *thread, int allowSelf)
 {
+       ILUInt16 threadState;
+
        /* Bail out if this is the current thread or main thread */
        if((thread == _ILThreadGetSelf() && !allowSelf) || thread == 
&mainThread)
        {
@@ -195,13 +197,16 @@ static void _ILPrivateThreadDestroy(ILThread *thread, int 
allowSelf)
        /* Lock down the thread object */
        _ILMutexLock(&(thread->lock));
 
+       threadState = thread->state;
+
        /* Don't terminate the thread or adjust counts if it has already been 
stopped */
-       if((thread->state & IL_TS_STOPPED) == 0)
+       if((threadState & IL_TS_STOPPED) == 0)
        {
-               thread->state |= IL_TS_STOPPED;
+               threadState |= IL_TS_STOPPED;
+               thread->state = threadState;
 
                /* Only terminate the system thread if one was created */
-               if((thread->state & IL_TS_UNSTARTED) == 0)
+               if((threadState & IL_TS_UNSTARTED) == 0)
                {
                        /* Terminating the thread is unsafe so just don't
                           destroy now and tell the thread to destroy itself
@@ -228,7 +233,7 @@ static void _ILPrivateThreadDestroy(ILThread *thread, int 
allowSelf)
        }
 
        /* Only destroy the system thread if one was created */
-       if((thread->state & IL_TS_UNSTARTED) == 0)
+       if((threadState & IL_TS_UNSTARTED) == 0)
        {
                _ILThreadDestroy(thread);
        }
@@ -306,7 +311,7 @@ void *ILThreadRunSelf(void *(* thread_func)(void *), void 
*arg)
 }
 
 void _ILThreadRun(ILThread *thread)
-{      
+{
        /* When a thread starts, it blocks until the ILThreadStart function
           has finished setup */
        /* Wait until the starting thread has released the lock */
@@ -325,10 +330,15 @@ void _ILThreadRun(ILThread *thread)
        
        _ILMutexLock(&(thread->lock));
        {
+               ILUInt16 threadState;
+
+               threadState = thread->state;
+
                /* Mark the thread as stopped */
-               thread->state |= IL_TS_STOPPED; 
+               threadState |= IL_TS_STOPPED;   
+               thread->state = threadState;
                /* Change the thread count */           
-               _ILThreadAdjustCount(-1, ((thread->state & IL_TS_BACKGROUND) != 
0) ? -1 : 0);
+               _ILThreadAdjustCount(-1, ((threadState & IL_TS_BACKGROUND) != 
0) ? -1 : 0);
        }
        _ILMutexUnlock(&(thread->lock));
 
@@ -400,12 +410,15 @@ ILThread *ILThreadCreate(ILThreadStartFunc startFunc, 
void *startArg)
 int ILThreadStart(ILThread *thread)
 {
        int result;
+       ILUInt16 threadState;
 
        /* Lock down the thread object */
        _ILMutexLock(&(thread->lock));
 
+       threadState = thread->state;
+
        /* Are we in the correct state to start? */
-       if((thread->state & IL_TS_UNSTARTED) != 0)
+       if((threadState & IL_TS_UNSTARTED) != 0)
        {
                /* Create the new thread */
                if(!_ILThreadCreateSystem(thread))
@@ -415,10 +428,11 @@ int ILThreadStart(ILThread *thread)
                else
                {
                        /* Set the thread state to running (0) */
-                       thread->state &= ~IL_TS_UNSTARTED;
-                       thread->state |= IL_TS_RUNNING;
+                       threadState &= ~IL_TS_UNSTARTED;
+                       threadState |= IL_TS_RUNNING;
+                       thread->state = threadState;
 
-                       _ILThreadAdjustCount(1, (thread->state & 
IL_TS_BACKGROUND) ? 1 : 0);
+                       _ILThreadAdjustCount(1, (threadState & 
IL_TS_BACKGROUND) ? 1 : 0);
 
                        result = 1;
                }
@@ -430,6 +444,7 @@ int ILThreadStart(ILThread *thread)
 
        /* Unlock the thread object and return */
        _ILMutexUnlock(&(thread->lock));
+
        return result;
 }
 
@@ -459,42 +474,44 @@ int ILThreadSuspend(ILThread *thread)
 
 int ILThreadSuspendRequest(ILThread *thread, int requestOnly)
 {
-       unsigned int state;
+       ILUInt16 threadState;
        int result = IL_SUSPEND_OK;
 
        /* Lock down the thread object */
        _ILMutexLock(&(thread->lock));
 
        /* Determine what to do based on the thread's state */
-       state = thread->state;
-       if ((state & (IL_TS_ABORT_REQUESTED)) != 0)
+       threadState = thread->state;
+       if((threadState & (IL_TS_ABORT_REQUESTED)) != 0)
        {
-               return IL_WAIT_ABORTED;
+               result = IL_WAIT_ABORTED;
        }
-       else if((state & IL_TS_SUSPENDED) != 0)
+       else if((threadState & IL_TS_SUSPENDED) != 0)
        {
                /* Nothing to do here - it is already suspended */
        }
-       else if((state & (IL_TS_UNSTARTED | IL_TS_STOPPED)) != 0)
+       else if((threadState & (IL_TS_UNSTARTED | IL_TS_STOPPED)) != 0)
        {
                /* We cannot suspend a thread that was never started
                   in the first place, or is stopped */
                result = IL_SUSPEND_FAILED;
        }
-       else if(((state & IL_TS_WAIT_SLEEP_JOIN) != 0) || requestOnly)
+       else if(((threadState & IL_TS_WAIT_SLEEP_JOIN) != 0) || requestOnly)
        {
                /* Request a suspend, but otherwise ignore the request */
-               thread->state |= IL_TS_SUSPEND_REQUESTED;
+               threadState |= IL_TS_SUSPEND_REQUESTED;
+               thread->state = threadState;
 
                result = IL_SUSPEND_REQUESTED;
        }
        else if(_ILThreadIsSelf(thread))
        {
                /* Mark the thread as suspended */
-               thread->state &= ~ IL_TS_SUSPEND_REQUESTED;
-               thread->state |= IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF;
+               threadState &= ~ IL_TS_SUSPEND_REQUESTED;
+               threadState |= IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF;
+               thread->state = threadState;
                thread->resumeRequested = 0;
-               
+
                /* Unlock the thread object prior to suspending */
                _ILMutexUnlock(&(thread->lock));
 
@@ -507,7 +524,8 @@ int ILThreadSuspendRequest(ILThread *thread, int 
requestOnly)
        else
        {
                /* Mark the thread as suspended and waiting for a resume */
-               thread->state |= IL_TS_SUSPENDED;
+               threadState |= IL_TS_SUSPENDED;
+               thread->state = threadState;
                thread->resumeRequested = 0;
 
                /* Put the thread to sleep temporarily */
@@ -544,34 +562,37 @@ int ILThreadSuspendRequest(ILThread *thread, int 
requestOnly)
 
 void ILThreadResume(ILThread *thread)
 {
-       unsigned int state;
+       ILUInt16 threadState;
 
        /* Lock down the thread object */
        _ILMutexLock(&(thread->lock));
 
        /* Determine what to do based on the thread's state */
-       state = thread->state;
-       if((state & IL_TS_SUSPENDED) != 0)
+       threadState = thread->state;
+       if((threadState & IL_TS_SUSPENDED) != 0)
        {
-               if((state & IL_TS_SUSPENDED_SELF) != 0)
+               if((threadState & IL_TS_SUSPENDED_SELF) != 0)
                {
                        /* The thread put itself to sleep */
-                       thread->state &= ~(IL_TS_SUSPENDED | 
IL_TS_SUSPENDED_SELF);
-                       thread->state |= IL_TS_RUNNING;
+                       threadState &= ~(IL_TS_SUSPENDED | 
IL_TS_SUSPENDED_SELF);
+                       threadState |= IL_TS_RUNNING;
+                       thread->state = threadState;
                        _ILThreadResumeSelf(thread);
                }
                else
                {
                        /* Someone else suspended the thread */
-                       thread->state &= ~IL_TS_SUSPENDED;
-                       thread->state |= IL_TS_RUNNING;                 
+                       threadState &= ~IL_TS_SUSPENDED;
+                       threadState |= IL_TS_RUNNING;
+                       thread->state = threadState;
                        _ILThreadResumeOther(thread);
                }
        }
-       else if((state & IL_TS_SUSPEND_REQUESTED) != 0)
+       else if((threadState & IL_TS_SUSPEND_REQUESTED) != 0)
        {
                /* A suspend was requested, but it hadn't started yet */
-               thread->state &= ~IL_TS_SUSPEND_REQUESTED;
+               threadState &= ~IL_TS_SUSPEND_REQUESTED;
+               thread->state = threadState;
        }
 
        /* Unlock the thread object */
@@ -580,14 +601,18 @@ void ILThreadResume(ILThread *thread)
 
 void ILThreadInterrupt(ILThread *thread)
 {
+       ILUInt16 threadState;
+
        /* Lock down the thread object */
        _ILMutexLock(&(thread->lock));
 
        /* Determine what to do based on the thread's state */
-       if((thread->state & IL_TS_STOPPED) == 0)
+       threadState = thread->state;
+       if((threadState & IL_TS_STOPPED) == 0)
        {
                /* Mark the thread as interrupted */
-               thread->state |= IL_TS_INTERRUPTED;
+               threadState |= IL_TS_INTERRUPTED;
+               thread->state = threadState;
 
                /* Unlock the thread object: we never hold the thread
                   lock when updating the thread's wakeup object */
@@ -607,21 +632,24 @@ void ILThreadInterrupt(ILThread *thread)
 int ILThreadSelfAborting()
 {
        int result;
+       ILUInt16 threadState;
        ILThread *thread = _ILThreadGetSelf();
        
        _ILMutexLock(&(thread->lock));
        
        /* Determine if we've already seen the abort request or not */
-       if((thread->state & IL_TS_ABORTED) != 0)
+       threadState = thread->state;
+       if((threadState & IL_TS_ABORTED) != 0)
        {
                /* Already aborted */
                result = 0;
        }
-       else if((thread->state & IL_TS_ABORT_REQUESTED) != 0)
+       else if((threadState & IL_TS_ABORT_REQUESTED) != 0)
        {
                /* Abort was requested */
-               thread->state &= ~IL_TS_ABORT_REQUESTED;
-               thread->state |= IL_TS_ABORTED;
+               threadState &= ~IL_TS_ABORT_REQUESTED;
+               threadState |= IL_TS_ABORTED;
+               thread->state = threadState;
                result = 1;
        }
        else
@@ -648,11 +676,14 @@ void ILThreadSigAbort(ILThread *thread)
 int ILThreadAbort(ILThread *thread)
 {
        int result;
+       ILUInt16 threadState;
 
        /* Lock down the thread object */
        _ILMutexLock(&(thread->lock));
 
-       if((thread->state & (IL_TS_ABORTED | IL_TS_ABORT_REQUESTED)) != 0)
+       threadState = thread->state;
+
+       if((threadState & (IL_TS_ABORTED | IL_TS_ABORT_REQUESTED)) != 0)
        {
                /* The thread is already processing an abort or an abort 
request */
                result = 0;
@@ -660,19 +691,25 @@ int ILThreadAbort(ILThread *thread)
        else
        {
                /* Mark the thread as needing to be aborted */
-               thread->state |= IL_TS_ABORT_REQUESTED;
+               threadState |= IL_TS_ABORT_REQUESTED;
 
                /* If the thread is in the "wait/sleep/join" state, then 
interrupt it */
-               if((thread->state & IL_TS_WAIT_SLEEP_JOIN) != 0)
+               if((threadState & IL_TS_WAIT_SLEEP_JOIN) != 0)
                {
-                       _ILWakeupInterrupt(&(thread->wakeup));
+                       thread->state = threadState;
 
+                       /* Unlock the thread object: we never hold the thread
+                          lock when updating the thread's wakeup object */
                        _ILMutexUnlock(&(thread->lock));
 
+                       _ILWakeupInterrupt(&(thread->wakeup));
+
                        return 0;
                }
-               else if (((thread->state & (IL_TS_SUSPENDED_SELF | 
IL_TS_SUSPENDED))) != 0)
+               else if (((threadState & (IL_TS_SUSPENDED_SELF | 
IL_TS_SUSPENDED))) != 0)
                {
+                       thread->state = threadState;
+
                        _ILMutexUnlock(&(thread->lock));
 
                        ILThreadResume(thread);
@@ -725,15 +762,19 @@ int ILThreadAbortReset(void)
 {
        ILThread *thread = _ILThreadGetSelf();
        int result;
+       ILUInt16 threadState;
 
        /* Lock down the thread object */
        _ILMutexLock(&(thread->lock));
 
+       threadState = thread->state;
+
        /* Reset the "abort" and "abort requested" flags */
-       if((thread->state & (IL_TS_ABORTED | IL_TS_ABORT_REQUESTED)) != 0)
+       if((threadState & (IL_TS_ABORTED | IL_TS_ABORT_REQUESTED)) != 0)
        {
-               thread->state &= ~(IL_TS_ABORTED | IL_TS_ABORT_REQUESTED);
-               thread->state &= ~(IL_TS_INTERRUPTED);
+               threadState &= ~(IL_TS_ABORTED | IL_TS_ABORT_REQUESTED);
+               threadState &= ~(IL_TS_INTERRUPTED);
+               thread->state = threadState;
 
                _ILWakeupCancelInterrupt(&thread->wakeup);
 
@@ -753,6 +794,7 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
 {
        ILThread *self = _ILThreadGetSelf();
        int result;
+       ILUInt16 threadState;
 
        /* Bail out if we are trying to join with ourselves */
        if(self == thread)
@@ -763,13 +805,15 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
        /* Lock down the thread object */
        _ILMutexLock(&(thread->lock));
 
+       threadState = thread->state;
+
        /* Determine what to do based on the thread's state */
-       if((thread->state & IL_TS_STOPPED) != 0)
+       if((threadState & IL_TS_STOPPED) != 0)
        {
                /* The thread is already stopped, so return immediately */
                result = IL_JOIN_OK;
        }
-       else if ((thread->state & IL_TS_UNSTARTED) != 0)
+       else if ((threadState & IL_TS_UNSTARTED) != 0)
        {
                /* Can't join a thread that hasn't started */
                result = IL_JOIN_UNSTARTED;
@@ -797,12 +841,15 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
                        }
                        else
                        {
+                               ILUInt16 selfState;
+
                                /* Unlock the foreign thread */
                                _ILMutexUnlock(&(thread->lock));
 
                                /* Put ourselves into the "wait/sleep/join" 
state */
                                _ILMutexLock(&(self->lock));
-                               if((self->state & (IL_TS_ABORT_REQUESTED)) != 0)
+                               selfState = self->state;
+                               if((selfState & (IL_TS_ABORT_REQUESTED)) != 0)
                                {
                                        /* The current thread is aborted */
                                        _ILMutexUnlock(&(self->lock));
@@ -811,7 +858,8 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
                                        _ILMutexUnlock(&(thread->lock));
                                        return IL_JOIN_ABORTED;
                                }
-                               self->state |= IL_TS_WAIT_SLEEP_JOIN;
+                               selfState |= IL_TS_WAIT_SLEEP_JOIN;
+                               self->state = selfState;
                                _ILMutexUnlock(&(self->lock));
 
                                result = _ILWakeupWait(&(self->wakeup), ms, 
(void **)0);
@@ -835,25 +883,29 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
                                /* Remove ourselves from the "wait/sleep/join" 
state,
                                and check for a pending interrupt */
                                _ILMutexLock(&(self->lock));
-                               if((self->state & IL_TS_INTERRUPTED) != 0)
+
+                               selfState = self->state;
+                               if((selfState & IL_TS_INTERRUPTED) != 0)
                                {
                                        result = IL_JOIN_INTERRUPTED;
                                }
-                               self->state &= ~(IL_TS_WAIT_SLEEP_JOIN | 
IL_TS_INTERRUPTED);
-                               
+                               selfState &= ~(IL_TS_WAIT_SLEEP_JOIN | 
IL_TS_INTERRUPTED);
+                               self->state = selfState;
                                /* Check and process any pending suspend 
request */
                                if ((thread->state & IL_TS_SUSPEND_REQUESTED) 
!= 0)
                                {
-                                       thread->state &= 
~IL_TS_SUSPEND_REQUESTED;
-                                       thread->state |= IL_TS_SUSPENDED | 
IL_TS_SUSPENDED_SELF;
-                                       thread->resumeRequested = 0;
-
                                        /* Unlock the thread object prior to 
suspending */
                                        _ILMutexUnlock(&(self->lock));
 
                                        /* Lock down the foreign thread again */
                                        _ILMutexLock(&(thread->lock));
 
+                                       threadState = thread->state;
+                                       threadState &= ~IL_TS_SUSPEND_REQUESTED;
+                                       threadState |= IL_TS_SUSPENDED | 
IL_TS_SUSPENDED_SELF;
+                                       thread->state = threadState;
+                                       thread->resumeRequested = 0;
+
                                        /* Remove ourselves from the foreign 
thread's join queue */
                                        
_ILWakeupQueueRemove(&(thread->joinQueue), &(self->wakeup));
 
@@ -897,18 +949,22 @@ int ILThreadGetBackground(ILThread *thread)
 void ILThreadSetBackground(ILThread *thread, int flag)
 {
        int change = 0;
+       ILUInt16 threadState;
 
        /* Lock down the thread object */
        _ILMutexLock(&(thread->lock));
 
+       threadState = thread->state;
+
        /* Change the background state of the thread */
        if(flag)
        {
-               if(!(thread->state & IL_TS_BACKGROUND))
+               if(!(threadState & IL_TS_BACKGROUND))
                {
-                       thread->state |= IL_TS_BACKGROUND;
-                       
-                       if(!(thread->state & (IL_TS_UNSTARTED | IL_TS_STOPPED)))
+                       threadState |= IL_TS_BACKGROUND;
+                       thread->state = threadState;
+
+                       if(!(threadState & (IL_TS_UNSTARTED | IL_TS_STOPPED)))
                        {
                                _ILThreadAdjustCount(0, 1);
                        }
@@ -916,12 +972,13 @@ void ILThreadSetBackground(ILThread *thread, int flag)
        }
        else
        {
-               if((thread->state & IL_TS_BACKGROUND))
+               if((threadState & IL_TS_BACKGROUND))
                {
-                       thread->state &= ~IL_TS_BACKGROUND;
+                       threadState &= ~IL_TS_BACKGROUND;
+                       thread->state = threadState;
                        change = -1;
 
-                       if(!(thread->state & (IL_TS_UNSTARTED | IL_TS_STOPPED)))
+                       if(!(threadState & (IL_TS_UNSTARTED | IL_TS_STOPPED)))
                        {
                                _ILThreadAdjustCount(0, -1);
                        }
@@ -982,29 +1039,33 @@ int ILThreadSleep(ILUInt32 ms)
 {
        ILThread *thread = _ILThreadGetSelf();
        int result;
+       ILUInt16 threadState;
 
        /* Lock down the thread */
        _ILMutexLock(&(thread->lock));
 
-       /* Bail out if the current thread is aborted or interrupted */
+       threadState = thread->state;
 
-       if (thread->state & (IL_TS_ABORT_REQUESTED))
+       /* Bail out if the current thread is aborted or interrupted */
+       if(threadState & (IL_TS_ABORT_REQUESTED))
        {
                _ILMutexUnlock(&(thread->lock));
                
                return IL_WAIT_ABORTED;
        }
-       else if (thread->state & IL_TS_INTERRUPTED)
+       else if (threadState & IL_TS_INTERRUPTED)
        {
-               thread->state &= ~(IL_TS_INTERRUPTED);
-               
+               threadState &= ~(IL_TS_INTERRUPTED);
+               thread->state = threadState;
+
                _ILMutexUnlock(&(thread->lock));
 
                return IL_WAIT_INTERRUPTED;
        }
 
        /* Put the thread into the "wait/sleep/join" state */
-       thread->state |= IL_TS_WAIT_SLEEP_JOIN;
+       threadState |= IL_TS_WAIT_SLEEP_JOIN;
+       thread->state = threadState;
 
        /* Unlock the thread to allow others to access it */
        _ILMutexUnlock(&(thread->lock));
@@ -1029,24 +1090,26 @@ int ILThreadSleep(ILUInt32 ms)
        /* Lock down the thread again */
        _ILMutexLock(&(thread->lock));
 
-       if (thread->state & (IL_TS_ABORT_REQUESTED))
+       threadState = thread->state;
+       if(threadState & (IL_TS_ABORT_REQUESTED))
        {
                result = IL_WAIT_ABORTED;
        }
-       else if (thread->state & IL_TS_INTERRUPTED)
+       else if(threadState & IL_TS_INTERRUPTED)
        {
                result = IL_WAIT_INTERRUPTED;
        }
 
        /* Exit from the "wait/sleep/join" and "interrupted" states */
-       thread->state &= ~(IL_TS_WAIT_SLEEP_JOIN | IL_TS_INTERRUPTED);
+       threadState &= ~(IL_TS_WAIT_SLEEP_JOIN | IL_TS_INTERRUPTED);
 
        /* Did someone else ask us to suspend? */
-       if((thread->state & IL_TS_SUSPEND_REQUESTED) != 0)
+       if((threadState & IL_TS_SUSPEND_REQUESTED) != 0)
        {
                /* Suspend the current thread */
-               thread->state &= ~IL_TS_SUSPEND_REQUESTED;
-               thread->state |= IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF;
+               threadState &= ~IL_TS_SUSPEND_REQUESTED;
+               threadState |= IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF;
+               thread->state = threadState;
                thread->resumeRequested = 0;
 
                /* Unlock the thread object prior to suspending */
@@ -1059,6 +1122,8 @@ int ILThreadSleep(ILUInt32 ms)
                return result;
        }
 
+       thread->state = threadState;
+
        /* Unlock the thread and exit */
        _ILMutexUnlock(&(thread->lock));
        return result;
diff --git a/support/wait.c b/support/wait.c
index de54638..49bb4ab 100644
--- a/support/wait.c
+++ b/support/wait.c
@@ -34,7 +34,7 @@ extern        "C" {
 
 int ILWaitHandleClose(ILWaitHandle *handle)
 {
-       int result = (*(handle->closeFunc))(handle);
+       int result = (*_ILWaitHandle_closeFunc(handle))(handle);
        if(result == IL_WAITCLOSE_FREE)
        {
                ILFree(handle);
@@ -44,24 +44,28 @@ int ILWaitHandleClose(ILWaitHandle *handle)
 
 /*
  * Enter the "wait/sleep/join" state on the current thread.
+ * NOTE: _ILWakeupCancelInterrupt doesn't read or change the thread's state.
  */
 int _ILEnterWait(ILThread *thread)
 {
        int result = 0;
+       ILUInt16 threadState;
 
        _ILMutexLock(&(thread->lock));
 
-       if((thread->state & (IL_TS_ABORT_REQUESTED)) != 0)
+       threadState = thread->state;
+       if((threadState & (IL_TS_ABORT_REQUESTED)) != 0)
        {
                result = IL_WAIT_ABORTED;
 
                _ILWakeupCancelInterrupt(&(thread->wakeup));
-               thread->state &= ~(IL_TS_INTERRUPTED);
+               threadState &= ~(IL_TS_INTERRUPTED);
        }
        else
        {
-               thread->state |= IL_TS_WAIT_SLEEP_JOIN;
+               threadState |= IL_TS_WAIT_SLEEP_JOIN;
        }
+       thread->state = threadState;
 
        _ILMutexUnlock(&(thread->lock));
 
@@ -70,9 +74,12 @@ int _ILEnterWait(ILThread *thread)
 
 /*
  * Leave the "wait/sleep/join" state on the current thread.
+ * NOTE: _ILWakeupCancelInterrupt doesn't read or change the thread's state.
  */
 int _ILLeaveWait(ILThread *thread, int result)
 {
+       ILUInt16 threadState;
+
        _ILMutexLock(&(thread->lock));
 
        /* The double checks for result == IL_WAIT_* are needed to bubble down
@@ -80,12 +87,13 @@ int _ILLeaveWait(ILThread *thread, int result)
           if enter/leavewait are called recursively */
 
        /* Abort has more priority over interrupt */
-       if((thread->state & (IL_TS_ABORT_REQUESTED)) != 0
+       threadState = thread->state;
+       if((threadState & (IL_TS_ABORT_REQUESTED)) != 0
                || result == IL_WAIT_ABORTED)
        {
                result = IL_WAIT_ABORTED;
        }
-       else if((thread->state & IL_TS_INTERRUPTED) != 0
+       else if((threadState & IL_TS_INTERRUPTED) != 0
                || result == IL_WAIT_INTERRUPTED)
        {                
                result = IL_WAIT_INTERRUPTED;
@@ -93,13 +101,15 @@ int _ILLeaveWait(ILThread *thread, int result)
 
        _ILWakeupCancelInterrupt(&(thread->wakeup));
        
-       if ((thread->state & IL_TS_SUSPEND_REQUESTED) != 0)
+       if ((threadState & IL_TS_SUSPEND_REQUESTED) != 0)
        {
-               thread->state &= ~IL_TS_SUSPEND_REQUESTED;
-               thread->state |= IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF;
+               threadState &= ~IL_TS_SUSPEND_REQUESTED;
+               threadState |= IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF;
                thread->resumeRequested = 0;
 
-               thread->state &= ~(IL_TS_INTERRUPTED);
+               threadState &= ~(IL_TS_INTERRUPTED);
+
+               thread->state = threadState;
 
                /* Unlock the thread object prior to suspending */
                _ILMutexUnlock(&(thread->lock));
@@ -107,16 +117,16 @@ int _ILLeaveWait(ILThread *thread, int result)
                /* Suspend until we receive notification from another thread */
                _ILThreadSuspendSelf(thread);
 
-               _ILMutexLock(&(thread->lock));          
-               thread->state &= ~(IL_TS_WAIT_SLEEP_JOIN | IL_TS_INTERRUPTED);
-               _ILMutexUnlock(&(thread->lock));
-       }
-       else
-       {       
-               thread->state &= ~(IL_TS_WAIT_SLEEP_JOIN | IL_TS_INTERRUPTED);
+               /* And relock for changing the state */
+               _ILMutexLock(&(thread->lock));
 
-               _ILMutexUnlock(&(thread->lock));
+               threadState = thread->state;
        }
+       threadState &= ~(IL_TS_WAIT_SLEEP_JOIN | IL_TS_INTERRUPTED);
+
+       thread->state = threadState;
+
+       _ILMutexUnlock(&(thread->lock));
 
        return result;
 }
@@ -132,7 +142,7 @@ static int _ILLeaveWaitHandle(ILThread *thread, 
ILWaitHandle *handle, int ok)
        int result = _ILLeaveWait(thread, 0);
        if(result != 0)
        {
-               (*(handle->unregisterFunc))(handle, &(thread->wakeup), 1);
+               (*_ILWaitHandle_unregisterFunc(handle))(handle, 
&(thread->wakeup), 1);
                return result;
        }
        else
@@ -154,7 +164,7 @@ int ILSignalAndWait(ILWaitHandle *signalHandle, 
ILWaitHandle *waitHandle, ILUInt
                return result;
        }
 
-       if (signalHandle->signalFunc == 0)
+       if (_ILWaitHandle_signalFunc(signalHandle) == 0)
        {
                return IL_WAIT_FAILED;
        }
@@ -166,9 +176,9 @@ int ILSignalAndWait(ILWaitHandle *signalHandle, 
ILWaitHandle *waitHandle, ILUInt
        }
 
        /* Register this thread with the handle */
-       result = (*(waitHandle->registerFunc))(waitHandle, wakeup);
+       result = (*_ILWaitHandle_registerFunc(waitHandle))(waitHandle, wakeup);
                
-       signalHandle->signalFunc(signalHandle);
+       _ILWaitHandle_signalFunc(signalHandle)(signalHandle);
        
        if(result == IL_WAITREG_ACQUIRED)
        {
@@ -187,7 +197,7 @@ int ILSignalAndWait(ILWaitHandle *signalHandle, 
ILWaitHandle *waitHandle, ILUInt
        result = _ILWakeupWait(wakeup, timeout, 0);
 
        /* Unregister the thread from the wait handle */
-       (*(waitHandle->unregisterFunc))(waitHandle, wakeup, (result <= 0));
+       (*_ILWaitHandle_unregisterFunc(waitHandle))(waitHandle, wakeup, (result 
<= 0));
 
        /* Tell the caller what happened */
        if(result > 0)
@@ -226,7 +236,7 @@ int ILWaitOne(ILWaitHandle *handle, ILUInt32 timeout)
        }
 
        /* Register this thread with the handle */
-       result = (*(handle->registerFunc))(handle, wakeup);
+       result = (*_ILWaitHandle_registerFunc(handle))(handle, wakeup);
 
        if(result == IL_WAITREG_ACQUIRED)
        {
@@ -245,7 +255,7 @@ int ILWaitOne(ILWaitHandle *handle, ILUInt32 timeout)
        result = _ILWakeupWait(wakeup, timeout, 0);
 
        /* Unregister the thread from the wait handle */
-       (*(handle->unregisterFunc))(handle, wakeup, (result <= 0));
+       (*_ILWaitHandle_unregisterFunc(handle))(handle, wakeup, (result <= 0));
 
        /* Tell the caller what happened */
        if(result > 0)
@@ -290,7 +300,7 @@ int ILWaitAny(ILWaitHandle **handles, ILUInt32 numHandles, 
ILUInt32 timeout)
        for(index = 0; index < numHandles; ++index)
        {
                handle = handles[index];
-               result = (*(handle->registerFunc))(handle, wakeup);
+               result = (*_ILWaitHandle_registerFunc(handle))(handle, wakeup);
                if(result == IL_WAITREG_ACQUIRED)
                {
                        /* We were able to acquire this wait handle immediately 
*/
@@ -300,7 +310,7 @@ int ILWaitAny(ILWaitHandle **handles, ILUInt32 numHandles, 
ILUInt32 timeout)
                        for(index2 = 0; index2 < index; ++index2)
                        {
                                handle = handles[index2];
-                               (*(handle->unregisterFunc))(handle, wakeup, 1);
+                               (*_ILWaitHandle_unregisterFunc(handle))(handle, 
wakeup, 1);
                        }
                        return _ILLeaveWaitHandle(thread, handles[index], 
index);
                }
@@ -313,7 +323,7 @@ int ILWaitAny(ILWaitHandle **handles, ILUInt32 numHandles, 
ILUInt32 timeout)
                        for(index2 = 0; index2 < index; ++index2)
                        {
                                handle = handles[index2];
-                               (*(handle->unregisterFunc))(handle, wakeup, 1);
+                               (*_ILWaitHandle_unregisterFunc(handle))(handle, 
wakeup, 1);
                        }
                        return _ILLeaveWait(thread, IL_WAIT_FAILED);
                }
@@ -331,11 +341,11 @@ int ILWaitAny(ILWaitHandle **handles, ILUInt32 
numHandles, ILUInt32 timeout)
                if(handle == resultHandle && result > 0)
                {
                        index2 = index;
-                       (*(handle->unregisterFunc))(handle, wakeup, 0);
+                       (*_ILWaitHandle_unregisterFunc(handle))(handle, wakeup, 
0);
                }
                else
                {
-                       (*(handle->unregisterFunc))(handle, wakeup, 1);
+                       (*_ILWaitHandle_unregisterFunc(handle))(handle, wakeup, 
1);
                }
        }
 
@@ -385,7 +395,7 @@ int ILWaitAll(ILWaitHandle **handles, ILUInt32 numHandles, 
ILUInt32 timeout)
        for(index = 0; index < numHandles; ++index)
        {
                handle = handles[index];
-               result = (*(handle->registerFunc))(handle, wakeup);
+               result = (*_ILWaitHandle_registerFunc(handle))(handle, wakeup);
                if(result == IL_WAITREG_ACQUIRED)
                {
                        /* We were able to acquire this wait handle immediately 
*/
@@ -400,7 +410,7 @@ int ILWaitAll(ILWaitHandle **handles, ILUInt32 numHandles, 
ILUInt32 timeout)
                        for(index2 = 0; index2 < index; ++index2)
                        {
                                handle = handles[index2];
-                               (*(handle->unregisterFunc))(handle, wakeup, 1);
+                               (*_ILWaitHandle_unregisterFunc(handle))(handle, 
wakeup, 1);
                        }
                        return _ILLeaveWait(thread, IL_WAIT_FAILED);
                }
@@ -424,7 +434,7 @@ int ILWaitAll(ILWaitHandle **handles, ILUInt32 numHandles, 
ILUInt32 timeout)
        for(index = 0; index < numHandles; ++index)
        {
                handle = handles[index];
-               (*(handle->unregisterFunc))(handle, wakeup, (result <= 0));
+               (*_ILWaitHandle_unregisterFunc(handle))(handle, wakeup, (result 
<= 0));
        }
 
        /* Tell the caller what happened */
@@ -442,7 +452,7 @@ int ILWaitAll(ILWaitHandle **handles, ILUInt32 numHandles, 
ILUInt32 timeout)
                        for(index = 0; index < numHandles; ++index)
                        {
                                handle = handles[index];
-                               (*(handle->unregisterFunc))(handle, wakeup, 1);
+                               (*_ILWaitHandle_unregisterFunc(handle))(handle, 
wakeup, 1);
                        }
                        return result;
                }
@@ -467,10 +477,13 @@ int ILWaitAll(ILWaitHandle **handles, ILUInt32 
numHandles, ILUInt32 timeout)
 int _ILWaitOneBackupInterruptsAndAborts(ILWaitHandle *handle, int timeout)
 {      
        ILThread *thread = _ILThreadGetSelf();
-       int result, retval = 0, threadstate = 0;
+       int result, retval = 0;
+       ILUInt16 threadstate = 0;
        
        for (;;)
        {
+               ILUInt16 newThreadstate;
+
                /* Wait to re-acquire the monitor (add ourselves to the "ready 
queue") */
                result = ILWaitOne(handle, timeout);
                
@@ -480,22 +493,25 @@ int _ILWaitOneBackupInterruptsAndAborts(ILWaitHandle 
*handle, int timeout)
                                and keep trying to reaquire the monitor */
                        
                        _ILMutexLock(&thread->lock);
-                       
-                       threadstate |= thread->state;
+
+                       newThreadstate = thread->state;
+                       threadstate |= newThreadstate;
                        
                        if (result == IL_WAIT_INTERRUPTED)
                        {
-                               /* Interrupted is cleared by ILWaitOne so save 
it manually */                                   
+                               /* Interrupted is cleared by ILWaitOne so save 
it manually */
                                threadstate |= IL_TS_INTERRUPTED;
                        }
                        
-                       thread->state &= ~(IL_TS_ABORT_REQUESTED | 
IL_TS_INTERRUPTED);
+                       newThreadstate &= 
~(IL_TS_INTERRUPTED_OR_ABORT_REQUESTED);
 
                        if (result < retval)
                        {
                                retval = result;
                        }
-                       
+
+                       thread->state = newThreadstate;
+
                        _ILMutexUnlock(&thread->lock);
                        
                        continue;
diff --git a/support/wait_event.c b/support/wait_event.c
index 25c9c37..86d04bb 100644
--- a/support/wait_event.c
+++ b/support/wait_event.c
@@ -104,6 +104,18 @@ static int EventSignal(ILWaitHandle *waitHandle)
 }
 
 /*
+ * The WaitHandleVtable for events
+ */
+static const _ILWaitHandleVtable _ILWaitEventVtable =
+{
+       IL_WAIT_EVENT,
+       (ILWaitCloseFunc)EventClose,
+       (ILWaitRegisterFunc)EventRegister,
+       (ILWaitUnregisterFunc)EventUnregister,
+       (ILWaitSignalFunc)EventSignal
+};
+
+/*
  * Creates and returns a new wait event.
  *
  * @param manualReset  If false (0), the event automatically resets itself
@@ -125,11 +137,7 @@ ILWaitHandle *ILWaitEventCreate(int manualReset, int 
initialState)
        _ILMutexCreate(&(event->parent.lock));
 
        /* setup event callbacks */
-       event->parent.kind = IL_WAIT_EVENT;
-       event->parent.closeFunc = (ILWaitCloseFunc)EventClose;  
-       event->parent.registerFunc = (ILWaitRegisterFunc)EventRegister;
-       event->parent.unregisterFunc = (ILWaitUnregisterFunc)EventUnregister;
-       event->parent.signalFunc = (ILWaitSignalFunc)EventSignal;
+       event->parent.vtable = &_ILWaitEventVtable;
 
        _ILWakeupQueueCreate(&(event->queue));
 
diff --git a/support/wait_mutex.c b/support/wait_mutex.c
index b3e0984..4fa460f 100644
--- a/support/wait_mutex.c
+++ b/support/wait_mutex.c
@@ -328,8 +328,8 @@ static int MutexRegister(ILWaitMutex *mutex, _ILWakeup 
*wakeup)
 
                result = IL_WAITREG_ACQUIRED;
 
-               if (mutex->parent.kind == IL_WAIT_MUTEX
-                       || mutex->parent.kind == IL_WAIT_NAMED_MUTEX)
+               if (_ILWaitHandle_kind(&(mutex->parent)) == IL_WAIT_MUTEX
+                       || _ILWaitHandle_kind(&(mutex->parent)) == 
IL_WAIT_NAMED_MUTEX)
                {
                        /* Newly aquired mutex so add it to the wakeup's owned 
mutex list */
 
@@ -376,8 +376,8 @@ static void MutexUnregister(ILWaitMutex *mutex, _ILWakeup 
*wakeup, int release)
        {
                if(--(mutex->count) == 0)
                {
-                       if (mutex->parent.kind == IL_WAIT_MUTEX
-                               || mutex->parent.kind == IL_WAIT_NAMED_MUTEX)
+                       if (_ILWaitHandle_kind(&(mutex->parent)) == 
IL_WAIT_MUTEX
+                               || _ILWaitHandle_kind(&(mutex->parent)) == 
IL_WAIT_NAMED_MUTEX)
                        {
                                RemoveMutexFromWakeup(mutex, wakeup);
                        }
@@ -392,8 +392,8 @@ static void MutexUnregister(ILWaitMutex *mutex, _ILWakeup 
*wakeup, int release)
        }
        else if (mutex->owner == wakeup && mutex->count == 1)
        {
-               if (mutex->parent.kind == IL_WAIT_MUTEX
-                       || mutex->parent.kind == IL_WAIT_NAMED_MUTEX)
+               if (_ILWaitHandle_kind(&(mutex->parent)) == IL_WAIT_MUTEX
+                       || _ILWaitHandle_kind(&(mutex->parent)) == 
IL_WAIT_NAMED_MUTEX)
                {
                        /* Newly aquired mutex so add it to the wakeup's owned 
mutex list */
                        AddMutexToWakeup(mutex, wakeup);                
@@ -409,6 +409,30 @@ static int MutexSignal(ILWaitHandle *waitHandle)
        return ILWaitMutexRelease(waitHandle) > 0;
 }
 
+/*
+ * The WaitHandleVtable for mutexes
+ */
+static const _ILWaitHandleVtable _ILWaitMutexVtable =
+{
+       IL_WAIT_MUTEX,
+       (ILWaitCloseFunc)MutexClose,
+       (ILWaitRegisterFunc)MutexRegister,
+       (ILWaitUnregisterFunc)MutexUnregister,
+       (ILWaitSignalFunc)MutexSignal
+};
+
+/*
+ * The WaitHandleVtable for named mutexes
+ */
+static const _ILWaitHandleVtable _ILWaitMutexNamedVtable =
+{
+       IL_WAIT_NAMED_MUTEX,
+       (ILWaitCloseFunc)MutexCloseNamed,
+       (ILWaitRegisterFunc)MutexRegister,
+       (ILWaitUnregisterFunc)MutexUnregister,
+       (ILWaitSignalFunc)MutexSignal
+};
+
 ILWaitHandle *ILWaitMutexCreate(int initiallyOwned)
 {
        ILWaitMutex *mutex;
@@ -420,12 +444,8 @@ ILWaitHandle *ILWaitMutexCreate(int initiallyOwned)
        }
 
        /* Initialize the mutex */
+       mutex->parent.vtable = &_ILWaitMutexVtable;
        _ILMutexCreate(&(mutex->parent.lock));
-       mutex->parent.kind = IL_WAIT_MUTEX;
-       mutex->parent.closeFunc = (ILWaitCloseFunc)MutexClose;
-       mutex->parent.registerFunc = (ILWaitRegisterFunc)MutexRegister;
-       mutex->parent.unregisterFunc = (ILWaitUnregisterFunc)MutexUnregister;
-       mutex->parent.signalFunc = MutexSignal;
 
        if(initiallyOwned)
        {
@@ -527,12 +547,8 @@ ILWaitHandle *ILWaitMutexNamedCreate(const char *name, int 
initiallyOwned,
        }
 
        /* Initialize the mutex */
+       mutex->parent.parent.vtable = &_ILWaitMutexNamedVtable;
        _ILMutexCreate(&(mutex->parent.parent.lock));
-       mutex->parent.parent.kind = IL_WAIT_NAMED_MUTEX;
-       mutex->parent.parent.closeFunc = (ILWaitCloseFunc)MutexCloseNamed;
-       mutex->parent.parent.registerFunc = (ILWaitRegisterFunc)MutexRegister;
-       mutex->parent.parent.unregisterFunc = 
(ILWaitUnregisterFunc)MutexUnregister;
-       mutex->parent.parent.signalFunc = MutexSignal;
        if(initiallyOwned)
        {
                mutex->parent.owner = &((_ILThreadGetSelf())->wakeup);
@@ -574,7 +590,7 @@ int ILWaitMutexRelease(ILWaitHandle *handle)
        wakeup = &_ILThreadGetSelf()->wakeup;
 
        /* Determine what to do based on the mutex's state */
-       if((mutex->parent.kind & IL_WAIT_MUTEX) == 0)
+       if((_ILWaitHandle_kind(&(mutex->parent)) & IL_WAIT_MUTEX) == 0)
        {
                /* This isn't actually a mutex */
                result = IL_WAITMUTEX_RELEASE_FAIL;
@@ -589,8 +605,8 @@ int ILWaitMutexRelease(ILWaitHandle *handle)
                /* The count has returned to zero, so find something
                   else to give the ownership of the mutex to */
 
-               if (mutex->parent.kind == IL_WAIT_MUTEX
-                       || mutex->parent.kind == IL_WAIT_NAMED_MUTEX)
+               if (_ILWaitHandle_kind(&(mutex->parent)) == IL_WAIT_MUTEX
+                       || _ILWaitHandle_kind(&(mutex->parent)) == 
IL_WAIT_NAMED_MUTEX)
                {
                        RemoveMutexFromWakeup(mutex, wakeup);
                }
@@ -638,6 +654,18 @@ static int MonitorClose(ILWaitMonitor *monitor)
        return IL_WAITCLOSE_FREE;
 }
 
+/*
+ * The WaitHandleVtable for wait monitors
+ */
+static const _ILWaitHandleVtable _ILWaitMonitorVtable =
+{
+       IL_WAIT_MONITOR,
+       (ILWaitCloseFunc)MonitorClose,
+       (ILWaitRegisterFunc)MutexRegister,
+       (ILWaitUnregisterFunc)MutexUnregister,
+       (ILWaitSignalFunc)MutexSignal
+};
+
 ILWaitHandle *ILWaitMonitorCreate(void)
 {
        ILWaitMonitor *monitor;
@@ -649,13 +677,8 @@ ILWaitHandle *ILWaitMonitorCreate(void)
        }
 
        /* Initialize the monitor fields */
+       monitor->parent.parent.vtable = &_ILWaitMonitorVtable;
        _ILMutexCreate(&(monitor->parent.parent.lock));
-       monitor->parent.parent.kind = IL_WAIT_MONITOR;
-       monitor->parent.parent.closeFunc = (ILWaitCloseFunc)MonitorClose;
-       monitor->parent.parent.registerFunc = (ILWaitRegisterFunc)MutexRegister;
-       monitor->parent.parent.unregisterFunc =
-                       (ILWaitUnregisterFunc)MutexUnregister;
-       monitor->parent.parent.signalFunc = MutexSignal;
        monitor->parent.owner = 0;
        monitor->parent.count = 0;
        monitor->waiters = 0;
@@ -703,7 +726,7 @@ int ILWaitMonitorWait(ILWaitHandle *handle, ILUInt32 
timeout)
        ++monitor->waiters;
 
        /* Determine what to do based on the monitor's state */
-       if(monitor->parent.parent.kind != IL_WAIT_MONITOR)
+       if(_ILWaitHandle_kind(&(monitor->parent.parent)) != IL_WAIT_MONITOR)
        {
                /* This isn't actually a monitor */
                result = 0;
@@ -801,7 +824,7 @@ static IL_INLINE int PrivateWaitMonitorPulse(ILWaitHandle 
*handle, int all)
        _ILMutexLock(&(monitor->parent.parent.lock));
 
        /* Determine what to do based on the monitor's state */
-       if(monitor->parent.parent.kind != IL_WAIT_MONITOR)
+       if(_ILWaitHandle_kind(&(monitor->parent.parent)) != IL_WAIT_MONITOR)
        {
                /* This isn't actually a monitor */
                result = 0;
diff --git a/support/wait_mutex.h b/support/wait_mutex.h
index c11628b..d6219d8 100644
--- a/support/wait_mutex.h
+++ b/support/wait_mutex.h
@@ -57,23 +57,26 @@ static IL_INLINE int ILWaitMutexFastEnter(ILThread *thread, 
ILWaitHandle *handle
         * entered (not just *any* monitor like with MS.NET) is
         * locked.  Currently, PNET uses the first option.
         */
-       if ((thread->state & (IL_TS_ABORT_REQUESTED)) != 0
-               || (thread->state & (IL_TS_INTERRUPTED)) != 0)
+       if ((thread->state & (IL_TS_INTERRUPTED_OR_ABORT_REQUESTED)) != 0)
        {
+               ILUInt16 threadState;
+
                _ILMutexLock(&thread->lock);
 
-               if ((thread->state & (IL_TS_ABORT_REQUESTED)) != 0)
+               threadState = thread->state;
+               if ((threadState & (IL_TS_ABORT_REQUESTED)) != 0)
                {
                        result = IL_WAIT_ABORTED;
                }
-               else if ((thread->state & (IL_TS_INTERRUPTED)) != 0)
+               else if ((threadState & (IL_TS_INTERRUPTED)) != 0)
                {
                        result = IL_WAIT_INTERRUPTED;
                }
                
                _ILWakeupCancelInterrupt(&(thread->wakeup));
-               thread->state &= ~(IL_TS_INTERRUPTED);
-               
+               threadState &= ~(IL_TS_INTERRUPTED);
+               thread->state = threadState;
+
                _ILMutexUnlock(&thread->lock);
        }
 
@@ -99,7 +102,7 @@ static IL_INLINE int ILWaitMutexFastRelease(ILThread 
*thread, ILWaitHandle *hand
        int result;
 
        /* Determine what to do based on the mutex's state */
-       if((mutex->parent.kind & IL_WAIT_MUTEX) == 0)
+       if((_ILWaitHandle_kind(&(mutex->parent)) & IL_WAIT_MUTEX) == 0)
        {
                /* This isn't actually a mutex */
                result = IL_WAITMUTEX_RELEASE_FAIL;

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog            |   31 +++++++
 support/thr_defs.h   |   59 ++++++++++++--
 support/thread.c     |  219 ++++++++++++++++++++++++++++++++------------------
 support/wait.c       |   96 +++++++++++++---------
 support/wait_event.c |   18 +++-
 support/wait_mutex.c |   77 ++++++++++++------
 support/wait_mutex.h |   17 +++--
 7 files changed, 352 insertions(+), 165 deletions(-)


hooks/post-receive
-- 
DotGNU Portable.NET engine, compilers and tools (pnet)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]