Index: /trunk/include/iprt/err.h
===================================================================
--- /trunk/include/iprt/err.h	(revision 25637)
+++ /trunk/include/iprt/err.h	(revision 25638)
@@ -860,4 +860,6 @@
 /** An illegal lock upgrade was attempted. */
 #define VERR_SEM_LV_ILLEGAL_UPGRADE         (-375)
+/** The thread is not a valid signaller of the event. */
+#define VERR_SEM_LV_NOT_SIGNALLER           (-376)
 /** @} */
 
Index: /trunk/include/iprt/lockvalidator.h
===================================================================
--- /trunk/include/iprt/lockvalidator.h	(revision 25637)
+++ /trunk/include/iprt/lockvalidator.h	(revision 25638)
@@ -220,6 +220,8 @@
     /** Whether it's enabled or not. */
     bool                                fEnabled;
+    /** Set if event semaphore signaller, clear if read-write semaphore. */
+    bool                                fSignaller;
     /** Alignment padding. */
-    bool                                afPadding[2];
+    bool                                fPadding;
     /** Pointer to a table containing pointers to records of all the owners. */
     R3R0PTRTYPE(PRTLOCKVALRECSHRDOWN volatile *) papOwners;
@@ -452,8 +454,11 @@
  * @param   fRecursiveOk        Whether it's ok to recurse.
  * @param   enmSleepState       The sleep state to enter on successful return.
+ * @param   fReallySleeping     Is it really going to sleep now or not.  Use
+ *                              false before calls to other IPRT synchronization
+ *                              methods.
  */
 RTDECL(int) RTLockValidatorRecExclCheckBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
                                                 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
-                                                RTTHREADSTATE enmSleepState);
+                                                RTTHREADSTATE enmSleepState, bool fReallySleeping);
 
 /**
@@ -467,8 +472,11 @@
  * @param   fRecursiveOk        Whether it's ok to recurse.
  * @param   enmSleepState       The sleep state to enter on successful return.
+ * @param   fReallySleeping     Is it really going to sleep now or not.  Use
+ *                              false before calls to other IPRT synchronization
+ *                              methods.
  */
 RTDECL(int) RTLockValidatorRecExclCheckOrderAndBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
                                                         PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
-                                                        RTTHREADSTATE enmSleepState);
+                                                        RTTHREADSTATE enmSleepState, bool fReallySleeping);
 
 /**
@@ -485,7 +493,10 @@
  * @param   pszName             The lock name (optional).
  * @param   hLock               The lock handle.
- */
-RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALIDATORCLASS hClass,
-                                          uint32_t uSubClass, const char *pszName, void *hLock);
+ * @param   fSignaller          Set if event semaphore signaller logic should be
+ *                              applied to this record, clear if read-write
+ *                              semaphore logic should be used.
+ */
+RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALIDATORCLASS hClass, uint32_t uSubClass,
+                                          const char *pszName, void *hLock, bool fSignaller);
 /**
  * Uninitialize a lock validator record previously initialized by
@@ -532,8 +543,11 @@
  * @param   fRecursiveOk        Whether it's ok to recurse.
  * @param   enmSleepState       The sleep state to enter on successful return.
+ * @param   fReallySleeping     Is it really going to sleep now or not.  Use
+ *                              false before calls to other IPRT synchronization
+ *                              methods.
  */
 RTDECL(int) RTLockValidatorRecSharedCheckBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
                                                   PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
-                                                  RTTHREADSTATE enmSleepState);
+                                                  RTTHREADSTATE enmSleepState, bool fReallySleeping);
 
 /**
@@ -546,8 +560,22 @@
  * @param   pSrcPos             The source position of the lock operation.
  * @param   fRecursiveOk        Whether it's ok to recurse.
+ * @param   enmSleepState       The sleep state to enter on successful return.
+ * @param   fReallySleeping     Is it really going to sleep now or not.  Use
+ *                              false before calls to other IPRT synchronization
+ *                              methods.
  */
 RTDECL(int) RTLockValidatorRecSharedCheckOrderAndBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
                                                           PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
-                                                          RTTHREADSTATE enmSleepState);
+                                                          RTTHREADSTATE enmSleepState, bool fReallySleeping);
+
+/**
+ * Removes all current owners and makes hThread the only owner.
+ *
+ * @param   pRead               The validator record.
+ * @param   hThread             The thread handle of the owner.  NIL_RTTHREAD is
+ *                              an alias for the current thread.
+ * @param   pSrcPos             The source position of the lock operation.
+ */
+RTDECL(void) RTLockValidatorRecSharedResetOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos);
 
 /**
@@ -558,8 +586,9 @@
  *
  * @param   pRead               The validator record.
- * @param   hThreadSelf         The calling thread and owner.
- * @param   pSrcPos             The source position of the lock operation.
- */
-RTDECL(void) RTLockValidatorSharedRecAddOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf, PCRTLOCKVALSRCPOS pSrcPos);
+ * @param   hThread             The thread handle of the owner.  NIL_RTTHREAD is
+ *                              an alias for the current thread.
+ * @param   pSrcPos             The source position of the lock operation.
+ */
+RTDECL(void) RTLockValidatorRecSharedAddOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos);
 
 /**
@@ -570,7 +599,8 @@
  *
  * @param   pRec                The validator record.
- * @param   hThreadSelf         The calling thread and the owner to remove.
- */
-RTDECL(void) RTLockValidatorSharedRecRemoveOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf);
+ * @param   hThread             The thread handle of the owner.  NIL_RTTHREAD is
+ *                              an alias for the current thread.
+ */
+RTDECL(void) RTLockValidatorRecSharedRemoveOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread);
 
 /**
@@ -584,9 +614,26 @@
  * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
  *
- * @param   pRead               The validator record.
- * @param   hThreadSelf         The handle of the calling thread.  If not known,
- *                              pass NIL_RTTHREAD and we'll figure it out.
+ * @param   pRec                The validator record.
+ * @param   hThreadSelf         The handle of the calling thread.  NIL_RTTHREAD
+ *                              is an alias for the current thread.
  */
 RTDECL(int) RTLockValidatorRecSharedCheckAndRelease(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf);
+
+/**
+ * Check the signaller of an event.
+ *
+ * This is called by routines implementing releasing the event sempahore (both
+ * kinds).
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_SEM_LV_NOT_SIGNALLER if the thread is not in the record.  Will
+ *          have done all necessary whining and breakpointing before returning.
+ * @retval  VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param   pRec                The validator record.
+ * @param   hThreadSelf         The handle of the calling thread.  NIL_RTTHREAD
+ *                              is an alias for the current thread.
+ */
+RTDECL(int) RTLockValidatorRecSharedCheckSignaller(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf);
 
 /**
Index: /trunk/include/iprt/semaphore.h
===================================================================
--- /trunk/include/iprt/semaphore.h	(revision 25637)
+++ /trunk/include/iprt/semaphore.h	(revision 25638)
@@ -109,4 +109,39 @@
  */
 RTDECL(int)  RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies);
+
+/**
+ * Sets the signaller thread to one specific thread.
+ *
+ * This is only used for validating usage and deadlock detection.  When used
+ * after calls to RTSemEventAddSignaller, the specified thread will be the only
+ * signalling thread.
+ *
+ * @param   hEventSem           The event semaphore.
+ * @param   hThread             The thread that will signal it.  Pass
+ *                              NIL_RTTHREAD to indicate that there is no
+ *                              special signalling thread.
+ */
+RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread);
+
+/**
+ * To add more signalling threads.
+ *
+ * First call RTSemEventSetSignaller then add further threads with this.
+ *
+ * @param   hEventSem           The event semaphore.
+ * @param   hThread             The thread that will signal it. NIL_RTTHREAD is
+ *                              not accepted.
+ */
+RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread);
+
+/**
+ * To remove a signalling thread.
+ *
+ * Reverts work done by RTSemEventAddSignaller and RTSemEventSetSignaller.
+ *
+ * @param   hEventSem           The event semaphore.
+ * @param   hThread             A previously added thread.
+ */
+RTDECL(void) RTSemEventRemoverSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread);
 
 /** @} */
Index: /trunk/include/iprt/thread.h
===================================================================
--- /trunk/include/iprt/thread.h	(revision 25637)
+++ /trunk/include/iprt/thread.h	(revision 25638)
@@ -586,9 +586,15 @@
  * @param   hThread         The current thread.
  * @param   enmState        The sleep state.
- */
-RTDECL(void) RTThreadBlocking(RTTHREAD hThread, RTTHREADSTATE enmState);
+ * @param   fReallySleeping Really going to sleep now.  Use false before calls
+ *                          to other IPRT synchronization methods.
+ */
+RTDECL(void) RTThreadBlocking(RTTHREAD hThread, RTTHREADSTATE enmState, bool fReallySleeping);
 
 /**
  * Get the current thread state.
+ *
+ * A thread that is reported as sleeping may actually still be running inside
+ * the lock validator or/and in the code of some other IPRT synchronization
+ * primitive.  Use RTThreadGetReallySleeping
  *
  * @returns The thread state.
@@ -598,4 +604,13 @@
 
 /**
+ * Checks if the thread is really sleeping or not.
+ *
+ * @returns RTTHREADSTATE_RUNNING if not really sleeping, otherwise the state it
+ *          is sleeping in.
+ * @param   hThread         The thread.
+ */
+RTDECL(RTTHREADSTATE) RTThreadGetReallySleeping(RTTHREAD hThread);
+
+/**
  * Translate a thread state into a string.
  *
@@ -604,4 +619,38 @@
  */
 RTDECL(const char *) RTThreadStateName(RTTHREADSTATE enmState);
+
+
+/**
+ * Native thread states returned by RTThreadNativeState.
+ */
+typedef enum RTTHREADNATIVESTATE
+{
+    /** Invalid thread handle. */
+    RTTHREADNATIVESTATE_INVALID = 0,
+    /** Unable to determine the thread state. */
+    RTTHREADNATIVESTATE_UNKNOWN,
+    /** The thread is running. */
+    RTTHREADNATIVESTATE_RUNNING,
+    /** The thread is blocked. */
+    RTTHREADNATIVESTATE_BLOCKED,
+    /** The thread is suspended / stopped. */
+    RTTHREADNATIVESTATE_SUSPENDED,
+    /** The thread has terminated. */
+    RTTHREADNATIVESTATE_TERMINATED,
+    /** Make sure it's a 32-bit type. */
+    RTTHREADNATIVESTATE_32BIT_HACK = 0x7fffffff
+} RTTHREADNATIVESTATE;
+
+
+/**
+ * Get the native state of a thread.
+ *
+ * @returns Native state.
+ * @param   hThread             The thread handle.
+ *
+ * @remarks Not yet implemented on all systems, so have a backup plan for
+ *          RTTHREADNATIVESTATE_UNKNOWN.
+ */
+RTDECL(RTTHREADNATIVESTATE) RTThreadGetNativeState(RTTHREAD hThread);
 
 
Index: /trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/Makefile.kmk	(revision 25637)
+++ /trunk/src/VBox/Runtime/Makefile.kmk	(revision 25638)
@@ -413,4 +413,5 @@
 	generic/uuid-generic.cpp \
 	generic/RTProcIsRunningByName-generic.cpp \
+	generic/RTThreadGetNativeState-generic.cpp \
 	nt/RTErrConvertFromNtStatus.cpp \
 	r3/posix/env-posix.cpp \
@@ -457,4 +458,5 @@
 	generic/utf16locale-generic.cpp \
 	generic/uuid-generic.cpp \
+	r3/linux/RTThreadGetNativeState-linux.cpp \
 	r3/linux/mp-linux.cpp \
 	r3/linux/rtProcInitExePath-linux.cpp \
@@ -527,4 +529,5 @@
 	generic/RTMpGetMaxFrequency-generic.cpp \
 	generic/RTProcIsRunningByName-generic.cpp \
+	generic/RTThreadGetNativeState-generic.cpp \
 	os2/RTErrConvertFromOS2.cpp \
 	r3/os2/filelock-os2.cpp \
@@ -568,4 +571,5 @@
 	generic/uuid-generic.cpp\
 	generic/RTProcIsRunningByName-generic.cpp \
+	generic/RTThreadGetNativeState-generic.cpp \
 	r3/darwin/alloc-darwin.cpp \
 	r3/darwin/filelock-darwin.cpp \
@@ -615,4 +619,5 @@
 	generic/RTMpIsCpuOnline-generic.cpp \
 	generic/RTProcIsRunningByName-generic.cpp \
+	generic/RTThreadGetNativeState-generic.cpp \
 	r3/freebsd/mp-freebsd.cpp \
 	r3/freebsd/alloc-freebsd.cpp \
@@ -655,4 +660,5 @@
 	generic/uuid-generic.cpp \
 	generic/RTProcIsRunningByName-generic.cpp \
+	generic/RTThreadGetNativeState-generic.cpp \
 	r3/posix/RTFileQueryFsSizes-posix.cpp \
 	r3/posix/RTSystemQueryOSInfo-posix.cpp \
@@ -716,4 +722,5 @@
 	generic/uuid-generic.cpp \
 	generic/RTProcIsRunningByName-generic.cpp \
+	generic/RTThreadGetNativeState-generic.cpp \
 	l4/l4-errno.cpp \
 	l4/rtProcInitExePath-l4.cpp \
Index: /trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/common/misc/lockvalidator.cpp	(revision 25638)
@@ -274,4 +274,5 @@
     if (!ASMAtomicUoReadBool(&g_fLockValidatorQuiet))
     {
+        ASMCompilerBarrier(); /* paranoia */
         RTAssertMsg1Weak("RTLockValidator", pSrcPos ? pSrcPos->uLine : 0, pSrcPos ? pSrcPos->pszFile : NULL, pSrcPos ? pSrcPos->pszFunction : NULL);
         if (pSrcPos && pSrcPos->uId)
@@ -417,4 +418,46 @@
 
 /**
+ * Checks if all owners are blocked - shared record operated in signaller mode.
+ *
+ * @returns true / false accordingly.
+ * @param   pRec                The record.
+ * @param   pThreadSelf         The current thread.
+ */
+DECL_FORCE_INLINE(bool) rtLockValidatorDdAreAllThreadsBlocked(PRTLOCKVALRECSHRD pRec, PRTTHREADINT pThreadSelf)
+{
+    PRTLOCKVALRECSHRDOWN volatile  *papOwners  = pRec->papOwners;
+    uint32_t                        cAllocated = pRec->cAllocated;
+    uint32_t                        cEntries   = ASMAtomicUoReadU32(&pRec->cEntries);
+    if (cEntries == 0)
+        return false;
+
+    for (uint32_t i = 0; i < cAllocated; i++)
+    {
+        PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorUoReadSharedOwner(&papOwners[i]);
+        if (   pEntry
+            && pEntry->Core.u32Magic == RTLOCKVALRECSHRDOWN_MAGIC)
+        {
+            PRTTHREADINT pCurThread = rtLockValidatorReadThreadHandle(&pEntry->hThread);
+            if (!pCurThread)
+                return false;
+            if (pCurThread->u32Magic != RTTHREADINT_MAGIC)
+                return false;
+            if (   !RTTHREAD_IS_SLEEPING(rtThreadGetState(pCurThread))
+                && pCurThread != pThreadSelf)
+                return false;
+            if (--cEntries == 0)
+                break;
+        }
+        else
+            Assert(!pEntry || pEntry->Core.u32Magic == RTLOCKVALRECSHRDOWN_MAGIC_DEAD);
+    }
+
+    return true;
+}
+
+
+
+
+/**
  * Verifies the deadlock stack before calling it a deadlock.
  *
@@ -424,6 +467,7 @@
  *
  * @param   pStack              The deadlock detection stack.
- */
-static int rtLockValidatorDdVerifyDeadlock(PRTLOCKVALDDSTACK pStack)
+ * @param   pThreadSelf         The current thread.
+ */
+static int rtLockValidatorDdVerifyDeadlock(PRTLOCKVALDDSTACK pStack, PRTTHREADINT pThreadSelf)
 {
     uint32_t const c = pStack->c;
@@ -438,4 +482,10 @@
                 return VERR_TRY_AGAIN;
             if (rtLockValidatorReadRecUnionPtr(&pThread->LockValidator.pRec) != pStack->a[i].pFirstSibling)
+                return VERR_TRY_AGAIN;
+            /* ASSUMES the signaller records won't have siblings! */
+            PRTLOCKVALRECUNION pRec = pStack->a[i].pRec;
+            if (   pRec->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC
+                && pRec->Shared.fSignaller
+                && !rtLockValidatorDdAreAllThreadsBlocked(&pRec->Shared, pThreadSelf))
                 return VERR_TRY_AGAIN;
         }
@@ -532,31 +582,39 @@
 
             case RTLOCKVALRECSHRD_MAGIC:
-                /* Skip to the next sibling if same side.  ASSUMES reader priority. */
-                /** @todo The read side of a read-write lock is problematic if
-                 * the implementation prioritizes writers over readers because
-                 * that means we should could deadlock against current readers
-                 * if a writer showed up.  If the RW sem implementation is
-                 * wrapping some native API, it's not so easy to detect when we
-                 * should do this and when we shouldn't.  Checking when we
-                 * shouldn't is subject to wakeup scheduling and cannot easily
-                 * be made reliable.
-                 *
-                 * At the moment we circumvent all this mess by declaring that
-                 * readers has priority.  This is TRUE on linux, but probably
-                 * isn't on Solaris and FreeBSD. */
-                if (   pRec == pFirstSibling
-                    && pRec->Shared.pSibling != NULL
-                    && pRec->Shared.pSibling != pFirstSibling)
+                if (!pRec->Shared.fSignaller)
                 {
-                    pRec = pRec->Shared.pSibling;
-                    Assert(iEntry == UINT32_MAX);
-                    continue;
+                    /* Skip to the next sibling if same side.  ASSUMES reader priority. */
+                    /** @todo The read side of a read-write lock is problematic if
+                     * the implementation prioritizes writers over readers because
+                     * that means we should could deadlock against current readers
+                     * if a writer showed up.  If the RW sem implementation is
+                     * wrapping some native API, it's not so easy to detect when we
+                     * should do this and when we shouldn't.  Checking when we
+                     * shouldn't is subject to wakeup scheduling and cannot easily
+                     * be made reliable.
+                     *
+                     * At the moment we circumvent all this mess by declaring that
+                     * readers has priority.  This is TRUE on linux, but probably
+                     * isn't on Solaris and FreeBSD. */
+                    if (   pRec == pFirstSibling
+                        && pRec->Shared.pSibling != NULL
+                        && pRec->Shared.pSibling != pFirstSibling)
+                    {
+                        pRec = pRec->Shared.pSibling;
+                        Assert(iEntry == UINT32_MAX);
+                        continue;
+                    }
                 }
 
                 /* Scan the owner table for blocked owners. */
                 pNextThread = NIL_RTTHREAD;
-                if (ASMAtomicUoReadU32(&pRec->Shared.cEntries) > 0)
+                if (    ASMAtomicUoReadU32(&pRec->Shared.cEntries) > 0
+                    &&  (   !pRec->Shared.fSignaller
+                         || iEntry != UINT32_MAX
+                         || rtLockValidatorDdAreAllThreadsBlocked(&pRec->Shared, pThreadSelf)
+                        )
+                    )
                 {
-                    uint32_t                        cAllocated = ASMAtomicUoReadU32(&pRec->Shared.cAllocated);
+                    uint32_t                        cAllocated = pRec->Shared.cAllocated;
                     PRTLOCKVALRECSHRDOWN volatile  *papOwners  = pRec->Shared.papOwners;
                     while (++iEntry < cAllocated)
@@ -642,6 +700,11 @@
             pStack->a[i].pFirstSibling  = pFirstSibling;
 
-            if (RT_UNLIKELY(pNextThread == pThreadSelf))
-                return rtLockValidatorDdVerifyDeadlock(pStack);
+            if (RT_UNLIKELY(   pNextThread == pThreadSelf
+                            && (   i != 0
+                                || pRec->Core.u32Magic != RTLOCKVALRECSHRD_MAGIC
+                                || !pRec->Shared.fSignaller) /* ASSUMES signaller records have no siblings. */
+                            )
+                )
+                return rtLockValidatorDdVerifyDeadlock(pStack, pThreadSelf);
 
             pRec            = pNextRec;
@@ -1135,5 +1198,5 @@
 RTDECL(int) RTLockValidatorRecExclCheckBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
                                                 PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
-                                                RTTHREADSTATE enmSleepState)
+                                                RTTHREADSTATE enmSleepState, bool fReallySleeping)
 {
     /*
@@ -1192,5 +1255,7 @@
         rc = rtLockValidatorDeadlockDetection(pRecU, pThreadSelf, pSrcPos);
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+        ASMAtomicWriteBool(&pThreadSelf->fReallySleeping, fReallySleeping);
+    else
         rtThreadSetState(pThreadSelf, enmThreadState);
     ASMAtomicWriteBool(&pThreadSelf->LockValidator.fInValidator, false);
@@ -1202,9 +1267,9 @@
 RTDECL(int) RTLockValidatorRecExclCheckOrderAndBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
                                                         PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
-                                                        RTTHREADSTATE enmSleepState)
+                                                        RTTHREADSTATE enmSleepState, bool fReallySleeping)
 {
     int rc = RTLockValidatorRecExclCheckOrder(pRec, hThreadSelf, pSrcPos);
     if (RT_SUCCESS(rc))
-        rc = RTLockValidatorRecExclCheckBlocking(pRec, hThreadSelf, pSrcPos, fRecursiveOk, enmSleepState);
+        rc = RTLockValidatorRecExclCheckBlocking(pRec, hThreadSelf, pSrcPos, fRecursiveOk, enmSleepState, fReallySleeping);
     return rc;
 }
@@ -1212,6 +1277,6 @@
 
 
-RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALIDATORCLASS hClass,
-                                          uint32_t uSubClass, const char *pszName, void *hLock)
+RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALIDATORCLASS hClass, uint32_t uSubClass,
+                                          const char *pszName, void *hLock, bool fSignaller)
 {
     RTLOCKVAL_ASSERT_PTR_ALIGN(pRec);
@@ -1224,4 +1289,5 @@
     pRec->pszName       = pszName;
     pRec->fEnabled      = RTLockValidatorIsEnabled();
+    pRec->fSignaller    = fSignaller;
     pRec->pSibling      = NULL;
 
@@ -1231,6 +1297,5 @@
     pRec->cAllocated    = 0;
     pRec->fReallocating = false;
-    pRec->afPadding[0]  = false;
-    pRec->afPadding[1]  = false;
+    pRec->fPadding      = false;
     pRec->papOwners     = NULL;
 #if HC_ARCH_BITS == 32
@@ -1334,5 +1399,5 @@
 RTDECL(int) RTLockValidatorRecSharedCheckBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
                                                   PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
-                                                  RTTHREADSTATE enmSleepState)
+                                                  RTTHREADSTATE enmSleepState, bool fReallySleeping)
 {
     /*
@@ -1373,5 +1438,7 @@
      */
     int rc = VINF_SUCCESS;
-    PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorRecSharedFindOwner(&pRecU->Shared, pThreadSelf, NULL);
+    PRTLOCKVALRECSHRDOWN pEntry = !pRecU->Shared.fSignaller
+                                ? rtLockValidatorRecSharedFindOwner(&pRecU->Shared, pThreadSelf, NULL)
+                                : NULL;
     if (pEntry)
     {
@@ -1389,5 +1456,7 @@
         rc = rtLockValidatorDeadlockDetection(pRecU, pThreadSelf, pSrcPos);
 
-    if (RT_FAILURE(rc))
+    if (RT_SUCCESS(rc))
+        ASMAtomicWriteBool(&pThreadSelf->fReallySleeping, fReallySleeping);
+    else
         rtThreadSetState(pThreadSelf, enmThreadState);
     ASMAtomicWriteBool(&pThreadSelf->LockValidator.fInValidator, false);
@@ -1399,9 +1468,9 @@
 RTDECL(int) RTLockValidatorRecSharedCheckOrderAndBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
                                                           PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk,
-                                                          RTTHREADSTATE enmSleepState)
+                                                          RTTHREADSTATE enmSleepState, bool fReallySleeping)
 {
     int rc = RTLockValidatorRecSharedCheckOrder(pRec, hThreadSelf, pSrcPos);
     if (RT_SUCCESS(rc))
-        rc = RTLockValidatorRecSharedCheckBlocking(pRec, hThreadSelf, pSrcPos, fRecursiveOk, enmSleepState);
+        rc = RTLockValidatorRecSharedCheckBlocking(pRec, hThreadSelf, pSrcPos, fRecursiveOk, enmSleepState, fReallySleeping);
     return rc;
 }
@@ -1413,5 +1482,5 @@
  *
  * @returns The new owner entry.
- * @param   pShared             The shared lock record.
+ * @param   pRec                The shared lock record.
  * @param   pThreadSelf         The calling thread and owner.  Used for record
  *                              initialization and allocation.
@@ -1419,19 +1488,20 @@
  */
 DECLINLINE(PRTLOCKVALRECSHRDOWN)
-rtLockValidatorRecSharedAllocOwner(PRTLOCKVALRECSHRD pRead, PRTTHREADINT pThreadSelf, PCRTLOCKVALSRCPOS pSrcPos)
+rtLockValidatorRecSharedAllocOwner(PRTLOCKVALRECSHRD pRec, PRTTHREADINT pThreadSelf, PCRTLOCKVALSRCPOS pSrcPos)
 {
     PRTLOCKVALRECSHRDOWN pEntry;
 
     /*
-     * Check if the thread has any statically allocated records we can use.
-     */
-    unsigned iEntry = ASMBitFirstSetU32(pThreadSelf->LockValidator.bmFreeShrdOwners);
-    if (iEntry > 0)
-    {
-        iEntry--;
-        pThreadSelf->LockValidator.bmFreeShrdOwners &= ~RT_BIT_32(iEntry);
-        pEntry = &pThreadSelf->LockValidator.aShrdOwners[iEntry];
+     * Check if the thread has any statically allocated records we can easily
+     * make use of.
+     */
+    unsigned iEntry = ASMBitFirstSetU32(ASMAtomicUoReadU32(&pThreadSelf->LockValidator.bmFreeShrdOwners));
+    if (   iEntry > 0
+        && ASMAtomicBitTestAndClear(&pThreadSelf->LockValidator.bmFreeShrdOwners, iEntry - 1))
+    {
+        pEntry = &pThreadSelf->LockValidator.aShrdOwners[iEntry - 1];
         Assert(!pEntry->fReserved);
         pEntry->fStaticAlloc = true;
+        rtThreadGet(pThreadSelf);
     }
     else
@@ -1448,5 +1518,5 @@
     pEntry->hThread         = pThreadSelf;
     pEntry->pDown           = NULL;
-    pEntry->pSharedRec      = pRead;
+    pEntry->pSharedRec      = pRec;
 #if HC_ARCH_BITS == 32
     pEntry->pvReserved      = NULL;
@@ -1469,9 +1539,9 @@
     if (pEntry)
     {
+        Assert(pEntry->Core.u32Magic == RTLOCKVALRECSHRDOWN_MAGIC);
         ASMAtomicWriteU32(&pEntry->Core.u32Magic, RTLOCKVALRECSHRDOWN_MAGIC_DEAD);
 
-        PRTTHREADINT pThreadSelf = pEntry->hThread;
-        ASMAtomicXchgHandle(&pEntry->hThread, NIL_RTTHREAD, &pThreadSelf);
-        Assert(pThreadSelf == RTThreadSelf());
+        PRTTHREADINT pThread;
+        ASMAtomicXchgHandle(&pEntry->hThread, NIL_RTTHREAD, &pThread);
 
         Assert(pEntry->fReserved);
@@ -1480,7 +1550,14 @@
         if (pEntry->fStaticAlloc)
         {
-            uintptr_t iEntry = pEntry - &pThreadSelf->LockValidator.aShrdOwners[0];
-            AssertReleaseReturnVoid(iEntry < RT_ELEMENTS(pThreadSelf->LockValidator.aShrdOwners));
-            pThreadSelf->LockValidator.bmFreeShrdOwners |= RT_BIT_32(iEntry);
+            AssertPtrReturnVoid(pThread);
+            AssertReturnVoid(pThread->u32Magic == RTTHREADINT_MAGIC);
+
+            uintptr_t iEntry = pEntry - &pThread->LockValidator.aShrdOwners[0];
+            AssertReleaseReturnVoid(iEntry < RT_ELEMENTS(pThread->LockValidator.aShrdOwners));
+
+            Assert(!ASMBitTest(&pThread->LockValidator.bmFreeShrdOwners, iEntry));
+            ASMAtomicBitSet(&pThread->LockValidator.bmFreeShrdOwners, iEntry);
+
+            rtThreadRelease(pThread);
         }
         else
@@ -1649,12 +1726,68 @@
 
 
-RTDECL(void) RTLockValidatorSharedRecAddOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf, PCRTLOCKVALSRCPOS pSrcPos)
+RTDECL(void) RTLockValidatorRecSharedResetOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos)
 {
     AssertReturnVoid(pRec->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC);
     if (!pRec->fEnabled)
         return;
-    AssertReturnVoid(hThreadSelf != NIL_RTTHREAD);
-    AssertReturnVoid(hThreadSelf->u32Magic == RTTHREADINT_MAGIC);
-    Assert(hThreadSelf == RTThreadSelf());
+    AssertReturnVoid(hThread == NIL_RTTHREAD || hThread->u32Magic == RTTHREADINT_MAGIC);
+
+    /*
+     * Free all current owners.
+     */
+    rtLockValidatorSerializeDetectionEnter();
+    while (ASMAtomicUoReadU32(&pRec->cEntries) > 0)
+    {
+        AssertReturnVoidStmt(pRec->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC, rtLockValidatorSerializeDetectionLeave());
+        uint32_t                        iEntry     = 0;
+        uint32_t                        cEntries   = pRec->cAllocated;
+        PRTLOCKVALRECSHRDOWN volatile  *papEntries = pRec->papOwners;
+        while (iEntry < cEntries)
+        {
+            PRTLOCKVALRECSHRDOWN pEntry = (PRTLOCKVALRECSHRDOWN)ASMAtomicXchgPtr((void * volatile *)&papEntries[iEntry], NULL);
+            if (pEntry)
+            {
+                ASMAtomicDecU32(&pRec->cEntries);
+                rtLockValidatorSerializeDetectionLeave();
+
+                rtLockValidatorRecSharedFreeOwner(pEntry);
+
+                rtLockValidatorSerializeDetectionEnter();
+                if (ASMAtomicUoReadU32(&pRec->cEntries) == 0)
+                    break;
+                cEntries   = pRec->cAllocated;
+                papEntries = pRec->papOwners;
+            }
+            iEntry++;
+        }
+    }
+    rtLockValidatorSerializeDetectionLeave();
+
+    if (hThread != NIL_RTTHREAD)
+    {
+        /*
+         * Allocate a new owner entry and insert it into the table.
+         */
+        PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorRecSharedAllocOwner(pRec, hThread, pSrcPos);
+        if (    pEntry
+            &&  !rtLockValidatorRecSharedAddOwner(pRec, pEntry))
+            rtLockValidatorRecSharedFreeOwner(pEntry);
+    }
+}
+RT_EXPORT_SYMBOL(RTLockValidatorRecSharedResetOwner);
+
+
+RTDECL(void) RTLockValidatorRecSharedAddOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos)
+{
+    AssertReturnVoid(pRec->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC);
+    if (!pRec->fEnabled)
+        return;
+    if (hThread == NIL_RTTHREAD)
+    {
+        hThread = RTThreadSelfAutoAdopt();
+        AssertReturnVoid(hThread != NIL_RTTHREAD);
+    }
+    AssertReturnVoid(hThread != NIL_RTTHREAD);
+    AssertReturnVoid(hThread->u32Magic == RTTHREADINT_MAGIC);
 
     /*
@@ -1665,7 +1798,8 @@
      *       so it can wait til later sometime.
      */
-    PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorRecSharedFindOwner(pRec, hThreadSelf, NULL);
+    PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorRecSharedFindOwner(pRec, hThread, NULL);
     if (pEntry)
     {
+        Assert(hThread == RTThreadSelf());
         pEntry->cRecursion++;
         return;
@@ -1675,39 +1809,86 @@
      * Allocate a new owner entry and insert it into the table.
      */
-    pEntry = rtLockValidatorRecSharedAllocOwner(pRec, hThreadSelf, pSrcPos);
+    pEntry = rtLockValidatorRecSharedAllocOwner(pRec, hThread, pSrcPos);
     if (    pEntry
         &&  !rtLockValidatorRecSharedAddOwner(pRec, pEntry))
         rtLockValidatorRecSharedFreeOwner(pEntry);
 }
-RT_EXPORT_SYMBOL(RTLockValidatorSharedRecAddOwner);
-
-
-RTDECL(void) RTLockValidatorSharedRecRemoveOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf)
+RT_EXPORT_SYMBOL(RTLockValidatorRecSharedAddOwner);
+
+
+RTDECL(void) RTLockValidatorRecSharedRemoveOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread)
 {
     AssertReturnVoid(pRec->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC);
     if (!pRec->fEnabled)
         return;
-    AssertReturnVoid(hThreadSelf != NIL_RTTHREAD);
-    AssertReturnVoid(hThreadSelf->u32Magic == RTTHREADINT_MAGIC);
+    AssertReturnVoid(hThread != NIL_RTTHREAD);
+    AssertReturnVoid(hThread->u32Magic == RTTHREADINT_MAGIC);
+
+    /*
+     * Find the entry hope it's a recursive one.
+     */
+    uint32_t iEntry = UINT32_MAX; /* shuts up gcc */
+    PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorRecSharedFindOwner(pRec, hThread, &iEntry);
+    AssertReturnVoid(pEntry);
+    if (pEntry->cRecursion > 1)
+    {
+        Assert(hThread == RTThreadSelf());
+        pEntry->cRecursion--;
+    }
+    else
+        rtLockValidatorRecSharedRemoveAndFreeOwner(pRec, pEntry, iEntry);
+}
+RT_EXPORT_SYMBOL(RTLockValidatorRecSharedRemoveOwner);
+
+
+RTDECL(int) RTLockValidatorRecSharedCheckAndRelease(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf)
+{
+    AssertReturn(pRec->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC, VERR_SEM_LV_INVALID_PARAMETER);
+    if (!pRec->fEnabled)
+        return VINF_SUCCESS;
+    if (hThreadSelf == NIL_RTTHREAD)
+    {
+        hThreadSelf = RTThreadSelfAutoAdopt();
+        AssertReturn(hThreadSelf != NIL_RTTHREAD, VERR_SEM_LV_INVALID_PARAMETER);
+    }
     Assert(hThreadSelf == RTThreadSelf());
 
     /*
-     * Find the entry hope it's a recursive one.
-     */
-    uint32_t iEntry = UINT32_MAX; /* shuts up gcc */
-    PRTLOCKVALRECSHRDOWN pEntry = rtLockValidatorRecSharedFindOwner(pRec, hThreadSelf, &iEntry);
-    AssertReturnVoid(pEntry);
+     * Locate the entry for this thread in the table.
+     */
+    uint32_t                iEntry = 0;
+    PRTLOCKVALRECSHRDOWN    pEntry = rtLockValidatorRecSharedFindOwner(pRec, hThreadSelf, &iEntry);
+    if (RT_UNLIKELY(!pEntry))
+    {
+        rtLockValidatorComplainFirst("Not owner (shared)", NULL, hThreadSelf, (PRTLOCKVALRECUNION)pRec);
+        rtLockValidatorComplainPanic();
+        return VERR_SEM_LV_NOT_OWNER;
+    }
+
+    /*
+     * Check the release order.
+     */
+    if (pRec->hClass != NIL_RTLOCKVALIDATORCLASS)
+    {
+        /** @todo order validation */
+    }
+
+    /*
+     * Release the ownership or unwind a level of recursion.
+     */
+    Assert(pEntry->cRecursion > 0);
     if (pEntry->cRecursion > 1)
         pEntry->cRecursion--;
     else
         rtLockValidatorRecSharedRemoveAndFreeOwner(pRec, pEntry, iEntry);
-}
-RT_EXPORT_SYMBOL(RTLockValidatorSharedRecRemoveOwner);
-
-
-RTDECL(int) RTLockValidatorRecSharedCheckAndRelease(PRTLOCKVALRECSHRD pRead, RTTHREAD hThreadSelf)
-{
-    AssertReturn(pRead->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC, VERR_SEM_LV_INVALID_PARAMETER);
-    if (!pRead->fEnabled)
+
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(int) RTLockValidatorRecSharedCheckSignaller(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf)
+{
+    AssertReturn(pRec->Core.u32Magic == RTLOCKVALRECSHRD_MAGIC, VERR_SEM_LV_INVALID_PARAMETER);
+    if (!pRec->fEnabled)
         return VINF_SUCCESS;
     if (hThreadSelf == NIL_RTTHREAD)
@@ -1722,24 +1903,11 @@
      */
     uint32_t                iEntry = 0;
-    PRTLOCKVALRECSHRDOWN    pEntry = rtLockValidatorRecSharedFindOwner(pRead, hThreadSelf, &iEntry);
-    AssertReturn(pEntry, VERR_SEM_LV_NOT_OWNER);
-
-    /*
-     * Check the release order.
-     */
-    if (pRead->hClass != NIL_RTLOCKVALIDATORCLASS)
-    {
-        /** @todo order validation */
-    }
-
-    /*
-     * Release the ownership or unwind a level of recursion.
-     */
-    Assert(pEntry->cRecursion > 0);
-    if (pEntry->cRecursion > 1)
-        pEntry->cRecursion--;
-    else
-        rtLockValidatorRecSharedRemoveAndFreeOwner(pRead, pEntry, iEntry);
-
+    PRTLOCKVALRECSHRDOWN    pEntry = rtLockValidatorRecSharedFindOwner(pRec, hThreadSelf, &iEntry);
+    if (RT_UNLIKELY(!pEntry))
+    {
+        rtLockValidatorComplainFirst("Invalid signaller", NULL, hThreadSelf, (PRTLOCKVALRECUNION)pRec);
+        rtLockValidatorComplainPanic();
+        return VERR_SEM_LV_NOT_SIGNALLER;
+    }
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/Runtime/common/misc/thread.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/misc/thread.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/common/misc/thread.cpp	(revision 25638)
@@ -349,10 +349,11 @@
         memcpy(pThread->szName, pszName, cchName);
         pThread->szName[cchName] = '\0';
-        pThread->cRefs      = 2 + !!(fFlags & RTTHREADFLAGS_WAITABLE); /* And extra reference if waitable. */
-        pThread->rc         = VERR_PROCESS_RUNNING; /** @todo get a better error code! */
-        pThread->enmType    = enmType;
-        pThread->fFlags     = fFlags;
-        pThread->fIntFlags  = fIntFlags;
-        pThread->enmState   = RTTHREADSTATE_INITIALIZING;
+        pThread->cRefs           = 2 + !!(fFlags & RTTHREADFLAGS_WAITABLE); /* And extra reference if waitable. */
+        pThread->rc              = VERR_PROCESS_RUNNING; /** @todo get a better error code! */
+        pThread->enmType         = enmType;
+        pThread->fFlags          = fFlags;
+        pThread->fIntFlags       = fIntFlags;
+        pThread->enmState        = RTTHREADSTATE_INITIALIZING;
+        pThread->fReallySleeping = false;
 #ifdef IN_RING3
         rtLockValidatorInitPerThread(&pThread->LockValidator);
@@ -1300,11 +1301,17 @@
  * @param   hThread         The current thread.
  * @param   enmState        The sleep state.
- */
-RTDECL(void) RTThreadBlocking(RTTHREAD hThread, RTTHREADSTATE enmState)
+ * @param   fReallySleeping Really going to sleep now.
+ */
+RTDECL(void) RTThreadBlocking(RTTHREAD hThread, RTTHREADSTATE enmState, bool fReallySleeping)
 {
     Assert(RTTHREAD_IS_SLEEPING(enmState));
     PRTTHREADINT pThread = hThread;
-    if (pThread && rtThreadGetState(pThread) == RTTHREADSTATE_RUNNING)
-        rtThreadSetState(pThread, enmState);
+    if (pThread != NIL_RTTHREAD)
+    {
+        Assert(pThread == RTThreadSelf());
+        if (rtThreadGetState(pThread) == RTTHREADSTATE_RUNNING)
+            rtThreadSetState(pThread, enmState);
+        ASMAtomicWriteBool(&pThread->fReallySleeping, fReallySleeping);
+    }
 }
 RT_EXPORT_SYMBOL(RTThreadBlocking);
@@ -1322,6 +1329,12 @@
 RTDECL(void) RTThreadUnblocked(RTTHREAD hThread, RTTHREADSTATE enmCurState)
 {
-    if (hThread && rtThreadGetState(hThread) == enmCurState)
-        rtThreadSetState(hThread, RTTHREADSTATE_RUNNING);
+    PRTTHREADINT pThread = hThread;
+    if (pThread != NIL_RTTHREAD)
+    {
+        Assert(pThread == RTThreadSelf());
+        ASMAtomicWriteBool(&pThread->fReallySleeping, false);
+        if (rtThreadGetState(pThread) == enmCurState)
+            rtThreadSetState(pThread, RTTHREADSTATE_RUNNING);
+    }
 }
 RT_EXPORT_SYMBOL(RTThreadUnblocked);
@@ -1346,4 +1359,20 @@
 }
 RT_EXPORT_SYMBOL(RTThreadGetState);
+
+
+RTDECL(RTTHREADSTATE) RTThreadGetReallySleeping(RTTHREAD hThread)
+{
+    RTTHREADSTATE   enmState = RTTHREADSTATE_INVALID;
+    PRTTHREADINT    pThread  = rtThreadGet(hThread);
+    if (pThread)
+    {
+        enmState = rtThreadGetState(pThread);
+        if (!ASMAtomicUoReadBool(&pThread->fReallySleeping))
+            enmState = RTTHREADSTATE_RUNNING;
+        rtThreadRelease(pThread);
+    }
+    return enmState;
+}
+RT_EXPORT_SYMBOL(RTThreadGetReallySleeping);
 
 
Index: /trunk/src/VBox/Runtime/generic/RTThreadGetNativeState-generic.cpp
===================================================================
--- /trunk/src/VBox/Runtime/generic/RTThreadGetNativeState-generic.cpp	(revision 25638)
+++ /trunk/src/VBox/Runtime/generic/RTThreadGetNativeState-generic.cpp	(revision 25638)
@@ -0,0 +1,53 @@
+/* $Id$ */
+/** @file
+ * IPRT - RTThreadGetNativeState, generic stub implementation.
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define LOG_GROUP RTLOGGROUP_PROCESS
+#include <iprt/thread.h>
+#include "internal/iprt.h"
+
+#include "internal/thread.h"
+
+
+RTDECL(RTTHREADNATIVESTATE) RTThreadGetNativeState(RTTHREAD hThread)
+{
+    RTTHREADNATIVESTATE enmRet  = RTTHREADNATIVESTATE_INVALID;
+    PRTTHREADINT        pThread = rtThreadGet(hThread);
+    if (pThread)
+    {
+        enmRet = RTTHREADNATIVESTATE_UNKNOWN;
+        rtThreadRelease(pThread);
+    }
+    return enmRet;
+}
+
Index: /trunk/src/VBox/Runtime/generic/critsect-generic.cpp
===================================================================
--- /trunk/src/VBox/Runtime/generic/critsect-generic.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/generic/critsect-generic.cpp	(revision 25638)
@@ -208,7 +208,7 @@
         {
 #ifdef RTCRITSECT_STRICT
-            int rc9 = RTLockValidatorRecExclCheckBlocking(pCritSect->pValidatorRec, hThreadSelf, pSrcPos,
-                                                          !(pCritSect->fFlags & RTCRITSECT_FLAGS_NO_NESTING),
-                                                          RTTHREADSTATE_CRITSECT);
+            rc9 = RTLockValidatorRecExclCheckBlocking(pCritSect->pValidatorRec, hThreadSelf, pSrcPos,
+                                                      !(pCritSect->fFlags & RTCRITSECT_FLAGS_NO_NESTING),
+                                                      RTTHREADSTATE_CRITSECT, false);
             if (RT_FAILURE(rc9))
             {
@@ -217,5 +217,5 @@
             }
 #else
-            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_CRITSECT);
+            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_CRITSECT, false);
 #endif
             int rc = RTSemEventWait(pCritSect->EventSem, RT_INDEFINITE_WAIT);
Index: /trunk/src/VBox/Runtime/generic/semrw-generic.cpp
===================================================================
--- /trunk/src/VBox/Runtime/generic/semrw-generic.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/generic/semrw-generic.cpp	(revision 25638)
@@ -136,5 +136,5 @@
 #ifdef RTSEMRW_STRICT
                         RTLockValidatorRecExclInit(&pThis->ValidatorWrite, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis);
-                        RTLockValidatorRecSharedInit(&pThis->ValidatorRead,  NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis);
+                        RTLockValidatorRecSharedInit(&pThis->ValidatorRead,  NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis, false /*fSignaller*/);
                         RTLockValidatorRecMakeSiblings(&pThis->ValidatorWrite.Core, &pThis->ValidatorRead.Core);
 #endif
@@ -272,5 +272,5 @@
         Assert(pThis->cReads > 0);
 #ifdef RTSEMRW_STRICT
-        RTLockValidatorSharedRecAddOwner(&pThis->ValidatorRead, hThreadSelf, pSrcPos);
+        RTLockValidatorRecSharedAddOwner(&pThis->ValidatorRead, hThreadSelf, pSrcPos);
 #endif
 
@@ -324,9 +324,10 @@
         }
 #ifdef RTSEMRW_STRICT
-        rc = RTLockValidatorRecSharedCheckBlocking(&pThis->ValidatorRead, hThreadSelf, pSrcPos, true, RTTHREADSTATE_RW_READ);
+        rc = RTLockValidatorRecSharedCheckBlocking(&pThis->ValidatorRead, hThreadSelf, pSrcPos, true,
+                                                   RTTHREADSTATE_RW_READ, false);
         if (RT_FAILURE(rc))
             break;
 #else
-        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_READ);
+        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_READ, false);
 #endif
         int rcWait;
@@ -368,5 +369,5 @@
             Assert(pThis->cReads > 0);
 #ifdef RTSEMRW_STRICT
-            RTLockValidatorSharedRecAddOwner(&pThis->ValidatorRead, hThreadSelf, pSrcPos);
+            RTLockValidatorRecSharedAddOwner(&pThis->ValidatorRead, hThreadSelf, pSrcPos);
 #endif
 
@@ -612,9 +613,10 @@
 
 #ifdef RTSEMRW_STRICT
-        rc = RTLockValidatorRecExclCheckBlocking(&pThis->ValidatorWrite, hThreadSelf, pSrcPos, true, RTTHREADSTATE_RW_WRITE);
+        rc = RTLockValidatorRecExclCheckBlocking(&pThis->ValidatorWrite, hThreadSelf, pSrcPos, true,
+                                                 RTTHREADSTATE_RW_WRITE, false);
         if (RT_FAILURE(rc))
             break;
 #else
-        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE);
+        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE, false);
 #endif
         int rcWait;
Index: /trunk/src/VBox/Runtime/include/internal/lockvalidator.h
===================================================================
--- /trunk/src/VBox/Runtime/include/internal/lockvalidator.h	(revision 25637)
+++ /trunk/src/VBox/Runtime/include/internal/lockvalidator.h	(revision 25638)
@@ -70,5 +70,5 @@
     bool                            afReserved[3];
     /** Bitmap indicating which entires are free (set) and allocated (clear). */
-    uint32_t                        bmFreeShrdOwners;
+    uint32_t volatile               bmFreeShrdOwners;
     /** Statically allocated shared owner records */
     RTLOCKVALRECSHRDOWN             aShrdOwners[32];
Index: /trunk/src/VBox/Runtime/include/internal/strict.h
===================================================================
--- /trunk/src/VBox/Runtime/include/internal/strict.h	(revision 25637)
+++ /trunk/src/VBox/Runtime/include/internal/strict.h	(revision 25638)
@@ -43,4 +43,17 @@
 #endif
 
+/** @def RTSEMEVENT_STRICT
+ * Enables strictness checks and lock accounting of the RTSemEvent API.
+ */
+#if defined(DOXYGEN_RUNNING) || (!defined(RTSEMEVENT_STRICT) && defined(IN_RING3) && (defined(RT_STRICT) || defined(RT_LOCK_STRICT) || defined(RTSEM_STRICT)))
+# define RTSEMEVENT_STRICT
+#endif
+
+/** @def RTSEMEVENTMULTI_STRICT
+ * Enables strictness checks and lock accounting of the RTSemEventMulti API.
+ */
+#if defined(DOXYGEN_RUNNING) || (!defined(RTSEMEVENTMULTI_STRICT) && defined(IN_RING3) && (defined(RT_STRICT) || defined(RT_LOCK_STRICT) || defined(RTSEM_STRICT)))
+# define RTSEMEVENTMULTI_STRICT
+#endif
 
 /** @def RTSEMMUTEX_STRICT
Index: /trunk/src/VBox/Runtime/include/internal/thread.h
===================================================================
--- /trunk/src/VBox/Runtime/include/internal/thread.h	(revision 25637)
+++ /trunk/src/VBox/Runtime/include/internal/thread.h	(revision 25638)
@@ -67,8 +67,15 @@
     /** The current thread state. */
     RTTHREADSTATE volatile  enmState;
+    /** Set when really sleeping. */
+    bool volatile           fReallySleeping;
 #if defined(RT_OS_WINDOWS) && defined(IN_RING3)
     /** The thread handle
      * This is not valid until the create function has returned! */
     uintptr_t               hThread;
+#endif
+#if defined(RT_OS_LINUX) && defined(IN_RING3)
+    /** The thread ID.
+     * This is not valid before rtThreadMain has been called by the new thread.  */
+    pid_t                   tid;
 #endif
     /** The user event semaphore. */
Index: /trunk/src/VBox/Runtime/r3/linux/RTThreadGetNativeState-linux.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/linux/RTThreadGetNativeState-linux.cpp	(revision 25638)
+++ /trunk/src/VBox/Runtime/r3/linux/RTThreadGetNativeState-linux.cpp	(revision 25638)
@@ -0,0 +1,115 @@
+/* $Id$ */
+/** @file
+ * IPRT - RTThreadGetNativeState, linux implementation.
+ */
+
+/*
+ * Copyright (C) 2010 Sun Microsystems, Inc.
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
+ * Clara, CA 95054 USA or visit http://www.sun.com if you need
+ * additional information or have any questions.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define LOG_GROUP RTLOGGROUP_PROCESS
+#include <iprt/thread.h>
+#include "internal/iprt.h"
+
+#include <iprt/assert.h>
+#include <iprt/ctype.h>
+#include <iprt/err.h>
+#include <iprt/string.h>
+
+#include "internal/thread.h"
+
+#include <unistd.h>
+#include <sys/fcntl.h>
+
+
+RTDECL(RTTHREADNATIVESTATE) RTThreadGetNativeState(RTTHREAD hThread)
+{
+    RTTHREADNATIVESTATE enmRet  = RTTHREADNATIVESTATE_INVALID;
+    PRTTHREADINT        pThread = rtThreadGet(hThread);
+    if (pThread)
+    {
+        enmRet = RTTHREADNATIVESTATE_UNKNOWN;
+
+        char szName[512];
+        RTStrPrintf(szName, sizeof(szName), "/proc/self/task/%u/stat", pThread->tid);
+        int fd = open(szName, O_RDONLY, 0);
+        if (fd >= 0)
+        {
+            ssize_t cch = read(fd, szName, sizeof(szName) - 1);
+            close(fd);
+            if (cch > 0)
+            {
+                szName[cch] = '\0';
+
+                /* skip the pid, the (comm name) and stop at the status char. */
+                const char *psz = szName;
+                while (   *psz
+                       && (   *psz != ')'
+                           || !RT_C_IS_SPACE(psz[1])
+                           || !RT_C_IS_ALPHA(psz[2])
+                           || !RT_C_IS_SPACE(psz[3])
+                          )
+                      )
+                    psz++;
+                if (*psz == ')')
+                {
+                    switch (psz[2])
+                    {
+                        case 'R':   /* running */
+                            enmRet = RTTHREADNATIVESTATE_RUNNING;
+                            break;
+
+                        case 'S':   /* sleeping */
+                        case 'D':   /* disk sleeping */
+                            enmRet = RTTHREADNATIVESTATE_BLOCKED;
+                            break;
+
+                        case 'T':   /* stopped or tracking stop */
+                            enmRet = RTTHREADNATIVESTATE_SUSPENDED;
+                            break;
+
+                        case 'Z':   /* zombie */
+                        case 'X':   /* dead */
+                            enmRet = RTTHREADNATIVESTATE_TERMINATED;
+                            break;
+
+                        default:
+                            AssertMsgFailed(("state=%c\n", psz[2]));
+                            enmRet = RTTHREADNATIVESTATE_UNKNOWN;
+                            break;
+                    }
+                }
+                else
+                    AssertMsgFailed(("stat='%s'\n", szName));
+            }
+        }
+        rtThreadRelease(pThread);
+    }
+    return enmRet;
+}
+
Index: /trunk/src/VBox/Runtime/r3/linux/semevent-linux.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/linux/semevent-linux.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/r3/linux/semevent-linux.cpp	(revision 25638)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -30,5 +30,5 @@
 
 #include <features.h>
-#if __GLIBC_PREREQ(2,6) && !defined(IPRT_WITH_FUTEX_BASED_SEMS)
+#if __GLIBC_PREREQ(2,6) && !defined(IPRT_WITH_FUTEX_BASED_SEMS)  && !defined(DEBUG_bird) //// testing 1 2 3
 
 /*
@@ -50,10 +50,14 @@
 *******************************************************************************/
 #include <iprt/semaphore.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
 #include <iprt/assert.h>
-#include <iprt/alloc.h>
-#include <iprt/asm.h>
 #include <iprt/err.h>
+#include <iprt/lockvalidator.h>
+#include <iprt/mem.h>
 #include <iprt/time.h>
 #include "internal/magics.h"
+#include "internal/strict.h"
 
 #include <errno.h>
@@ -87,4 +91,10 @@
     /** The number of waiting threads */
     int32_t volatile    cWaiters;
+#ifdef RTSEMEVENT_STRICT
+    /** Signallers. */
+    RTLOCKVALRECSHRD    Signallers;
+    /** Indicates that lock validation should be performed. */
+    bool volatile       fEverHadSignallers;
+#endif
 };
 
@@ -118,4 +128,10 @@
         pThis->cWaiters = 0;
         pThis->fSignalled = 0;
+#ifdef RTSEMEVENT_STRICT
+        RTLockValidatorRecSharedInit(&pThis->Signallers,
+                                     NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY,
+                                     "RTSemEvent", pThis, true /*fSignaller*/);
+        pThis->fEverHadSignallers = false;
+#endif
         *pEventSem = pThis;
         return VINF_SUCCESS;
@@ -149,4 +165,7 @@
      * Free the semaphore memory and be gone.
      */
+#ifdef RTSEMEVENT_STRICT
+    RTLockValidatorRecSharedDelete(&pThis->Signallers);
+#endif
     RTMemFree(pThis);
     return VINF_SUCCESS;
@@ -160,6 +179,15 @@
      */
     struct RTSEMEVENTINTERNAL *pThis = EventSem;
-    AssertReturn(VALID_PTR(pThis) && pThis->iMagic == RTSEMEVENT_MAGIC,
-                 VERR_INVALID_HANDLE);
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->iMagic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE);
+
+#ifdef RTSEMEVENT_STRICT
+    if (pThis->fEverHadSignallers)
+    {
+        int rc9 = RTLockValidatorRecSharedCheckSignaller(&pThis->Signallers, NIL_RTTHREAD);
+        if (RT_FAILURE(rc9))
+            return rc9;
+    }
+#endif
 
     ASMAtomicWriteU32(&pThis->fSignalled, 1);
@@ -181,14 +209,19 @@
 static int rtSemEventWait(RTSEMEVENT EventSem, unsigned cMillies, bool fAutoResume)
 {
+    PCRTLOCKVALSRCPOS pSrcPos = NULL;
+
     /*
      * Validate input.
      */
     struct RTSEMEVENTINTERNAL *pThis = EventSem;
-    AssertReturn(VALID_PTR(pThis) && pThis->iMagic == RTSEMEVENT_MAGIC,
-                 VERR_INVALID_HANDLE);
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->iMagic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE);
 
     /*
      * Quickly check whether it's signaled.
      */
+    /** @todo this isn't fair if someone is already waiting on it.  They should
+     *        have the first go at it!
+     *  (ASMAtomicReadS32(&pThis->cWaiters) == 0 || !cMillies) && ... */
     if (ASMAtomicCmpXchgU32(&pThis->fSignalled, 0, 1))
         return VINF_SUCCESS;
@@ -215,8 +248,24 @@
      * The wait loop.
      */
+#ifdef RTSEMEVENT_STRICT
+    RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
+#else
+    RTTHREAD hThreadSelf = RTThreadSelf();
+#endif
     int rc = VINF_SUCCESS;
     for (;;)
     {
+#ifdef RTSEMEVENT_STRICT
+        if (pThis->fEverHadSignallers)
+        {
+            rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
+                                                       RTTHREADSTATE_EVENT, true);
+            if (RT_FAILURE(rc))
+                break;
+        }
+#endif
+        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT, true);
         long lrc = sys_futex(&pThis->fSignalled, FUTEX_WAIT, 0, pTimeout, NULL, 0);
+        RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT);
         if (RT_UNLIKELY(pThis->iMagic != RTSEMEVENT_MAGIC))
         {
@@ -284,4 +333,42 @@
 }
 
+
+RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+#ifdef RTSEMEVENT_STRICT
+    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
+    AssertPtrReturnVoid(pThis);
+    AssertReturnVoid(pThis->iMagic == RTSEMEVENT_MAGIC);
+
+    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
+    RTLockValidatorRecSharedResetOwner(&pThis->Signallers, hThread, NULL);
+#endif
+}
+
+
+RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+#ifdef RTSEMEVENT_STRICT
+    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
+    AssertPtrReturnVoid(pThis);
+    AssertReturnVoid(pThis->iMagic == RTSEMEVENT_MAGIC);
+
+    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
+    RTLockValidatorRecSharedAddOwner(&pThis->Signallers, hThread, NULL);
+#endif
+}
+
+
+RTDECL(void) RTSemEventRemoveSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+#ifdef RTSEMEVENT_STRICT
+    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
+    AssertPtrReturnVoid(pThis);
+    AssertReturnVoid(pThis->iMagic == RTSEMEVENT_MAGIC);
+
+    RTLockValidatorRecSharedRemoveOwner(&pThis->Signallers, hThread);
+#endif
+}
+
 #endif /* glibc < 2.6 || IPRT_WITH_FUTEX_BASED_SEMS */
 
Index: /trunk/src/VBox/Runtime/r3/linux/semmutex-linux.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/linux/semmutex-linux.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/r3/linux/semmutex-linux.cpp	(revision 25638)
@@ -240,9 +240,10 @@
             {
 #ifdef RTSEMMUTEX_STRICT
-                int rc9 = RTLockValidatorRecExclCheckBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true, RTTHREADSTATE_MUTEX);
+                int rc9 = RTLockValidatorRecExclCheckBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true,
+                                                              RTTHREADSTATE_MUTEX, true);
                 if (RT_FAILURE(rc9))
                     return rc9;
 #else
-                RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX);
+                RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, true);
 #endif
             }
Index: /trunk/src/VBox/Runtime/r3/os2/sems-os2.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/os2/sems-os2.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/r3/os2/sems-os2.cpp	(revision 25638)
@@ -124,4 +124,22 @@
 
 
+RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+/** @todo implement RTSemEventSetSignaller and friends for OS/2 */
+}
+
+
+RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+
+}
+
+
+RTDECL(void) RTSemEventRemoverSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+
+}
+
+
 
 
Index: /trunk/src/VBox/Runtime/r3/posix/semevent-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/semevent-posix.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/r3/posix/semevent-posix.cpp	(revision 25638)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2007 Sun Microsystems, Inc.
+ * Copyright (C) 2006-2010 Sun Microsystems, Inc.
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -33,8 +33,13 @@
 *******************************************************************************/
 #include <iprt/semaphore.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
 #include <iprt/assert.h>
-#include <iprt/alloc.h>
-#include <iprt/asm.h>
 #include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/lockvalidator.h>
+
+#include "internal/strict.h"
 
 #include <errno.h>
@@ -72,4 +77,10 @@
     /** Number of waiters. */
     volatile uint32_t   cWaiters;
+#ifdef RTSEMEVENT_STRICT
+    /** Signallers. */
+    RTLOCKVALRECSHRD    Signallers;
+    /** Indicates that lock validation should be performed. */
+    bool volatile       fEverHadSignallers;
+#endif
 };
 
@@ -85,25 +96,4 @@
 
 
-/**
- * Validate an Event semaphore handle passed to one of the interface.
- *
- * @returns true if valid.
- * @returns false if invalid.
- * @param   pIntEventSem    Pointer to the event semaphore to validate.
- */
-inline bool rtsemEventValid(struct RTSEMEVENTINTERNAL *pIntEventSem)
-{
-    if ((uintptr_t)pIntEventSem < 0x10000)
-        return false;
-
-    uint32_t    u32 = pIntEventSem->u32State; /* this is volatile, so a explicit read like this is needed. */
-    if (    u32 != EVENT_STATE_NOT_SIGNALED
-        &&  u32 != EVENT_STATE_SIGNALED)
-        return false;
-
-    return true;
-}
-
-
 RTDECL(int)  RTSemEventCreate(PRTSEMEVENT pEventSem)
 {
@@ -113,6 +103,6 @@
      * Allocate semaphore handle.
      */
-    struct RTSEMEVENTINTERNAL *pIntEventSem = (struct RTSEMEVENTINTERNAL *)RTMemAlloc(sizeof(struct RTSEMEVENTINTERNAL));
-    if (pIntEventSem)
+    struct RTSEMEVENTINTERNAL *pThis = (struct RTSEMEVENTINTERNAL *)RTMemAlloc(sizeof(struct RTSEMEVENTINTERNAL));
+    if (pThis)
     {
         /*
@@ -123,5 +113,5 @@
         if (!rc)
         {
-            rc = pthread_cond_init(&pIntEventSem->Cond, &CondAttr);
+            rc = pthread_cond_init(&pThis->Cond, &CondAttr);
             if (!rc)
             {
@@ -133,5 +123,5 @@
                 if (!rc)
                 {
-                    rc = pthread_mutex_init(&pIntEventSem->Mutex, &MutexAttr);
+                    rc = pthread_mutex_init(&pThis->Mutex, &MutexAttr);
                     if (!rc)
                     {
@@ -139,13 +129,19 @@
                         pthread_condattr_destroy(&CondAttr);
 
-                        ASMAtomicXchgU32(&pIntEventSem->u32State, EVENT_STATE_NOT_SIGNALED);
-                        ASMAtomicXchgU32(&pIntEventSem->cWaiters, 0);
-
-                        *pEventSem = pIntEventSem;
+                        ASMAtomicXchgU32(&pThis->u32State, EVENT_STATE_NOT_SIGNALED);
+                        ASMAtomicXchgU32(&pThis->cWaiters, 0);
+#ifdef RTSEMEVENT_STRICT
+                        RTLockValidatorRecSharedInit(&pThis->Signallers,
+                                                     NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_ANY,
+                                                     "RTSemEvent", pThis, true /*fSignaller*/);
+                        pThis->fEverHadSignallers = false;
+#endif
+
+                        *pEventSem = pThis;
                         return VINF_SUCCESS;
                     }
                     pthread_mutexattr_destroy(&MutexAttr);
                 }
-                pthread_cond_destroy(&pIntEventSem->Cond);
+                pthread_cond_destroy(&pThis->Cond);
             }
             pthread_condattr_destroy(&CondAttr);
@@ -153,5 +149,5 @@
 
         rc = RTErrConvertFromErrno(rc);
-        RTMemFree(pIntEventSem);
+        RTMemFree(pThis);
     }
     else
@@ -167,25 +163,22 @@
      * Validate handle.
      */
-    if (EventSem == NIL_RTSEMEVENT)     /* don't bitch */
+    struct RTSEMEVENTINTERNAL *pThis = EventSem;
+    if (pThis == NIL_RTSEMEVENT)        /* don't bitch */
         return VERR_INVALID_HANDLE;
-    if (!rtsemEventValid(EventSem))
-    {
-        AssertMsgFailed(("Invalid handle %p!\n", EventSem));
-        return VERR_INVALID_HANDLE;
-    }
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    uint32_t    u32 = pThis->u32State;
+    AssertReturn(u32 == EVENT_STATE_NOT_SIGNALED || u32 == EVENT_STATE_SIGNALED, VERR_INVALID_HANDLE);
 
     /*
      * Abort all waiters forcing them to return failure.
-     *
-     */
-    struct RTSEMEVENTINTERNAL *pIntEventSem = EventSem;
+     */
     int rc;
     for (int i = 30; i > 0; i--)
     {
-        ASMAtomicXchgU32(&pIntEventSem->u32State, EVENT_STATE_UNINITIALIZED);
-        rc = pthread_cond_destroy(&pIntEventSem->Cond);
+        ASMAtomicXchgU32(&pThis->u32State, EVENT_STATE_UNINITIALIZED);
+        rc = pthread_cond_destroy(&pThis->Cond);
         if (rc != EBUSY)
             break;
-        pthread_cond_broadcast(&pIntEventSem->Cond);
+        pthread_cond_broadcast(&pThis->Cond);
         usleep(1000);
     }
@@ -202,5 +195,5 @@
     for (int i = 30; i > 0; i--)
     {
-        rc = pthread_mutex_destroy(&pIntEventSem->Mutex);
+        rc = pthread_mutex_destroy(&pThis->Mutex);
         if (rc != EBUSY)
             break;
@@ -216,5 +209,8 @@
      * Free the semaphore memory and be gone.
      */
-    RTMemFree(pIntEventSem);
+#ifdef RTSEMEVENT_STRICT
+    RTLockValidatorRecSharedDelete(&pThis->Signallers);
+#endif
+    RTMemFree(pThis);
     return VINF_SUCCESS;
 }
@@ -226,15 +222,22 @@
      * Validate input.
      */
-    if (!rtsemEventValid(EventSem))
-    {
-        AssertMsgFailed(("Invalid handle %p!\n", EventSem));
-        return VERR_INVALID_HANDLE;
-    }
+    struct RTSEMEVENTINTERNAL *pThis = EventSem;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    uint32_t    u32 = pThis->u32State;
+    AssertReturn(u32 == EVENT_STATE_NOT_SIGNALED || u32 == EVENT_STATE_SIGNALED, VERR_INVALID_HANDLE);
+
+#ifdef RTSEMEVENT_STRICT
+    if (pThis->fEverHadSignallers)
+    {
+        int rc9 = RTLockValidatorRecSharedCheckSignaller(&pThis->Signallers, NIL_RTTHREAD);
+        if (RT_FAILURE(rc9))
+            return rc9;
+    }
+#endif
 
     /*
      * Lock the mutex semaphore.
      */
-    struct RTSEMEVENTINTERNAL *pIntEventSem = EventSem;
-    int rc = pthread_mutex_lock(&pIntEventSem->Mutex);
+    int rc = pthread_mutex_lock(&pThis->Mutex);
     if (rc)
     {
@@ -246,13 +249,13 @@
      * Check the state.
      */
-    if (pIntEventSem->u32State == EVENT_STATE_NOT_SIGNALED)
-    {
-        ASMAtomicXchgU32(&pIntEventSem->u32State, EVENT_STATE_SIGNALED);
-        rc = pthread_cond_signal(&pIntEventSem->Cond);
+    if (pThis->u32State == EVENT_STATE_NOT_SIGNALED)
+    {
+        ASMAtomicXchgU32(&pThis->u32State, EVENT_STATE_SIGNALED);
+        rc = pthread_cond_signal(&pThis->Cond);
         AssertMsg(!rc, ("Failed to signal event sem %p, rc=%d.\n", EventSem, rc));
     }
-    else if (pIntEventSem->u32State == EVENT_STATE_SIGNALED)
-    {
-        rc = pthread_cond_signal(&pIntEventSem->Cond); /* give'm another kick... */
+    else if (pThis->u32State == EVENT_STATE_SIGNALED)
+    {
+        rc = pthread_cond_signal(&pThis->Cond); /* give'm another kick... */
         AssertMsg(!rc, ("Failed to signal event sem %p, rc=%d. (2)\n", EventSem, rc));
     }
@@ -263,5 +266,5 @@
      * Release the mutex and return.
      */
-    int rc2 = pthread_mutex_unlock(&pIntEventSem->Mutex);
+    int rc2 = pthread_mutex_unlock(&pThis->Mutex);
     AssertMsg(!rc2, ("Failed to unlock event sem %p, rc=%d.\n", EventSem, rc));
     if (rc)
@@ -274,31 +277,31 @@
 
 
-static int  rtSemEventWait(RTSEMEVENT EventSem, unsigned cMillies, bool fAutoResume)
-{
+DECL_FORCE_INLINE(int) rtSemEventWait(RTSEMEVENT EventSem, unsigned cMillies, bool fAutoResume)
+{
+    PCRTLOCKVALSRCPOS  pSrcPos = NULL;
+
     /*
      * Validate input.
      */
-    if (!rtsemEventValid(EventSem))
-    {
-        AssertMsgFailed(("Invalid handle %p!\n", EventSem));
-        return VERR_INVALID_HANDLE;
-    }
+    struct RTSEMEVENTINTERNAL *pThis = EventSem;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    uint32_t    u32 = pThis->u32State;
+    AssertReturn(u32 == EVENT_STATE_NOT_SIGNALED || u32 == EVENT_STATE_SIGNALED, VERR_INVALID_HANDLE);
 
     /*
      * Timed or indefinite wait?
      */
-    struct RTSEMEVENTINTERNAL *pIntEventSem = EventSem;
     if (cMillies == RT_INDEFINITE_WAIT)
     {
         /* for fairness, yield before going to sleep. */
-        if (    ASMAtomicIncU32(&pIntEventSem->cWaiters) > 1
-            &&  pIntEventSem->u32State == EVENT_STATE_SIGNALED)
+        if (    ASMAtomicIncU32(&pThis->cWaiters) > 1
+            &&  pThis->u32State == EVENT_STATE_SIGNALED)
             pthread_yield();
 
          /* take mutex */
-        int rc = pthread_mutex_lock(&pIntEventSem->Mutex);
+        int rc = pthread_mutex_lock(&pThis->Mutex);
         if (rc)
         {
-            ASMAtomicDecU32(&pIntEventSem->cWaiters);
+            ASMAtomicDecU32(&pThis->cWaiters);
             AssertMsgFailed(("Failed to lock event sem %p, rc=%d.\n", EventSem, rc));
             return RTErrConvertFromErrno(rc);
@@ -308,15 +311,15 @@
         {
             /* check state. */
-            if (pIntEventSem->u32State == EVENT_STATE_SIGNALED)
-            {
-                ASMAtomicXchgU32(&pIntEventSem->u32State, EVENT_STATE_NOT_SIGNALED);
-                ASMAtomicDecU32(&pIntEventSem->cWaiters);
-                rc = pthread_mutex_unlock(&pIntEventSem->Mutex);
+            if (pThis->u32State == EVENT_STATE_SIGNALED)
+            {
+                ASMAtomicXchgU32(&pThis->u32State, EVENT_STATE_NOT_SIGNALED);
+                ASMAtomicDecU32(&pThis->cWaiters);
+                rc = pthread_mutex_unlock(&pThis->Mutex);
                 AssertMsg(!rc, ("Failed to unlock event sem %p, rc=%d.\n", EventSem, rc)); NOREF(rc);
                 return VINF_SUCCESS;
             }
-            if (pIntEventSem->u32State == EVENT_STATE_UNINITIALIZED)
-            {
-                rc = pthread_mutex_unlock(&pIntEventSem->Mutex);
+            if (pThis->u32State == EVENT_STATE_UNINITIALIZED)
+            {
+                rc = pthread_mutex_unlock(&pThis->Mutex);
                 AssertMsg(!rc, ("Failed to unlock event sem %p, rc=%d.\n", EventSem, rc)); NOREF(rc);
                 return VERR_SEM_DESTROYED;
@@ -324,10 +327,28 @@
 
             /* wait */
-            rc = pthread_cond_wait(&pIntEventSem->Cond, &pIntEventSem->Mutex);
+#ifdef RTSEMEVENT_STRICT
+            RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
+            if (pThis->fEverHadSignallers)
+            {
+                rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
+                                                           RTTHREADSTATE_EVENT, true);
+                if (RT_FAILURE(rc))
+                {
+                    ASMAtomicDecU32(&pThis->cWaiters);
+                    pthread_mutex_unlock(&pThis->Mutex);
+                    return rc;
+                }
+            }
+#else
+            RTTHREAD hThreadSelf = RTThreadSelf();
+#endif
+            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT, true);
+            rc = pthread_cond_wait(&pThis->Cond, &pThis->Mutex);
+            RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT);
             if (rc)
             {
                 AssertMsgFailed(("Failed to wait on event sem %p, rc=%d.\n", EventSem, rc));
-                ASMAtomicDecU32(&pIntEventSem->cWaiters);
-                int rc2 = pthread_mutex_unlock(&pIntEventSem->Mutex);
+                ASMAtomicDecU32(&pThis->cWaiters);
+                int rc2 = pthread_mutex_unlock(&pThis->Mutex);
                 AssertMsg(!rc2, ("Failed to unlock event sem %p, rc=%d.\n", EventSem, rc2)); NOREF(rc2);
                 return RTErrConvertFromErrno(rc);
@@ -361,16 +382,12 @@
 
         /* for fairness, yield before going to sleep. */
-        if (ASMAtomicIncU32(&pIntEventSem->cWaiters) > 1)
+        if (ASMAtomicIncU32(&pThis->cWaiters) > 1 && cMillies)
             pthread_yield();
 
         /* take mutex */
-#ifdef RT_OS_DARWIN
-        int rc = pthread_mutex_lock(&pIntEventSem->Mutex);
-#else
-        int rc = pthread_mutex_timedlock(&pIntEventSem->Mutex, &ts);
-#endif
+        int rc = pthread_mutex_lock(&pThis->Mutex);
         if (rc)
         {
-            ASMAtomicDecU32(&pIntEventSem->cWaiters);
+            ASMAtomicDecU32(&pThis->cWaiters);
             AssertMsg(rc == ETIMEDOUT, ("Failed to lock event sem %p, rc=%d.\n", EventSem, rc));
             return RTErrConvertFromErrno(rc);
@@ -380,26 +397,52 @@
         {
             /* check state. */
-            if (pIntEventSem->u32State == EVENT_STATE_SIGNALED)
-            {
-                ASMAtomicXchgU32(&pIntEventSem->u32State, EVENT_STATE_NOT_SIGNALED);
-                ASMAtomicDecU32(&pIntEventSem->cWaiters);
-                rc = pthread_mutex_unlock(&pIntEventSem->Mutex);
+            if (pThis->u32State == EVENT_STATE_SIGNALED)
+            {
+                ASMAtomicXchgU32(&pThis->u32State, EVENT_STATE_NOT_SIGNALED);
+                ASMAtomicDecU32(&pThis->cWaiters);
+                rc = pthread_mutex_unlock(&pThis->Mutex);
                 AssertMsg(!rc, ("Failed to unlock event sem %p, rc=%d.\n", EventSem, rc)); NOREF(rc);
                 return VINF_SUCCESS;
             }
-            if (pIntEventSem->u32State == EVENT_STATE_UNINITIALIZED)
-            {
-                rc = pthread_mutex_unlock(&pIntEventSem->Mutex);
+            if (pThis->u32State == EVENT_STATE_UNINITIALIZED)
+            {
+                rc = pthread_mutex_unlock(&pThis->Mutex);
                 AssertMsg(!rc, ("Failed to unlock event sem %p, rc=%d.\n", EventSem, rc)); NOREF(rc);
                 return VERR_SEM_DESTROYED;
             }
 
+            /* we're done if the timeout is 0. */
+            if (!cMillies)
+            {
+                ASMAtomicDecU32(&pThis->cWaiters);
+                rc = pthread_mutex_unlock(&pThis->Mutex);
+                return VERR_SEM_BUSY;
+            }
+
             /* wait */
-            rc = pthread_cond_timedwait(&pIntEventSem->Cond, &pIntEventSem->Mutex, &ts);
+#ifdef RTSEMEVENT_STRICT
+            RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
+            if (pThis->fEverHadSignallers)
+            {
+                rc = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
+                                                           RTTHREADSTATE_EVENT, true);
+                if (RT_FAILURE(rc))
+                {
+                    ASMAtomicDecU32(&pThis->cWaiters);
+                    pthread_mutex_unlock(&pThis->Mutex);
+                    return rc;
+                }
+            }
+#else
+            RTTHREAD hThreadSelf = RTThreadSelf();
+#endif
+            RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT, true);
+            rc = pthread_cond_timedwait(&pThis->Cond, &pThis->Mutex, &ts);
+            RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT);
             if (rc && (rc != EINTR || !fAutoResume)) /* according to SuS this function shall not return EINTR, but linux man page says differently. */
             {
                 AssertMsg(rc == ETIMEDOUT, ("Failed to wait on event sem %p, rc=%d.\n", EventSem, rc));
-                ASMAtomicDecU32(&pIntEventSem->cWaiters);
-                int rc2 = pthread_mutex_unlock(&pIntEventSem->Mutex);
+                ASMAtomicDecU32(&pThis->cWaiters);
+                int rc2 = pthread_mutex_unlock(&pThis->Mutex);
                 AssertMsg(!rc2, ("Failed to unlock event sem %p, rc2=%d.\n", EventSem, rc2)); NOREF(rc2);
                 return RTErrConvertFromErrno(rc);
@@ -423,2 +466,43 @@
 }
 
+
+RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+#ifdef RTSEMEVENT_STRICT
+    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
+    AssertPtrReturnVoid(pThis);
+    uint32_t u32 = pThis->u32State;
+    AssertReturnVoid(u32 == EVENT_STATE_NOT_SIGNALED || u32 == EVENT_STATE_SIGNALED);
+
+    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
+    RTLockValidatorRecSharedResetOwner(&pThis->Signallers, hThread, NULL);
+#endif
+}
+
+
+RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+#ifdef RTSEMEVENT_STRICT
+    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
+    AssertPtrReturnVoid(pThis);
+    uint32_t u32 = pThis->u32State;
+    AssertReturnVoid(u32 == EVENT_STATE_NOT_SIGNALED || u32 == EVENT_STATE_SIGNALED);
+
+    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
+    RTLockValidatorRecSharedAddOwner(&pThis->Signallers, hThread, NULL);
+#endif
+}
+
+
+RTDECL(void) RTSemEventRemoveSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+#ifdef RTSEMEVENT_STRICT
+    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
+    AssertPtrReturnVoid(pThis);
+    uint32_t u32 = pThis->u32State;
+    AssertReturnVoid(u32 == EVENT_STATE_NOT_SIGNALED || u32 == EVENT_STATE_SIGNALED);
+
+    RTLockValidatorRecSharedRemoveOwner(&pThis->Signallers, hThread);
+#endif
+}
+
Index: /trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp	(revision 25638)
@@ -188,10 +188,11 @@
 #ifdef RTSEMMUTEX_STRICT
         hThreadSelf = RTThreadSelfAutoAdopt();
-        int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true, RTTHREADSTATE_MUTEX);
+        int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true,
+                                                              RTTHREADSTATE_MUTEX, true);
         if (RT_FAILURE(rc9))
             return rc9;
 #else
         hThreadSelf = RTThreadSelf();
-        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX);
+        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, true);
 #endif
     }
Index: /trunk/src/VBox/Runtime/r3/posix/semrw-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/semrw-posix.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/r3/posix/semrw-posix.cpp	(revision 25638)
@@ -127,5 +127,5 @@
 #ifdef RTSEMRW_STRICT
                 RTLockValidatorRecExclInit(&pThis->ValidatorWrite, NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis);
-                RTLockValidatorRecSharedInit(&pThis->ValidatorRead,  NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis);
+                RTLockValidatorRecSharedInit(&pThis->ValidatorRead,  NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemRW", pThis, false /*fSignaller*/);
                 RTLockValidatorRecMakeSiblings(&pThis->ValidatorWrite.Core, &pThis->ValidatorRead.Core);
 #endif
@@ -224,10 +224,11 @@
 #ifdef RTSEMRW_STRICT
         hThreadSelf = RTThreadSelfAutoAdopt();
-        int rc9 = RTLockValidatorRecSharedCheckOrderAndBlocking(&pThis->ValidatorRead, hThreadSelf, pSrcPos, true, RTTHREADSTATE_RW_READ);
+        int rc9 = RTLockValidatorRecSharedCheckOrderAndBlocking(&pThis->ValidatorRead, hThreadSelf, pSrcPos, true,
+                                                                RTTHREADSTATE_RW_READ, true);
         if (RT_FAILURE(rc9))
             return rc9;
 #else
         hThreadSelf = RTThreadSelf();
-        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_READ);
+        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_READ, true);
 #endif
     }
@@ -280,5 +281,5 @@
     ASMAtomicIncU32(&pThis->cReaders);
 #ifdef RTSEMRW_STRICT
-    RTLockValidatorSharedRecAddOwner(&pThis->ValidatorRead, hThreadSelf, pSrcPos);
+    RTLockValidatorRecSharedAddOwner(&pThis->ValidatorRead, hThreadSelf, pSrcPos);
 #endif
     return VINF_SUCCESS;
@@ -416,10 +417,11 @@
 #ifdef RTSEMRW_STRICT
         hThreadSelf = RTThreadSelfAutoAdopt();
-        int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorWrite, hThreadSelf, pSrcPos, true, RTTHREADSTATE_RW_WRITE);
+        int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorWrite, hThreadSelf, pSrcPos, true,
+                                                              RTTHREADSTATE_RW_WRITE, true);
         if (RT_FAILURE(rc9))
             return rc9;
 #else
         hThreadSelf = RTThreadSelf();
-        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE);
+        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_RW_WRITE, true);
 #endif
     }
Index: /trunk/src/VBox/Runtime/r3/posix/thread-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/thread-posix.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/r3/posix/thread-posix.cpp	(revision 25638)
@@ -37,4 +37,8 @@
 #include <pthread.h>
 #include <signal.h>
+#if defined(RT_OS_LINUX)
+# include <unistd.h>
+# include <sys/syscall.h>
+#endif
 #if defined(RT_OS_SOLARIS)
 # include <sched.h>
@@ -170,4 +174,12 @@
     PRTTHREADINT  pThread = (PRTTHREADINT)pvArgs;
 
+#if defined(RT_OS_LINUX)
+    /*
+     * Set the TID.
+     */
+    pThread->tid = syscall(__NR_gettid);
+    ASMMemoryFence();
+#endif
+
     /*
      * Block SIGALRM - required for timer-posix.cpp.
@@ -204,4 +216,8 @@
     if (!pThread->cbStack)
         pThread->cbStack = 512*1024;
+
+#ifdef RT_OS_LINUX
+    pThread->tid = -1;
+#endif
 
     /*
Index: /trunk/src/VBox/Runtime/r3/win/semevent-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/semevent-win.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/r3/win/semevent-win.cpp	(revision 25638)
@@ -124,2 +124,20 @@
 }
 
+
+RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+/** @todo implement RTSemEventSetSignaller and friends for NT. */
+}
+
+
+RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+
+}
+
+
+RTDECL(void) RTSemEventRemoverSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
+{
+
+}
+
Index: /trunk/src/VBox/Runtime/r3/win/semmutex-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/semmutex-win.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/r3/win/semmutex-win.cpp	(revision 25638)
@@ -182,10 +182,11 @@
 #ifdef RTSEMMUTEX_STRICT
         hThreadSelf = RTThreadSelfAutoAdopt();
-        int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true, RTTHREADSTATE_MUTEX);
+        int rc9 = RTLockValidatorRecExclCheckOrderAndBlocking(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true,
+                                                              RTTHREADSTATE_MUTEX, true);
         if (RT_FAILURE(rc9))
             return rc9;
 #else
         hThreadSelf = RTThreadSelf();
-        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX);
+        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_MUTEX, true);
 #endif
     }
Index: /trunk/src/VBox/Runtime/testcase/tstRTLockValidator.cpp
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstRTLockValidator.cpp	(revision 25637)
+++ /trunk/src/VBox/Runtime/testcase/tstRTLockValidator.cpp	(revision 25638)
@@ -58,4 +58,11 @@
 static RTSEMRW              g_ahSemRWs[32];
 static RTSEMMUTEX           g_ahSemMtxes[32];
+static RTSEMEVENT           g_hSemEvt;
+static RTSEMEVENTMULTI      g_hSemEvtMulti;
+
+/** Multiple release event semaphore that is signalled by the main thread after
+ * it has started all the threads. */
+static RTSEMEVENTMULTI      g_hThreadStarteEvt;
+
 
 /** When to stop testing. */
@@ -75,4 +82,7 @@
 static bool testWaitForCritSectToBeOwned(PRTCRITSECT pCritSect)
 {
+    RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
+    RTTEST_CHECK_RC_OK(g_hTest, RTSemEventMultiWait(g_hThreadStarteEvt, 10*1000));
+
     unsigned iLoop = 0;
     while (!RTCritSectIsOwned(pCritSect))
@@ -97,4 +107,6 @@
 {
     RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
+    RTTEST_CHECK_RC_OK(g_hTest, RTSemEventMultiWait(g_hThreadStarteEvt, 10*1000));
+
     unsigned iLoop = 0;
     for (;;)
@@ -119,4 +131,7 @@
 static bool testWaitForSemMutexToBeOwned(RTSEMMUTEX hSemMutex)
 {
+    RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
+    RTTEST_CHECK_RC_OK(g_hTest, RTSemEventMultiWait(g_hThreadStarteEvt, 10*1000));
+
     unsigned iLoop = 0;
     while (!RTSemMutexIsOwned(hSemMutex))
@@ -126,36 +141,4 @@
     }
     return true;
-}
-
-
-/**
- * Waits for a thread to enter a sleeping state.
- *
- * @returns true on success, false on abort.
- * @param   hThread             The thread.
- * @param   enmDesiredState     The desired thread sleep state.
- * @param   pvLock              The lock it should be sleeping on.
- */
-static bool testWaitForThreadToSleep(RTTHREAD hThread, RTTHREADSTATE enmDesiredState, void *pvLock)
-{
-    RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
-    for (unsigned iLoop = 0; ; iLoop++)
-    {
-        RTTHREADSTATE enmState = RTThreadGetState(hThread);
-        if (RTTHREAD_IS_SLEEPING(enmState))
-        {
-            if (   enmState == enmDesiredState
-                && (   !pvLock
-                    || (   pvLock == RTLockValidatorQueryBlocking(hThread)
-                        && !RTLockValidatorIsBlockedThreadInValidator(hThread) )
-                   )
-               )
-                return true;
-        }
-        else if (   enmState != RTTHREADSTATE_RUNNING
-                 && enmState != RTTHREADSTATE_INITIALIZING)
-            return false;
-        RTThreadSleep(g_fDoNotSpin ? 3600*1000 : iLoop > 256 ? 1 : 0);
-    }
 }
 
@@ -172,30 +155,68 @@
 static int testWaitForAllOtherThreadsToSleep(RTTHREADSTATE enmDesiredState, uint32_t cWaitOn)
 {
+    RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
+    RTTEST_CHECK_RC_OK(g_hTest, RTSemEventMultiWait(g_hThreadStarteEvt, 10*1000));
+
     RTTHREAD hThreadSelf = RTThreadSelf();
-    for (uint32_t i = 0; i < g_cThreads; i++)
-    {
-        RTTHREAD hThread = g_ahThreads[i];
-        if (    hThread != NIL_RTTHREAD
-            &&  hThread != hThreadSelf)
-        {
-            void *pvLock = NULL;
-            if (cWaitOn != UINT32_MAX)
+    for (uint32_t iOuterLoop = 0; ; iOuterLoop++)
+    {
+        uint32_t cMissing  = 0;
+        uint32_t cWaitedOn = 0;
+        for (uint32_t i = 0; i < g_cThreads; i++)
+        {
+            RTTHREAD hThread = g_ahThreads[i];
+            if (hThread == NIL_RTTHREAD)
+                cMissing++;
+            else if (hThread != hThreadSelf)
             {
-                uint32_t j = (i + cWaitOn) % g_cThreads;
-                switch (enmDesiredState)
+                /*
+                 * Figure out which lock to wait for.
+                 */
+                void *pvLock = NULL;
+                if (cWaitOn != UINT32_MAX)
                 {
-                    case RTTHREADSTATE_CRITSECT:    pvLock = &g_aCritSects[j]; break;
-                    case RTTHREADSTATE_RW_WRITE:
-                    case RTTHREADSTATE_RW_READ:     pvLock = g_ahSemRWs[j]; break;
-                    case RTTHREADSTATE_MUTEX:       pvLock = g_ahSemMtxes[j]; break;
-                    default: break;
+                    uint32_t j = (i + cWaitOn) % g_cThreads;
+                    switch (enmDesiredState)
+                    {
+                        case RTTHREADSTATE_CRITSECT:    pvLock = &g_aCritSects[j]; break;
+                        case RTTHREADSTATE_RW_WRITE:
+                        case RTTHREADSTATE_RW_READ:     pvLock = g_ahSemRWs[j]; break;
+                        case RTTHREADSTATE_MUTEX:       pvLock = g_ahSemMtxes[j]; break;
+                        default: break;
+                    }
+                }
+
+                /*
+                 * Wait for this thread.
+                 */
+                for (unsigned iLoop = 0; ; iLoop++)
+                {
+                    RTTHREADSTATE enmState = RTThreadGetReallySleeping(hThread);
+                    if (RTTHREAD_IS_SLEEPING(enmState))
+                    {
+                        if (   enmState == enmDesiredState
+                            && (   !pvLock
+                                || (   pvLock == RTLockValidatorQueryBlocking(hThread)
+                                    && !RTLockValidatorIsBlockedThreadInValidator(hThread) )
+                               )
+                            && RTThreadGetNativeState(hThread) != RTTHREADNATIVESTATE_RUNNING
+                           )
+                            break;
+                    }
+                    else if (   enmState != RTTHREADSTATE_RUNNING
+                             && enmState != RTTHREADSTATE_INITIALIZING)
+                        return VERR_INTERNAL_ERROR;
+                    RTThreadSleep(g_fDoNotSpin ? 3600*1000 : iOuterLoop + iLoop > 256 ? 1 : 0);
+                    cWaitedOn++;
                 }
             }
-            bool fRet = testWaitForThreadToSleep(hThread, enmDesiredState, pvLock);
-            if (!fRet)
-                return VERR_INTERNAL_ERROR;
-        }
-    }
-    RTThreadSleep(4);                   /* fudge factor */
+        }
+
+        if (!cMissing && !cWaitedOn)
+            break;
+        RTThreadSleep(g_fDoNotSpin ? 3600*1000 : iOuterLoop > 256 ? 1 : 0);
+    }
+
+    RTThreadSleep(0);                   /* fudge factor */
     return VINF_SUCCESS;
 }
@@ -211,14 +232,21 @@
 static int testStartThreads(uint32_t cThreads, PFNRTTHREAD pfnThread)
 {
-    uint32_t i;
-    for (i = 0; i < RT_ELEMENTS(g_ahThreads); i++)
+    RTSemEventMultiReset(g_hThreadStarteEvt);
+
+    for (uint32_t i = 0; i < RT_ELEMENTS(g_ahThreads); i++)
         g_ahThreads[i] = NIL_RTTHREAD;
 
-    for (i = 0; i < cThreads; i++)
-        RTTEST_CHECK_RC_OK_RET(g_hTest,
-                               RTThreadCreateF(&g_ahThreads[i], pfnThread, (void *)(uintptr_t)i, 0,
-                                               RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "thread-%02u", i),
-                               rcCheck);
-    return VINF_SUCCESS;
+    int rc = VINF_SUCCESS;
+    for (uint32_t i = 0; i < cThreads; i++)
+    {
+        rc = RTThreadCreateF(&g_ahThreads[i], pfnThread, (void *)(uintptr_t)i, 0,
+                             RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "thread-%02u", i);
+        RTTEST_CHECK_RC_OK(g_hTest, rc);
+        if (RT_FAILURE(rc))
+            break;
+    }
+
+    RTTEST_CHECK_RC_OK_RET(g_hTest, RTSemEventMultiSignal(g_hThreadStarteEvt), rcCheck);
+    return rc;
 }
 
@@ -250,4 +278,7 @@
 static void testIt(uint32_t cThreads, uint32_t cPasses, uint32_t cSecs, PFNRTTHREAD pfnThread, const char *pszName)
 {
+    /*
+     * Init test.
+     */
     if (cSecs)
         RTTestSubF(g_hTest, "%s, %u threads, %u secs", pszName, cThreads, cSecs * cPasses);
@@ -266,5 +297,11 @@
         RTTEST_CHECK_RC_RETV(g_hTest, RTSemMutexCreate(&g_ahSemMtxes[i]), VINF_SUCCESS);
     }
-
+    RTTEST_CHECK_RC_RETV(g_hTest, RTSemEventCreate(&g_hSemEvt), VINF_SUCCESS);
+    RTTEST_CHECK_RC_RETV(g_hTest, RTSemEventMultiCreate(&g_hSemEvtMulti), VINF_SUCCESS);
+    RTTEST_CHECK_RC_RETV(g_hTest, RTSemEventMultiCreate(&g_hThreadStarteEvt), VINF_SUCCESS);
+
+    /*
+     * The test loop.
+     */
     uint32_t cLoops     = 0;
     uint32_t cDeadlocks = 0;
@@ -287,4 +324,7 @@
     }
 
+    /*
+     * Cleanup.
+     */
     for (uint32_t i = 0; i < cThreads; i++)
     {
@@ -293,6 +333,13 @@
         RTTEST_CHECK_RC(g_hTest, RTSemMutexDestroy(g_ahSemMtxes[i]), VINF_SUCCESS);
     }
+    RTTEST_CHECK_RC(g_hTest, RTSemEventDestroy(g_hSemEvt), VINF_SUCCESS);
+    RTTEST_CHECK_RC(g_hTest, RTSemEventMultiDestroy(g_hSemEvtMulti), VINF_SUCCESS);
+    RTTEST_CHECK_RC(g_hTest, RTSemEventMultiDestroy(g_hThreadStarteEvt), VINF_SUCCESS);
+
     testWaitForThreads(10*1000, false);
 
+    /*
+     * Print results if applicable.
+     */
     if (cSecs)
         RTTestPrintf(g_hTest,  RTTESTLVL_ALWAYS, "cLoops=%u cDeadlocks=%u (%u%%)\n",
@@ -531,4 +578,56 @@
 
 
+static DECLCALLBACK(int) test6Thread(RTTHREAD ThreadSelf, void *pvUser)
+{
+    uintptr_t       i     = (uintptr_t)pvUser;
+    PRTCRITSECT     pMine = &g_aCritSects[i];
+    PRTCRITSECT     pNext = &g_aCritSects[(i + 1) % g_cThreads];
+
+    RTTEST_CHECK_RC_RET(g_hTest, RTCritSectEnter(pMine), VINF_SUCCESS, rcCheck);
+    if (i & 1)
+        RTTEST_CHECK_RC(g_hTest, RTCritSectEnter(pMine), VINF_SUCCESS);
+    if (testWaitForCritSectToBeOwned(pNext))
+    {
+        int rc;
+        if (i != g_iDeadlockThread)
+        {
+            RTTEST_CHECK_RC(g_hTest, rc = RTCritSectEnter(pNext), VINF_SUCCESS);
+            RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
+            if (RT_SUCCESS(rc))
+                RTTEST_CHECK_RC(g_hTest, rc = RTCritSectLeave(pNext), VINF_SUCCESS);
+        }
+        else
+        {
+            RTTEST_CHECK_RC_OK(g_hTest, rc = testWaitForAllOtherThreadsToSleep(RTTHREADSTATE_CRITSECT, 1));
+            if (RT_SUCCESS(rc))
+            {
+                RTSemEventSetSignaller(g_hSemEvt, g_ahThreads[0]);
+                for (uint32_t iThread = 1; iThread < g_cThreads; iThread++)
+                    RTSemEventAddSignaller(g_hSemEvt, g_ahThreads[iThread]);
+                RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
+                RTTEST_CHECK_RC(g_hTest, RTSemEventWait(g_hSemEvt, 10*1000), VERR_SEM_LV_DEADLOCK);
+                RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
+                RTTEST_CHECK_RC(g_hTest, RTSemEventSignal(g_hSemEvt), VINF_SUCCESS);
+                RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
+                RTTEST_CHECK_RC(g_hTest, RTSemEventWait(g_hSemEvt, 10*1000), VINF_SUCCESS);
+                RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
+                RTSemEventSetSignaller(g_hSemEvt, NIL_RTTHREAD);
+            }
+        }
+        RTTEST_CHECK(g_hTest, RTThreadGetState(RTThreadSelf()) == RTTHREADSTATE_RUNNING);
+    }
+    if (i & 1)
+        RTTEST_CHECK_RC(g_hTest, RTCritSectLeave(pMine), VINF_SUCCESS);
+    RTTEST_CHECK_RC(g_hTest, RTCritSectLeave(pMine), VINF_SUCCESS);
+    return VINF_SUCCESS;
+}
+
+
+static void test6(uint32_t cThreads, uint32_t cPasses)
+{
+    testIt(cThreads, cPasses, 0, test6Thread, "event");
+}
+
+
 static bool testIsLockValidationCompiledIn(void)
 {
@@ -551,4 +650,24 @@
     RTTEST_CHECK_RC_OK_RET(g_hTest, RTSemRWDestroy(hSemRW), false);
 
+#if 0 /** @todo detect it on RTSemMutex... */
+    RTSEMMUTEX hSemMtx;
+    RTTEST_CHECK_RC_OK_RET(g_hTest, RTSemMutexCreate(&hSemRW), false);
+    RTTEST_CHECK_RC_OK_RET(g_hTest, RTSemMutexRequest(hSemRW, 50), false);
+    /*??*/
+    RTTEST_CHECK_RET(g_hTest, RT_FAILURE_NP(rc), false);
+    RTTEST_CHECK_RC_OK_RET(g_hTest, RTSemRWRelease(hSemRW), false);
+    RTTEST_CHECK_RC_OK_RET(g_hTest, RTSemRWDestroy(hSemRW), false);
+#endif
+
+    RTSEMEVENT hSemEvt;
+    RTTEST_CHECK_RC_OK_RET(g_hTest, RTSemEventCreate(&hSemEvt), false);
+    RTSemEventSetSignaller(hSemEvt, RTThreadSelf());
+    RTSemEventSetSignaller(hSemEvt, NIL_RTTHREAD);
+    rc = RTSemEventSignal(hSemEvt);
+    if (rc != VERR_SEM_LV_NOT_SIGNALLER)
+        fRet = false;
+    RTTEST_CHECK_RET(g_hTest, RT_FAILURE_NP(rc), false);
+    RTTEST_CHECK_RC_OK_RET(g_hTest, RTSemEventDestroy(hSemEvt), false);
+
     return fRet;
 }
@@ -577,10 +696,11 @@
      * Some initial tests with verbose output.
      */
-#if 0
+#if 1
     test1(3, 1);
     test2(1, 1);
     test2(3, 1);
+    test5(3, 1);
+    test6(3, 1);
 #endif
-    test5(3, 1);
 
     /*
@@ -588,5 +708,4 @@
      */
     RTLockValidatorSetQuiet(true);
-#if 0
     test1( 2, 256);                     /* 256 * 4ms = 1s (approx); 4ms == fudge factor */
     test1( 3, 256);
@@ -596,4 +715,5 @@
     test1(30, 256);
 
+#if 1
     test2( 1, 256);
     test2( 2, 256);
@@ -611,5 +731,4 @@
     test4(10,  1, 10);
     test4(30,  1, 10);
-#endif
 
     test5( 2, 256);
@@ -619,4 +738,12 @@
     test5(15, 256);
     test5(30, 256);
+#endif
+
+    test6( 2, 256);
+    test6( 3, 256);
+    test6( 7, 256);
+    test6(10, 256);
+    test6(15, 256);
+    test6(30, 256);
 
     return RTTestSummaryAndDestroy(g_hTest);
Index: /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 25637)
+++ /trunk/src/VBox/VMM/VMMAll/PDMAllCritSect.cpp	(revision 25638)
@@ -140,9 +140,9 @@
         int rc9 = RTLockValidatorRecExclCheckBlocking(pCritSect->s.Core.pValidatorRec, hThreadSelf, pSrcPos,
                                                       !(pCritSect->s.Core.fFlags & RTCRITSECT_FLAGS_NO_NESTING),
-                                                      RTTHREADSTATE_CRITSECT);
+                                                      RTTHREADSTATE_CRITSECT, true);
         if (RT_FAILURE(rc9))
             return rc9;
 # else
-        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_CRITSECT);
+        RTThreadBlocking(hThreadSelf, RTTHREADSTATE_CRITSECT, true);
 # endif
         int rc = SUPSemEventWaitNoResume(pSession, hEvent, RT_INDEFINITE_WAIT);
