Index: /trunk/src/VBox/Runtime/r3/win/semevent-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/semevent-win.cpp	(revision 25652)
+++ /trunk/src/VBox/Runtime/r3/win/semevent-win.cpp	(revision 25653)
@@ -37,7 +37,13 @@
 
 #include <iprt/semaphore.h>
-#include <iprt/thread.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
 #include <iprt/assert.h>
 #include <iprt/err.h>
+#include <iprt/lockvalidator.h>
+#include <iprt/mem.h>
+#include <iprt/thread.h>
+#include "internal/magics.h"
 #include "internal/strict.h"
 
@@ -46,6 +52,17 @@
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
-/** Converts semaphore to win32 handle. */
-#define SEM2HND(Sem) ((HANDLE)(uintptr_t)Sem)
+struct RTSEMEVENTINTERNAL
+{
+    /** Magic value (RTSEMEVENT_MAGIC). */
+    uint32_t            u32Magic;
+    /** The event handle. */
+    HANDLE              hev;
+#ifdef RTSEMEVENT_STRICT
+    /** Signallers. */
+    RTLOCKVALRECSHRD    Signallers;
+    /** Indicates that lock validation should be performed. */
+    bool volatile       fEverHadSignallers;
+#endif
+};
 
 
@@ -57,16 +74,30 @@
 RTDECL(int)   RTSemEventCreate(PRTSEMEVENT pEventSem)
 {
+    struct RTSEMEVENTINTERNAL *pThis = (struct RTSEMEVENTINTERNAL *)RTMemAlloc(sizeof(*pThis));
+    if (!pThis)
+        return VERR_NO_MEMORY;
+
     /*
      * Create the semaphore.
      * (Auto reset, not signaled, private event object.)
      */
-    HANDLE hev = CreateEvent(NULL, FALSE, FALSE, NULL);
-    if (hev)
-    {
-        *pEventSem = (RTSEMEVENT)(void *)hev;
-        Assert(*pEventSem != NIL_RTSEMEVENT);
+    pThis->hev = CreateEvent(NULL, FALSE, FALSE, NULL);
+    if (pThis->hev != NULL) /* not INVALID_HANDLE_VALUE */
+    {
+        pThis->u32Magic = RTSEMEVENT_MAGIC;
+#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;
     }
-    return RTErrConvertFromWin32(GetLastError());
+
+    DWORD dwErr = GetLastError();
+    RTMemFree(pThis);
+    return RTErrConvertFromWin32(dwErr);
 }
 
@@ -74,14 +105,31 @@
 RTDECL(int)   RTSemEventDestroy(RTSEMEVENT EventSem)
 {
-    if (EventSem == NIL_RTSEMEVENT)     /* don't bitch */
+    struct RTSEMEVENTINTERNAL *pThis = EventSem;
+    if (pThis == NIL_RTSEMEVENT)        /* don't bitch */
         return VERR_INVALID_HANDLE;
-
-    /*
-     * Close semaphore handle.
-     */
-    if (CloseHandle(SEM2HND(EventSem)))
-        return VINF_SUCCESS;
-    AssertMsgFailed(("Destroy EventSem %p failed, lasterr=%d\n", EventSem, GetLastError()));
-    return RTErrConvertFromWin32(GetLastError());
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE);
+
+    /*
+     * Invalidate the handle and close the semaphore.
+     */
+    int rc = VINF_SUCCESS;
+    AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, ~RTSEMEVENT_MAGIC, RTSEMEVENT_MAGIC), VERR_INVALID_HANDLE);
+    if (CloseHandle(pThis->hev))
+    {
+#ifdef RTSEMEVENT_STRICT
+        RTLockValidatorRecSharedDelete(&pThis->Signallers);
+#endif
+        RTMemFree(pThis);
+    }
+    else
+    {
+        DWORD dwErr = GetLastError();
+        rc = RTErrConvertFromWin32(dwErr);
+        AssertMsgFailed(("Destroy EventSem %p failed, lasterr=%u (%Rrc)\n", pThis, dwErr, rc));
+        /* Leak it. */
+    }
+
+    return rc;
 }
 
@@ -89,8 +137,33 @@
 RTDECL(int)   RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)
 {
+    PCRTLOCKVALSRCPOS pSrcPos = NULL;
+
+    /*
+     * Validate input.
+     */
+    struct RTSEMEVENTINTERNAL *pThis = EventSem;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, VERR_INVALID_HANDLE);
+
     /*
      * Wait for condition.
      */
-    int rc = WaitForSingleObjectEx(SEM2HND(EventSem), cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies, TRUE);
+#ifdef RTSEMEVENT_STRICT
+    RTTHREAD hThreadSelf = RTThreadSelfAutoAdopt();
+    if (pThis->fEverHadSignallers)
+    {
+        int rc9 = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
+                                                        RTTHREADSTATE_EVENT, true);
+        if (RT_FAILURE(rc9))
+            return rc9;
+    }
+#else
+    RTTHREAD hThreadSelf = RTThreadSelf();
+#endif
+    RTThreadBlocking(hThreadSelf, RTTHREADSTATE_EVENT, true);
+    DWORD rc = WaitForSingleObjectEx(pThis->hev,
+                                     cMillies == RT_INDEFINITE_WAIT ? INFINITE : cMillies,
+                                     TRUE /*fAlertable*/);
+    RTThreadUnblocked(hThreadSelf, RTTHREADSTATE_EVENT);
     switch (rc)
     {
@@ -100,4 +173,6 @@
         case WAIT_ABANDONED:        return VERR_SEM_OWNER_DIED;
         default:
+            AssertMsgFailed(("%u\n", rc));
+        case WAIT_FAILED:
         {
             AssertMsgFailed(("Wait on EventSem %p failed, rc=%d lasterr=%d\n", EventSem, rc, GetLastError()));
@@ -116,10 +191,27 @@
 {
     /*
+     * Validate input.
+     */
+    struct RTSEMEVENTINTERNAL *pThis = EventSem;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->u32Magic == 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
+
+    /*
      * Signal the object.
      */
-    if (SetEvent(SEM2HND(EventSem)))
+    if (SetEvent(pThis->hev))
         return VINF_SUCCESS;
-    AssertMsgFailed(("Signaling EventSem %p failed, lasterr=%d\n", EventSem, GetLastError()));
-    return RTErrConvertFromWin32(GetLastError());
+    DWORD dwErr = GetLastError();
+    AssertMsgFailed(("Signaling EventSem %p failed, lasterr=%d\n", pThis, dwErr));
+    return RTErrConvertFromWin32(dwErr);
 }
 
@@ -127,5 +219,12 @@
 RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
 {
-/** @todo implement RTSemEventSetSignaller and friends for NT. */
+#ifdef RTSEMEVENT_STRICT
+    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
+    AssertPtrReturnVoid(pThis);
+    AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC);
+
+    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
+    RTLockValidatorRecSharedResetOwner(&pThis->Signallers, hThread, NULL);
+#endif
 }
 
@@ -133,5 +232,12 @@
 RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
 {
-
+#ifdef RTSEMEVENT_STRICT
+    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
+    AssertPtrReturnVoid(pThis);
+    AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC);
+
+    ASMAtomicWriteBool(&pThis->fEverHadSignallers, true);
+    RTLockValidatorRecSharedAddOwner(&pThis->Signallers, hThread, NULL);
+#endif
 }
 
@@ -139,5 +245,11 @@
 RTDECL(void) RTSemEventRemoveSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread)
 {
-
-}
-
+#ifdef RTSEMEVENT_STRICT
+    struct RTSEMEVENTINTERNAL *pThis = hEventSem;
+    AssertPtrReturnVoid(pThis);
+    AssertReturnVoid(pThis->u32Magic == RTSEMEVENT_MAGIC);
+
+    RTLockValidatorRecSharedRemoveOwner(&pThis->Signallers, hThread);
+#endif
+}
+
