Index: /trunk/include/iprt/localipc.h
===================================================================
--- /trunk/include/iprt/localipc.h	(revision 58289)
+++ /trunk/include/iprt/localipc.h	(revision 58290)
@@ -85,4 +85,6 @@
  *
  * @returns IPRT status code.
+ * @retval  VINF_SUCCESS if still other references or NIL.
+ * @retval  VINF_OBJECT_DESTROYED if actually destroyed.
  *
  * @param   hServer     The server handle. The nil value is quietly ignored (VINF_SUCCESS).
@@ -134,4 +136,6 @@
  *
  * @returns IPRT status code.
+ * @retval  VINF_SUCCESS if still other references or NIL.
+ * @retval  VINF_OBJECT_DESTROYED if session destroyed.
  *
  * @param   hSession            The session handle. The nil value is quietly ignored (VINF_SUCCESS).
Index: /trunk/include/iprt/log.h
===================================================================
--- /trunk/include/iprt/log.h	(revision 58289)
+++ /trunk/include/iprt/log.h	(revision 58290)
@@ -67,4 +67,5 @@
     RTLOGGROUP_TIME,
     RTLOGGROUP_TIMER,
+    RTLOGGROUP_LOCALIPC,
     RTLOGGROUP_ZIP = 31,
     RTLOGGROUP_FIRST_USER = 32
@@ -100,5 +101,5 @@
     "RT_TIME",      \
     "RT_TIMER",     \
-    "RT_15", \
+    "RT_LOCALIPC", \
     "RT_16", \
     "RT_17", \
Index: /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp	(revision 58289)
+++ /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo-win.cpp	(revision 58290)
@@ -1014,5 +1014,5 @@
 #endif
             int rc2 = RTLocalIpcSessionClose(hSession);
-            if (RT_SUCCESS(rc))
+            if (RT_SUCCESS(rc) && RT_FAILURE(rc2))
                 rc = rc2;
         }
Index: /trunk/src/VBox/Runtime/r3/posix/localipc-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/localipc-posix.cpp	(revision 58289)
+++ /trunk/src/VBox/Runtime/r3/posix/localipc-posix.cpp	(revision 58290)
@@ -29,4 +29,5 @@
 *   Header Files                                                               *
 *******************************************************************************/
+#define LOG_GROUP RTLOGGROUP_LOCALIPC
 #include "internal/iprt.h"
 #include <iprt/localipc.h>
@@ -37,4 +38,5 @@
 #include <iprt/critsect.h>
 #include <iprt/mem.h>
+#include <iprt/log.h>
 #include <iprt/poll.h>
 #include <iprt/socket.h>
@@ -44,4 +46,8 @@
 #include <sys/socket.h>
 #include <sys/un.h>
+#ifndef RT_OS_OS2
+# include <sys/poll.h>
+# include <errno.h>
+#endif
 #include <fcntl.h>
 #include <unistd.h>
@@ -226,4 +232,5 @@
                         if (RT_SUCCESS(rc))
                         {
+                            LogFlow(("RTLocalIpcServerCreate: Created %p (%s)\n", pThis, pThis->Name.sun_path));
                             *phServer = pThis;
                             return VINF_SUCCESS;
@@ -239,4 +246,5 @@
             rc = VERR_NO_MEMORY;
     }
+    Log(("RTLocalIpcServerCreate: failed, rc=%Rrc\n", rc));
     return rc;
 }
@@ -258,13 +266,19 @@
 /**
  * Server instance destructor.
+ *
+ * @returns VINF_OBJECT_DESTROYED
  * @param   pThis               The server instance.
  */
-static void rtLocalIpcServerDtor(PRTLOCALIPCSERVERINT pThis)
+static int rtLocalIpcServerDtor(PRTLOCALIPCSERVERINT pThis)
 {
     pThis->u32Magic = ~RTLOCALIPCSERVER_MAGIC;
-    RTSocketRelease(pThis->hSocket);
+    if (RTSocketRelease(pThis->hSocket) == 0)
+        Log(("rtLocalIpcServerDtor: Released socket\n"));
+    else
+        Log(("rtLocalIpcServerDtor: Socket still has references (impossible?)\n"));
     RTCritSectDelete(&pThis->CritSect);
     unlink(pThis->Name.sun_path);
     RTMemFree(pThis);
+    return VINF_OBJECT_DESTROYED;
 }
 
@@ -273,12 +287,14 @@
  * Releases a reference to the server instance.
  *
+ * @returns VINF_SUCCESS if only release, VINF_OBJECT_DESTROYED if destroyed.
  * @param   pThis               The server instance.
  */
-DECLINLINE(void) rtLocalIpcServerRelease(PRTLOCALIPCSERVERINT pThis)
+DECLINLINE(int) rtLocalIpcServerRelease(PRTLOCALIPCSERVERINT pThis)
 {
     uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
     Assert(cRefs < UINT32_MAX / 2);
     if (!cRefs)
-        rtLocalIpcServerDtor(pThis);
+        return rtLocalIpcServerDtor(pThis);
+    return VINF_SUCCESS;
 }
 
@@ -294,4 +310,5 @@
     RTCritSectEnter(&pThis->CritSect);
     pThis->fCancelled = true;
+    Log(("rtLocalIpcServerCancel:\n"));
     if (pThis->hListenThread != NIL_RTTHREAD)
         RTThreadPoke(pThis->hListenThread);
@@ -320,7 +337,5 @@
 
     rtLocalIpcServerCancel(pThis);
-    rtLocalIpcServerRelease(pThis);
-
-    return VINF_SUCCESS;
+    return rtLocalIpcServerRelease(pThis);
 }
 
@@ -385,5 +400,7 @@
                     size_t              cbAddr = sizeof(Addr);
                     RTSOCKET            hClient;
+                    Log(("RTLocalIpcServerListen: Calling rtSocketAccept...\n"));
                     rc = rtSocketAccept(pThis->hSocket, &hClient, (struct sockaddr *)&Addr, &cbAddr);
+                    Log(("RTLocalIpcServerListen: rtSocketAccept returns %Rrc.\n", rc));
 
                     int rc2 = RTCritSectEnter(&pThis->CritSect);
@@ -407,7 +424,11 @@
                             rc = RTCritSectInit(&pSession->CritSect);
                             if (RT_SUCCESS(rc))
+                            {
+                                Log(("RTLocalIpcServerListen: Returning new client session: %p\n", pSession));
                                 *phClientSession = pSession;
-                            else
-                                RTMemFree(pSession);
+                                break;
+                            }
+
+                            RTMemFree(pSession);
                         }
                         else
@@ -440,4 +461,5 @@
     rtLocalIpcServerRelease(pThis);
 
+    Log(("RTLocalIpcServerListen: returns %Rrc\n", rc));
     return rc;
 }
@@ -491,4 +513,5 @@
                         {
                             *phSession = pThis;
+                            Log(("RTLocalIpcSessionConnect: Returns new session %p\n", pThis));
                             return VINF_SUCCESS;
                         }
@@ -502,4 +525,5 @@
             rc = VERR_NO_MEMORY;
     }
+    Log(("RTLocalIpcSessionConnect: returns %Rrc\n", rc));
     return rc;
 }
@@ -520,13 +544,18 @@
 /**
  * Session instance destructor.
+ *
+ * @returns VINF_OBJECT_DESTROYED
  * @param   pThis               The server instance.
  */
-static void rtLocalIpcSessionDtor(PRTLOCALIPCSESSIONINT pThis)
+static int rtLocalIpcSessionDtor(PRTLOCALIPCSESSIONINT pThis)
 {
     pThis->u32Magic = ~RTLOCALIPCSESSION_MAGIC;
     if (RTSocketRelease(pThis->hSocket) == 0)
-        pThis->hSocket = NIL_RTSOCKET;
+        Log(("rtLocalIpcSessionDtor: Released socket\n"));
+    else
+        Log(("rtLocalIpcSessionDtor: Socket still has references (impossible?)\n"));
     RTCritSectDelete(&pThis->CritSect);
     RTMemFree(pThis);
+    return VINF_OBJECT_DESTROYED;
 }
 
@@ -535,12 +564,15 @@
  * Releases a reference to the session instance.
  *
+ * @returns VINF_SUCCESS or VINF_OBJECT_DESTROYED as appropriate.
  * @param   pThis               The session instance.
  */
-DECLINLINE(void) rtLocalIpcSessionRelease(PRTLOCALIPCSESSIONINT pThis)
+DECLINLINE(int) rtLocalIpcSessionRelease(PRTLOCALIPCSESSIONINT pThis)
 {
     uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
     Assert(cRefs < UINT32_MAX / 2);
     if (!cRefs)
-        rtLocalIpcSessionDtor(pThis);
+        return rtLocalIpcSessionDtor(pThis);
+    Log(("rtLocalIpcSessionRelease: %u refs left\n", cRefs));
+    return VINF_SUCCESS;
 }
 
@@ -556,4 +588,5 @@
     RTCritSectEnter(&pThis->CritSect);
     pThis->fCancelled = true;
+    Log(("rtLocalIpcSessionCancel:\n"));
     if (pThis->hReadThread != NIL_RTTHREAD)
         RTThreadPoke(pThis->hReadThread);
@@ -581,9 +614,8 @@
      */
     AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, ~RTLOCALIPCSESSION_MAGIC, RTLOCALIPCSESSION_MAGIC), VERR_WRONG_ORDER);
+    Log(("RTLocalIpcSessionClose:\n"));
 
     rtLocalIpcSessionCancel(pThis);
-    rtLocalIpcSessionRelease(pThis);
-
-    return VINF_SUCCESS;
+    return rtLocalIpcSessionRelease(pThis);
 }
 
@@ -606,4 +638,28 @@
     return VINF_SUCCESS;
 }
+
+
+#if 0 /* maybe later */
+/**
+ * Checks if the socket has has a HUP condition.
+ *
+ * @returns true if HUP, false if no.
+ * @param   pThis       The IPC session handle.
+ */
+static bool rtLocalIpcPosixHasHup(PRTLOCALIPCSESSIONINT pThis)
+{
+# ifndef RT_OS_OS2
+    struct pollfd PollFd;
+    RT_ZERO(PollFd);
+    PollFd.fd      = RTSocketToNative(pThis->hSocket);
+    PollFd.events  = POLLHUP;
+    return poll(&PollFd, 1, 0) >= 1
+       && (PollFd.revents & POLLHUP);
+
+# else /* RT_OS_OS2: */
+    return false;
+# endif
+}
+#endif
 
 
@@ -779,5 +835,29 @@
 
                     uint32_t fEvents = 0;
+#ifdef RT_OS_OS2
+                    /* This doesn't give us any error condition on hangup. */
+                    Log(("RTLocalIpcSessionWaitForData: Calling RTSocketSelectOneEx...\n"));
                     rc = RTSocketSelectOneEx(pThis->hSocket, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, &fEvents, cMillies);
+                    Log(("RTLocalIpcSessionWaitForData: RTSocketSelectOneEx returns %Rrc, fEvents=%#x\n", rc, fEvents));
+#else
+/** @todo RTSocketPoll */
+                    /* POLLHUP will be set on hangup. */
+                    struct pollfd PollFd;
+                    RT_ZERO(PollFd);
+                    PollFd.fd      = RTSocketToNative(pThis->hSocket);
+                    PollFd.events  = POLLHUP | POLLERR | POLLIN;
+                    Log(("RTLocalIpcSessionWaitForData: Calling poll...\n"));
+                    int cFds = poll(&PollFd, 1, cMillies == RT_INDEFINITE_WAIT ? -1 : cMillies);
+                    if (cFds >= 1)
+                    {
+                        fEvents = PollFd.revents & (POLLHUP | POLLERR) ? RTPOLL_EVT_ERROR : RTPOLL_EVT_READ;
+                        rc = VINF_SUCCESS;
+                    }
+                    else if (rc == 0)
+                        rc = VERR_TIMEOUT;
+                    else
+                        rc = RTErrConvertFromErrno(errno);
+                    Log(("RTLocalIpcSessionWaitForData: poll returns %u (rc=%%d), revents=%#x\n", cFds, rc, PollFd.revents));
+#endif
 
                     int rc2 = RTCritSectEnter(&pThis->CritSect);
Index: /trunk/src/VBox/Runtime/r3/win/localipc-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/localipc-win.cpp	(revision 58289)
+++ /trunk/src/VBox/Runtime/r3/win/localipc-win.cpp	(revision 58290)
@@ -401,8 +401,11 @@
 /**
  * Call when the reference count reaches 0.
+ *
  * Caller owns the critsect.
+ *
+ * @returns VINF_OBJECT_DESTROYED
  * @param   pThis       The instance to destroy.
  */
-static void rtLocalIpcServerWinDestroy(PRTLOCALIPCSERVERINT pThis)
+static int rtLocalIpcServerWinDestroy(PRTLOCALIPCSERVERINT pThis)
 {
     BOOL fRc = CloseHandle(pThis->hNmPipe);
@@ -418,4 +421,5 @@
 
     RTMemFree(pThis);
+    return VINF_OBJECT_DESTROYED;
 }
 
@@ -450,6 +454,5 @@
     }
     else
-        rtLocalIpcServerWinDestroy(pThis);
-
+        return rtLocalIpcServerWinDestroy(pThis);
     return VINF_SUCCESS;
 }
@@ -735,8 +738,11 @@
 /**
  * Call when the reference count reaches 0.
+ *
  * Caller owns the critsect.
+ *
+ * @returns VINF_OBJECT_DESTROYED
  * @param   pThis       The instance to destroy.
  */
-static void rtLocalIpcSessionWinDestroy(PRTLOCALIPCSESSIONINT pThis)
+static int rtLocalIpcSessionWinDestroy(PRTLOCALIPCSESSIONINT pThis)
 {
     BOOL fRc = CloseHandle(pThis->hNmPipe);
@@ -752,4 +758,5 @@
 
     RTMemFree(pThis);
+    return VINF_OBJECT_DESTROYED;
 }
 
@@ -783,6 +790,5 @@
     }
     else
-        rtLocalIpcSessionWinDestroy(pThis);
-
+        return rtLocalIpcSessionWinDestroy(pThis);
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp	(revision 58289)
+++ /trunk/src/VBox/Runtime/testcase/tstRTLocalIpc.cpp	(revision 58290)
@@ -74,5 +74,5 @@
     RTTESTI_CHECK_RC_RETV(RTLocalIpcServerCreate(&hIpcServer, "BasicTest", RTLOCALIPC_FLAGS_MULTI_SESSION), VINF_SUCCESS);
     RTTESTI_CHECK_RC(RTLocalIpcServerCancel(hIpcServer), VINF_SUCCESS);
-    RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VINF_SUCCESS);
+    RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VINF_OBJECT_DESTROYED);
 
     /* Client-side (per session). */
@@ -120,5 +120,5 @@
             RTThreadSleep(8); /* windows output fudge (purely esthetical) */
             RTTestIPrintf(RTTESTLVL_INFO, "testServerListenThread: Got new client connection.\n");
-            RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hIpcSession), VINF_SUCCESS);
+            RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hIpcSession), VINF_OBJECT_DESTROYED);
         }
         else
@@ -143,5 +143,5 @@
                         VINF_SUCCESS, rcCheck);
     RTTEST_CHECK_RC_RET(g_hTest, RTLocalIpcSessionClose(hClientSession),
-                        VINF_SUCCESS, rcCheck);
+                        VINF_OBJECT_DESTROYED, rcCheck);
 
     return VINF_SUCCESS;
@@ -214,5 +214,5 @@
     }
 
-    RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VINF_SUCCESS);
+    RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VINF_OBJECT_DESTROYED);
 }
 
@@ -242,5 +242,5 @@
             RTTESTI_CHECK_RC(RTLocalIpcSessionWaitForData(hIpcSession, RT_MS_1MIN), VINF_SUCCESS);
 
-            RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hIpcSession), VINF_SUCCESS);
+            RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hIpcSession), VINF_OBJECT_DESTROYED);
             RTTESTI_CHECK_RC_OK(RTThreadUserSignal(hSelf));
         }
@@ -288,5 +288,5 @@
     }
 
-    RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hClientSession), VINF_SUCCESS);
+    RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hClientSession), VINF_OBJECT_DESTROYED);
 
     return VINF_SUCCESS;
@@ -347,5 +347,5 @@
             RTTESTI_CHECK_RC(rcThread, VERR_CANCELLED);
 
-        RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VINF_SUCCESS);
+        RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VINF_OBJECT_DESTROYED);
 
         /*
@@ -521,5 +521,5 @@
             }
 
-            RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hIpcSession), VINF_SUCCESS);
+            RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hIpcSession), VINF_OBJECT_DESTROYED);
             RTTESTI_CHECK_RC_OK(RTThreadUserSignal(hSelf));
         }
@@ -567,5 +567,5 @@
     }
 
-    RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hClientSession), VINF_SUCCESS);
+    RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hClientSession), VINF_OBJECT_DESTROYED);
 
     return rc;
@@ -625,5 +625,5 @@
             RTTESTI_CHECK_RC(rcThread, VERR_CANCELLED);
 
-        RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VINF_SUCCESS);
+        RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VINF_OBJECT_DESTROYED);
 
         /*
@@ -702,5 +702,5 @@
                     if (cNsElapsed > 2*RT_NS_1SEC_64)
                     {
-                        uint32_t uMsg = IPC_PERF_LAST_MSG;
+                        uMsg = IPC_PERF_LAST_MSG;
                         RTTESTI_CHECK_RC_BREAK(rc = RTLocalIpcSessionWrite(hIpcSession, &uMsg, sizeof(uMsg)), VINF_SUCCESS);
                         break;
@@ -715,5 +715,5 @@
             }
 
-            RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hIpcSession), VINF_SUCCESS);
+            RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hIpcSession), VINF_OBJECT_DESTROYED);
             RTTESTI_CHECK_RC_OK(RTThreadUserSignal(hSelf));
         }
@@ -767,5 +767,5 @@
     }
 
-    RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hClientSession), VINF_SUCCESS);
+    RTTESTI_CHECK_RC(RTLocalIpcSessionClose(hClientSession), VINF_OBJECT_DESTROYED);
     return rc;
 }
@@ -824,5 +824,5 @@
             RTTESTI_CHECK_RC(rcThread, VERR_CANCELLED);
 
-        RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VINF_SUCCESS);
+        RTTESTI_CHECK_RC(RTLocalIpcServerDestroy(hIpcServer), VINF_OBJECT_DESTROYED);
 
         /*
