Index: /trunk/include/iprt/semaphore.h
===================================================================
--- /trunk/include/iprt/semaphore.h	(revision 25623)
+++ /trunk/include/iprt/semaphore.h	(revision 25624)
@@ -281,4 +281,12 @@
  */
 RTDECL(int)  RTSemMutexRelease(RTSEMMUTEX MutexSem);
+
+/**
+ * Checks if the mutex semaphore is owned or not.
+ *
+ * @returns true if owned, false if not.
+ * @param   hMutex              The mutex semaphore.
+ */
+RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutex);
 
 /* Strict build: Remap the two request calls to the debug versions. */
Index: /trunk/src/VBox/Runtime/r3/linux/semmutex-linux.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/linux/semmutex-linux.cpp	(revision 25623)
+++ /trunk/src/VBox/Runtime/r3/linux/semmutex-linux.cpp	(revision 25624)
@@ -409,2 +409,15 @@
 }
 
+
+RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutex)
+{
+    /*
+     * Validate.
+     */
+    RTSEMMUTEXINTERNAL *pThis = hMutex;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
+
+    return pThis->Owner != (pthread_t)~0;
+}
+
Index: /trunk/src/VBox/Runtime/r3/os2/sems-os2.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/os2/sems-os2.cpp	(revision 25623)
+++ /trunk/src/VBox/Runtime/r3/os2/sems-os2.cpp	(revision 25624)
@@ -279,3 +279,19 @@
 
 
-
+RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutex);
+{
+    /*
+     * Unlock mutex semaphore.
+     */
+    PID     pid;
+    TID     tid;
+    ULONG   cRecursions;
+    int rc = DosQueryMutexSem(SEM2HND(MutexSem), &pid, &tid, &cRecursions);
+    if (!rc)
+        return cRecursions != 0;
+    AssertMsgFailed(("DosQueryMutexSem %p failed, rc=%d\n", MutexSem, rc));
+    return rc == ERROR_SEM_OWNER_DIED;
+}
+
+
+
Index: /trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp	(revision 25623)
+++ /trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp	(revision 25624)
@@ -331,5 +331,5 @@
      */
     pThis->Owner = (pthread_t)-1;
-    ASMAtomicXchgU32(&pThis->cNesting, 0);
+    ASMAtomicWriteU32(&pThis->cNesting, 0);
 
     /*
@@ -346,2 +346,15 @@
 }
 
+
+RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutex)
+{
+    /*
+     * Validate.
+     */
+    RTSEMMUTEXINTERNAL *pThis = hMutex;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
+
+    return pThis->Owner != (pthread_t)-1;
+}
+
Index: /trunk/src/VBox/Runtime/r3/win/semmutex-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/semmutex-win.cpp	(revision 25623)
+++ /trunk/src/VBox/Runtime/r3/win/semmutex-win.cpp	(revision 25624)
@@ -56,10 +56,14 @@
 {
     /** Magic value (RTSEMMUTEX_MAGIC). */
-    uint32_t            u32Magic;
+    uint32_t                u32Magic;
+    /** Recursion count. */
+    uint32_t volatile       cRecursions;
+    /** The owner thread. */
+    RTNATIVETHREAD volatile hNativeOwner;
     /** The mutex handle. */
-    HANDLE              hMtx;
+    HANDLE                  hMtx;
 #ifdef RTSEMMUTEX_STRICT
     /** Lock validator record associated with this mutex. */
-    RTLOCKVALRECEXCL    ValidatorRec;
+    RTLOCKVALRECEXCL        ValidatorRec;
 #endif
 };
@@ -84,6 +88,8 @@
         if (pThis)
         {
-            pThis->u32Magic = RTSEMMUTEX_MAGIC;
-            pThis->hMtx = hMtx;
+            pThis->u32Magic     = RTSEMMUTEX_MAGIC;
+            pThis->hMtx         = hMtx;
+            pThis->hNativeOwner = NIL_RTNATIVETHREAD;
+            pThis->cRecursions  = 0;
 #ifdef RTSEMMUTEX_STRICT
             RTLockValidatorRecExclInit(&pThis->ValidatorRec,  NIL_RTLOCKVALIDATORCLASS, RTLOCKVALIDATOR_SUB_CLASS_NONE, "RTSemMutex", pThis);
@@ -152,7 +158,24 @@
 
     /*
+     * Check for recursive entry.
+     */
+    RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();
+    RTNATIVETHREAD hNativeOwner;
+    ASMAtomicReadHandle(&pThis->hNativeOwner, hNativeOwner);
+    if (hNativeOwner == hNativeSelf)
+    {
+#ifdef RTSEMMUTEX_STRICT
+        int rc9 = RTLockValidatorRecExclRecursion(&pThis->ValidatorRec, pSrcPos);
+        if (RT_FAILURE(rc9))
+            return rc9;
+#endif
+        ASMAtomicIncU32(&pThis->cRecursions);
+        return VINF_SUCCESS;
+    }
+
+    /*
      * Lock mutex semaphore.
      */
-    RTTHREAD hThreadSelf = NIL_RTTHREAD;
+    RTTHREAD        hThreadSelf = NIL_RTTHREAD;
     if (cMillies > 0)
     {
@@ -175,7 +198,8 @@
         case WAIT_OBJECT_0:
 #ifdef RTSEMMUTEX_STRICT
-            RTLockValidatorRecExclSetOwner(&pThis->ValidatorRec, hThreadSelf, pSrcPos, false /* we don't know */);
-#endif
-/** @todo record who owns this thing and avoid kernel calls during recursion. */
+            RTLockValidatorRecExclSetOwner(&pThis->ValidatorRec, hThreadSelf, pSrcPos, true);
+#endif
+            ASMAtomicWriteHandle(&pThis->hNativeOwner, hNativeSelf);
+            ASMAtomicWriteU32(&pThis->cRecursions, 1);
             return VINF_SUCCESS;
 
@@ -224,4 +248,30 @@
     AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
 
+    /*
+     * Check ownership and recursions.
+     */
+    RTNATIVETHREAD hNativeSelf = RTThreadNativeSelf();
+    RTNATIVETHREAD hNativeOwner;
+    ASMAtomicReadHandle(&pThis->hNativeOwner, hNativeOwner);
+    if (RT_UNLIKELY(hNativeOwner != hNativeSelf))
+    {
+        AssertMsgFailed(("Not owner of mutex %p!! hNativeSelf=%RTntrd Owner=%RTntrd cRecursions=%d\n",
+                         pThis, hNativeSelf, hNativeOwner, pThis->cRecursions));
+        return VERR_NOT_OWNER;
+    }
+    if (pThis->cRecursions > 1)
+    {
+#ifdef RTSEMMUTEX_STRICT
+        int rc9 = RTLockValidatorRecExclUnwind(&pThis->ValidatorRec);
+        if (RT_FAILURE(rc9))
+            return rc9;
+#endif
+        ASMAtomicDecU32(&pThis->cRecursions);
+        return VINF_SUCCESS;
+    }
+
+    /*
+     * Unlock mutex semaphore.
+     */
 #ifdef RTSEMMUTEX_STRICT
     int rc9 = RTLockValidatorRecExclReleaseOwner(&pThis->ValidatorRec, false);
@@ -229,10 +279,10 @@
         return rc9;
 #endif
-
-    /*
-     * Unlock mutex semaphore.
-     */
+    ASMAtomicWriteU32(&pThis->cRecursions, 0);
+    ASMAtomicWriteHandle(&pThis->hNativeOwner, NIL_RTNATIVETHREAD);
+
     if (ReleaseMutex(pThis->hMtx))
         return VINF_SUCCESS;
+
     int rc = RTErrConvertFromWin32(GetLastError());
     AssertMsgFailed(("%p/%p, rc=%Rrc lasterr=%d\n", pThis, pThis->hMtx, rc, GetLastError()));
@@ -240,2 +290,17 @@
 }
 
+
+RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutex)
+{
+    /*
+     * Validate.
+     */
+    RTSEMMUTEXINTERNAL *pThis = hMutex;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, VERR_INVALID_HANDLE);
+
+    RTNATIVETHREAD hNativeOwner;
+    ASMAtomicReadHandle(&pThis->hNativeOwner, hNativeOwner);
+    return hNativeOwner == NIL_RTNATIVETHREAD;
+}
+
