Index: /trunk/include/iprt/localipc.h
===================================================================
--- /trunk/include/iprt/localipc.h	(revision 58299)
+++ /trunk/include/iprt/localipc.h	(revision 58300)
@@ -138,10 +138,10 @@
 /** @} */
 
-
 /**
  * Closes the local IPC session.
  *
  * This can be used with sessions created by both RTLocalIpcSessionConnect
- * and RTLocalIpcServerListen.
+ * and RTLocalIpcServerListen.  It will release one cancel pending I/O and
+ * relase one reference (typically the implict reference from the create API).
  *
  * @returns IPRT status code.
@@ -152,4 +152,26 @@
  */
 RTDECL(int) RTLocalIpcSessionClose(RTLOCALIPCSESSION hSession);
+
+/**
+ * Retain a refence to the given session.
+ *
+ * @returns New reference count, UINT32_MAX if the handle is invalid.
+ * @param   hSession            The session handle.
+ */
+RTDECL(uint32_t) RTLocalIpcSessionRetain(RTLOCALIPCSESSION hSession);
+
+/**
+ * Releases a refence to the given session.
+ *
+ * This differs from RTLocalIpcSessionClose in that it won't cancel any pending
+ * I/O.  So, better call RTLocalIpcSessionClose if you want to terminate the
+ * session.
+ *
+ * @returns New reference count, 0 if NIL handle, UINT32_MAX if the handle is
+ *          invalid.
+ * @param   hSession            The session handle.
+ */
+RTDECL(uint32_t) RTLocalIpcSessionRelease(RTLOCALIPCSESSION hSession);
+
 
 /**
Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 58299)
+++ /trunk/include/iprt/mangling.h	(revision 58300)
@@ -743,4 +743,6 @@
 # define RTLocalIpcSessionRead                          RT_MANGLER(RTLocalIpcSessionRead)
 # define RTLocalIpcSessionReadNB                        RT_MANGLER(RTLocalIpcSessionReadNB)
+# define RTLocalIpcSessionRetain                        RT_MANGLER(RTLocalIpcSessionRetain)
+# define RTLocalIpcSessionRelease                       RT_MANGLER(RTLocalIpcSessionRelease)
 # define RTLocalIpcSessionWrite                         RT_MANGLER(RTLocalIpcSessionWrite)
 # define RTLocalIpcSessionFlush                         RT_MANGLER(RTLocalIpcSessionFlush)
Index: /trunk/src/VBox/Runtime/r3/posix/localipc-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/localipc-posix.cpp	(revision 58299)
+++ /trunk/src/VBox/Runtime/r3/posix/localipc-posix.cpp	(revision 58300)
@@ -557,4 +557,16 @@
 
 
+RTDECL(uint32_t) RTLocalIpcSessionRetain(RTLOCALIPCSESSION hSession)
+{
+    PRTLOCALIPCSESSIONINT pThis = (PRTLOCALIPCSESSIONINT)hSession;
+    AssertPtrReturn(pThis, UINT32_MAX);
+    AssertReturn(pThis->u32Magic == RTLOCALIPCSESSION_MAGIC, UINT32_MAX);
+
+    uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+    Assert(cRefs < UINT32_MAX / 2 && cRefs);
+    return cRefs;
+}
+
+
 /**
  * Session instance destructor.
@@ -590,4 +602,23 @@
     Log(("rtLocalIpcSessionRelease: %u refs left\n", cRefs));
     return VINF_SUCCESS;
+}
+
+
+RTDECL(uint32_t) RTLocalIpcSessionRelease(RTLOCALIPCSESSION hSession)
+{
+    if (hSession == NIL_RTLOCALIPCSESSION)
+        return 0;
+
+    PRTLOCALIPCSESSIONINT pThis = (PRTLOCALIPCSESSIONINT)hSession;
+    AssertPtrReturn(pThis, UINT32_MAX);
+    AssertReturn(pThis->u32Magic == RTLOCALIPCSESSION_MAGIC, UINT32_MAX);
+
+    uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
+    Assert(cRefs < UINT32_MAX / 2);
+    if (cRefs)
+        Log(("RTLocalIpcSessionRelease: %u refs left\n", cRefs));
+    else
+        rtLocalIpcSessionDtor(pThis);
+    return cRefs;
 }
 
Index: /trunk/src/VBox/Runtime/r3/win/localipc-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/localipc-win.cpp	(revision 58299)
+++ /trunk/src/VBox/Runtime/r3/win/localipc-win.cpp	(revision 58300)
@@ -909,4 +909,16 @@
 
 
+RTDECL(uint32_t) RTLocalIpcSessionRetain(RTLOCALIPCSESSION hSession)
+{
+    PRTLOCALIPCSESSIONINT pThis = (PRTLOCALIPCSESSIONINT)hSession;
+    AssertPtrReturn(pThis, UINT32_MAX);
+    AssertReturn(pThis->u32Magic == RTLOCALIPCSESSION_MAGIC, UINT32_MAX);
+
+    uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+    Assert(cRefs < UINT32_MAX / 2 && cRefs);
+    return cRefs;
+}
+
+
 /**
  * Call when the reference count reaches 0.
@@ -936,34 +948,4 @@
     RTMemFree(pThis);
     return VINF_OBJECT_DESTROYED;
-}
-
-
-/**
- * Session instance destructor.
- *
- * @returns VINF_OBJECT_DESTROYED
- * @param   pThis               The server instance.
- */
-DECL_NO_INLINE(static, int) rtLocalIpcSessionDtor(PRTLOCALIPCSESSIONINT pThis)
-{
-    RTCritSectEnter(&pThis->CritSect);
-    return rtLocalIpcSessionWinDestroy(pThis);
-}
-
-
-/**
- * Releases a reference to the session instance.
- *
- * @returns VINF_SUCCESS or VINF_OBJECT_DESTROYED as appropriate.
- * @param   pThis               The session instance.
- */
-DECLINLINE(int) rtLocalIpcSessionRelease(PRTLOCALIPCSESSIONINT pThis)
-{
-    uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
-    Assert(cRefs < UINT32_MAX / 2);
-    if (!cRefs)
-        return rtLocalIpcSessionDtor(pThis);
-    Log(("rtLocalIpcSessionRelease: %u refs left\n", cRefs));
-    return VINF_SUCCESS;
 }
 
@@ -983,6 +965,28 @@
 
     int rc2 = RTCritSectLeave(&pThis->CritSect); AssertRC(rc2);
-    Log(("rtLocalIpcSessionRelease: %u refs left\n", cRefs));
+    Log(("rtLocalIpcSessionReleaseAndUnlock: %u refs left\n", cRefs));
     return VINF_SUCCESS;
+}
+
+
+RTDECL(uint32_t) RTLocalIpcSessionRelease(RTLOCALIPCSESSION hSession)
+{
+    if (hSession == NIL_RTLOCALIPCSESSION)
+        return 0;
+
+    PRTLOCALIPCSESSIONINT pThis = (PRTLOCALIPCSESSIONINT)hSession;
+    AssertPtrReturn(pThis, UINT32_MAX);
+    AssertReturn(pThis->u32Magic == RTLOCALIPCSESSION_MAGIC, UINT32_MAX);
+
+    uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
+    Assert(cRefs < UINT32_MAX / 2);
+    if (cRefs)
+        Log(("RTLocalIpcSessionRelease: %u refs left\n", cRefs));
+    else
+    {
+        RTCritSectEnter(&pThis->CritSect);
+        rtLocalIpcSessionWinDestroy(pThis);
+    }
+    return cRefs;
 }
 
@@ -1002,6 +1006,4 @@
      * Invalidate the instance, cancel all outstanding I/O and drop our reference.
      */
-    AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, ~RTLOCALIPCSESSION_MAGIC, RTLOCALIPCSESSION_MAGIC), VERR_WRONG_ORDER);
-
     RTCritSectEnter(&pThis->CritSect);
     rtLocalIpcWinCancel(pThis);
