Index: trunk/src/libs/xpcom18a4/Makefile.kmk
===================================================================
--- trunk/src/libs/xpcom18a4/Makefile.kmk	(revision 103176)
+++ trunk/src/libs/xpcom18a4/Makefile.kmk	(revision 103300)
@@ -106,4 +106,9 @@
  	VBoxXPCOM \
  	VBoxXPCOMIPCC
+ ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
+  VBOX_XPCOM_DLLS += \
+ 	VBoxXPCOMIPCD
+ endif
+
  DLLS += $(VBOX_XPCOM_DLLS)
 
@@ -134,5 +139,7 @@
   	tstPrimitiveTest
  endif # VBOX_WITH_TESTCASES
- PROGRAMS += VBoxXPCOMIPCD
+ ifndef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
+  PROGRAMS += VBoxXPCOMIPCD
+ endif
 
 endif # !VBOX_ONLY_SDK && (!defined(VBOX_ONLY_EXTPACKS) || !defined(VBOX_ONLY_EXTPACKS_USE_IMPLIBS))
@@ -754,9 +761,21 @@
 TEMPLATE_XPComIpcDll                  = XPCOM IPC libraries
 TEMPLATE_XPComIpcDll_EXTENDS          = XPComDll
-TEMPLATE_XPComIpcDll_DEFS             = $(TEMPLATE_XPComDll_DEFS) BUILD_DCONNECT=1
-ifdef VBOX_WITH_AUTOMATIC_DEFS_QUOTING
- TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME="VBoxXPCOMIPCD$(SUFF_EXE)"
+TEMPLATE_XPComIpcDll_DEFS             = \
+	$(TEMPLATE_XPComDll_DEFS) \
+	BUILD_DCONNECT=1 \
+	$(if $(VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC),VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC,)
+
+ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
+ ifdef VBOX_WITH_AUTOMATIC_DEFS_QUOTING
+  TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME="VBoxSVC$(SUFF_EXE)"
+ else
+  TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME=\"VBoxSVC$(SUFF_EXE)\"
+ endif
 else
- TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME=\"VBoxXPCOMIPCD$(SUFF_EXE)\"
+ ifdef VBOX_WITH_AUTOMATIC_DEFS_QUOTING
+  TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME="VBoxXPCOMIPCD$(SUFF_EXE)"
+ else
+  TEMPLATE_XPComIpcDll_DEFS           += IPC_DAEMON_APP_NAME=\"VBoxXPCOMIPCD$(SUFF_EXE)\"
+ endif
 endif
 ifdef IPC_LOGGING
@@ -808,5 +827,4 @@
 VBoxXPCOMIPCC_TEMPLATE = XPComIpcDll
 VBoxXPCOMIPCC_INST = $(INST_BIN)components/
-#VBoxXPCOMIPCC_DEFS = HAVE_DEPENDENT_LIBS - dependentLibs.h is linux specific, so this cannot be required.
 VBoxXPCOMIPCC_SOURCES = \
 	ipc/ipcd/client/src/ipcdclient.cpp \
@@ -839,10 +857,23 @@
 # DCONNECT daemon executable
 #
-VBoxXPCOMIPCD_TEMPLATE = XPComIpcExe
-VBoxXPCOMIPCD_SOURCES = \
-	ipc/ipcd/daemon/src/ipcd.cpp \
-	ipc/ipcd/daemon/src/ipcClient.cpp \
-	ipc/ipcd/daemon/src/ipcCommandModule.cpp \
-	ipc/ipcd/daemon/src/ipcdUnix.cpp
+ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
+ VBoxXPCOMIPCD_TEMPLATE = XPComIpcDll
+ VBoxXPCOMIPCD_SOURCES = \
+ 	ipc/ipcd/daemon/src/ipcd.cpp \
+ 	ipc/ipcd/daemon/src/ipcClient.cpp \
+ 	ipc/ipcd/daemon/src/ipcCommandModule.cpp \
+ 	ipc/ipcd/daemon/src/ipcdUnix.cpp
+ VBoxXPCOMIPCD_LIBS = \
+	$(VBox-xpcom-ipcshared_1_TARGET) \
+	$(VBoxXPCOM_1_TARGET) \
+	$(TEMPLATE_XPComDll_LIBS)
+else
+ VBoxXPCOMIPCD_TEMPLATE = XPComIpcExe
+ VBoxXPCOMIPCD_SOURCES = \
+ 	ipc/ipcd/daemon/src/ipcd.cpp \
+ 	ipc/ipcd/daemon/src/ipcClient.cpp \
+ 	ipc/ipcd/daemon/src/ipcCommandModule.cpp \
+ 	ipc/ipcd/daemon/src/ipcdUnix.cpp
+endif
 
 
Index: trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp
===================================================================
--- trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp	(revision 103176)
+++ trunk/src/libs/xpcom18a4/ipc/ipcd/client/src/ipcdclient.cpp	(revision 103300)
@@ -1242,5 +1242,10 @@
     {
       char szPipeInheritFd[32]; RT_ZERO(szPipeInheritFd);
-      const char *const s_apszArgs[] = { (char *const) path, "--inherit-startup-pipe", &szPipeInheritFd[0], NULL };
+      const char *const s_apszArgs[] = { (char *const) path,
+#ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
+                                         "--auto-shutdown",
+#endif
+                                         "--inherit-startup-pipe",
+                                         &szPipeInheritFd[0], NULL };
       char c;
 
Index: trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdPrivate.h
===================================================================
--- trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdPrivate.h	(revision 103176)
+++ trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdPrivate.h	(revision 103300)
@@ -48,5 +48,9 @@
 // XXX may want to make this more dynamic
 //
-#define IPC_MAX_CLIENTS 10000
+#ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
+# define IPC_MAX_CLIENTS 100
+#else
+# define IPC_MAX_CLIENTS 10000
+#endif
 
 /** List of connected IPC clients. */
Index: trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdUnix.cpp
===================================================================
--- trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdUnix.cpp	(revision 103176)
+++ trunk/src/libs/xpcom18a4/ipc/ipcd/daemon/src/ipcdUnix.cpp	(revision 103300)
@@ -37,5 +37,5 @@
 #define LOG_GROUP LOG_GROUP_IPC
 #include <iprt/assert.h>
-#include <iprt/errcore.h>
+#include <iprt/err.h>
 #include <iprt/initterm.h>
 #include <iprt/getopt.h>
@@ -44,4 +44,7 @@
 #include <iprt/socket.h>
 #include <iprt/string.h>
+#ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
+# include <iprt/thread.h>
+#endif
 #include <VBox/log.h>
 
@@ -65,19 +68,35 @@
 #include "ipcd.h"
 
+
+/**
+ * The IPC daemon state
+ */
+typedef struct IPCDSTATE
+{
+    RTSOCKET hSockListen;
+    int      fdListen;
+    int      ipcLockFD;
+    int      ipcClientCount;
+
+    //
+    // the first element of this array is always zero; this is done so that the
+    // k'th element of ipcClientArray corresponds to the k'th element of
+    // ipcPollList.
+    //
+    ipcClient ipcClientArray[IPC_MAX_CLIENTS];
+
+    RTPOLLSET hPollSet;
+
+#ifdef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
+    RTTHREAD hThread;
+#endif
+} IPCDSTATE;
+typedef IPCDSTATE *PIPCDSTATE;
+typedef const IPCDSTATE *PCIPCDSTATE;
+
+
 //-----------------------------------------------------------------------------
 // ipc directory and locking...
 //-----------------------------------------------------------------------------
-
-//
-// advisory file locking is used to ensure that only one IPC daemon is active
-// and bound to the local domain socket at a time.
-//
-// XXX this code does not work on OS/2.
-//
-#if !defined(XP_OS2)
-#define IPC_USE_FILE_LOCK
-#endif
-
-#ifdef IPC_USE_FILE_LOCK
 
 enum Status
@@ -89,7 +108,5 @@
 };
 
-static int ipcLockFD = 0;
-
-static Status AcquireDaemonLock(const char *baseDir)
+static Status AcquireDaemonLock(PIPCDSTATE pThis, const char *baseDir)
 {
     const char lockName[] = "lock";
@@ -100,5 +117,4 @@
             + sizeof(lockName); // "lock"
 
-#ifdef VBOX
     //
     // Security checks for the directory
@@ -107,5 +123,5 @@
     if (stat(baseDir, &st) == -1)
     {
-        printf("Cannot stat '%s'.\n", baseDir);
+        LogFlowFunc(("Cannot stat '%s'.\n", baseDir));
         return ELockFileOwner;
     }
@@ -113,10 +129,10 @@
     if (st.st_uid != getuid() && st.st_uid != geteuid())
     {
-        printf("Wrong owner (%d) of '%s'", st.st_uid, baseDir);
+        LogFlowFunc(("Wrong owner (%d) of '%s'", st.st_uid, baseDir));
         if (   !stat("/tmp", &st)
             && (st.st_mode & 07777) != 01777)
-            printf(" -- check /tmp permissions (%o should be 1777)\n",
-                    st.st_mode & 07777);
-        printf(".\n");
+            LogFlowFunc((" -- check /tmp permissions (%o should be 1777)\n",
+                         st.st_mode & 07777));
+        LogFlowFunc((".\n"));
         return ELockFileOwner;
     }
@@ -124,13 +140,12 @@
     if (st.st_mode != (S_IRUSR | S_IWUSR | S_IXUSR | S_IFDIR))
     {
-        printf("Wrong mode (%o) of '%s'", st.st_mode, baseDir);
+        LogFlowFunc(("Wrong mode (%o) of '%s'", st.st_mode, baseDir));
         if (   !stat("/tmp", &st)
             && (st.st_mode & 07777) != 01777)
-            printf(" -- check /tmp permissions (%o should be 1777)\n",
-                    st.st_mode & 07777);
-        printf(".\n");
+            LogFlowFunc((" -- check /tmp permissions (%o should be 1777)\n",
+                    st.st_mode & 07777));
+        LogFlowFunc((".\n"));
         return ELockFileOwner;
     }
-#endif
 
     char *lockFile = (char *) malloc(len);
@@ -142,11 +157,6 @@
     // open lock file.  it remains open until we shutdown.
     //
-    ipcLockFD = open(lockFile, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR);
-
-#ifndef VBOX
-    free(lockFile);
-#endif
-
-    if (ipcLockFD == -1)
+    pThis->ipcLockFD = open(lockFile, O_WRONLY|O_CREAT, S_IWUSR|S_IRUSR);
+    if (pThis->ipcLockFD == -1)
     {
         free(lockFile);
@@ -154,11 +164,10 @@
     }
 
-#ifdef VBOX
     //
     // Security checks for the lock file
     //
-    if (fstat(ipcLockFD, &st) == -1)
-    {
-        printf("Cannot stat '%s'.\n", lockFile);
+    if (fstat(pThis->ipcLockFD, &st) == -1)
+    {
+        LogFlowFunc(("Cannot stat '%s'.\n", lockFile));
         free(lockFile);
         return ELockFileOwner;
@@ -167,5 +176,5 @@
     if (st.st_uid != getuid() && st.st_uid != geteuid())
     {
-        printf("Wrong owner (%d) of '%s'.\n", st.st_uid, lockFile);
+        LogFlowFunc(("Wrong owner (%d) of '%s'.\n", st.st_uid, lockFile));
         free(lockFile);
         return ELockFileOwner;
@@ -174,5 +183,5 @@
     if (st.st_mode != (S_IRUSR | S_IWUSR | S_IFREG))
     {
-        printf("Wrong mode (%o) of '%s'.\n", st.st_mode, lockFile);
+        LogFlowFunc(("Wrong mode (%o) of '%s'.\n", st.st_mode, lockFile));
         free(lockFile);
         return ELockFileOwner;
@@ -180,5 +189,4 @@
 
     free(lockFile);
-#endif
 
     //
@@ -193,11 +201,14 @@
     lock.l_len = 0;
     lock.l_whence = SEEK_SET;
-    if (fcntl(ipcLockFD, F_SETLK, &lock) == -1)
+    if (fcntl(pThis->ipcLockFD, F_SETLK, &lock) == -1)
+    {
+        LogFlowFunc(("Setting lock failed -> %Rrc.\n", RTErrConvertFromErrno(errno)));
         return ELockFileLock;
+    }
 
     //
     // truncate lock file once we have exclusive access to it.
     //
-    ftruncate(ipcLockFD, 0);
+    ftruncate(pThis->ipcLockFD, 0);
 
     //
@@ -209,10 +220,10 @@
     if (nb <= 0)
         return ELockFileOpen;
-    write(ipcLockFD, buf, (size_t)nb);
+    write(pThis->ipcLockFD, buf, (size_t)nb);
 
     return EOk;
 }
 
-static Status InitDaemonDir(const char *socketPath)
+static Status InitDaemonDir(PIPCDSTATE pThis, const char *socketPath)
 {
     LogFlowFunc(("InitDaemonDir [sock=%s]\n", socketPath));
@@ -232,5 +243,5 @@
     // must be active, so bail.
     //
-    Status status = AcquireDaemonLock(baseDir);
+    Status status = AcquireDaemonLock(pThis, baseDir);
 
     RTStrFree(baseDir);
@@ -243,21 +254,4 @@
 }
 
-static void ShutdownDaemonDir()
-{
-    LogFlowFunc(("ShutdownDaemonDir\n"));
-
-    // deleting directory and files underneath it allows another process
-    // to think it has exclusive access.  better to just leave the hidden
-    // directory in /tmp and let the OS clean it up via the usual tmpdir
-    // cleanup cron job.
-
-    // this removes the advisory lock, allowing other processes to acquire it.
-    if (ipcLockFD) {
-        close(ipcLockFD);
-        ipcLockFD = 0;
-    }
-}
-
-#endif // IPC_USE_FILE_LOCK
 
 //-----------------------------------------------------------------------------
@@ -269,20 +263,12 @@
 //
 DECL_HIDDEN_DATA(RTLISTANCHOR) g_LstIpcClients;
-static int                     ipcClientCount = 0;
-
-//
-// the first element of this array is always zero; this is done so that the
-// k'th element of ipcClientArray corresponds to the k'th element of
-// ipcPollList.
-//
-static ipcClient ipcClientArray[IPC_MAX_CLIENTS];
-
 static RTPOLLSET g_hPollSet = NIL_RTPOLLSET;
 
-//-----------------------------------------------------------------------------
-
-static int AddClient(RTPOLLSET hPollSet, RTSOCKET hSock)
-{
-    if (ipcClientCount == IPC_MAX_CLIENTS) {
+
+//-----------------------------------------------------------------------------
+
+static int AddClient(PIPCDSTATE pThis, RTSOCKET hSock)
+{
+    if (pThis->ipcClientCount == IPC_MAX_CLIENTS) {
         LogFlowFunc(("reached maximum client limit\n"));
         return -1;
@@ -290,19 +276,19 @@
 
     /* Find an unused client entry. */
-    for (uint32_t i = 0; i < RT_ELEMENTS(ipcClientArray); i++)
-    {
-        if (!ipcClientArray[i].m_fUsed)
+    for (uint32_t i = 0; i < RT_ELEMENTS(pThis->ipcClientArray); i++)
+    {
+        if (!pThis->ipcClientArray[i].m_fUsed)
         {
-            ipcClientArray[i].Init(i, hSock);
-            ipcClientArray[i].m_fPollEvts = RTPOLL_EVT_READ;
-            int vrc = RTPollSetAddSocket(hPollSet, hSock, RTPOLL_EVT_READ, i);
+            pThis->ipcClientArray[i].Init(i, hSock);
+            pThis->ipcClientArray[i].m_fPollEvts = RTPOLL_EVT_READ;
+            int vrc = RTPollSetAddSocket(pThis->hPollSet, hSock, RTPOLL_EVT_READ, i);
             if (RT_SUCCESS(vrc))
             {
-                RTListAppend(&g_LstIpcClients, &ipcClientArray[i].NdClients);
-                ipcClientCount++;
+                RTListAppend(&g_LstIpcClients, &pThis->ipcClientArray[i].NdClients);
+                pThis->ipcClientCount++;
                 return 0;
             }
 
-            ipcClientArray[i].Finalize();
+            pThis->ipcClientArray[i].Finalize();
             break;
         }
@@ -313,12 +299,12 @@
 }
 
-static int RemoveClient(RTPOLLSET hPollSet, uint32_t idClient)
-{
-    int vrc = RTPollSetRemove(hPollSet, idClient);
+static int RemoveClient(PIPCDSTATE pThis, uint32_t idClient)
+{
+    int vrc = RTPollSetRemove(pThis->hPollSet, idClient);
     AssertRC(vrc); RT_NOREF(vrc);
 
-    RTListNodeRemove(&ipcClientArray[idClient].NdClients);
-    ipcClientArray[idClient].Finalize();
-    --ipcClientCount;
+    RTListNodeRemove(&pThis->ipcClientArray[idClient].NdClients);
+    pThis->ipcClientArray[idClient].Finalize();
+    pThis->ipcClientCount--;
     return 0;
 }
@@ -326,5 +312,5 @@
 //-----------------------------------------------------------------------------
 
-static void PollLoop(RTPOLLSET hPollSet, int fdListen)
+static void PollLoop(PIPCDSTATE pThis)
 {
     RTListInit(&g_LstIpcClients);
@@ -332,8 +318,8 @@
     for (;;)
     {
-        LogFlowFunc(("Polling [ipcClientCount=%d]\n", ipcClientCount));
+        LogFlowFunc(("Polling [ipcClientCount=%d]\n", pThis->ipcClientCount));
         uint32_t idPoll = 0;
         uint32_t fEvents = 0;
-        int vrc = RTPoll(hPollSet, 5 * RT_MS_1MIN, &fEvents, &idPoll);
+        int vrc = RTPoll(pThis->hPollSet, 5 * RT_MS_1MIN, &fEvents, &idPoll);
         if (RT_SUCCESS(vrc))
         { /* likely */ }
@@ -351,5 +337,5 @@
             LogFlowFunc(("Got new connection\n"));
 
-            int fdClient = accept(fdListen, NULL, NULL);
+            int fdClient = accept(pThis->fdListen, NULL, NULL);
             if (fdClient == -1)
             {
@@ -363,5 +349,5 @@
                 if (RT_SUCCESS(vrc))
                 {
-                    if (AddClient(hPollSet, hSock) != 0)
+                    if (AddClient(pThis, hSock) != 0)
                         RTSocketClose(hSock);
                 }
@@ -375,12 +361,12 @@
         else
         {
-            uint32_t fNewFlags = ipcClientArray[idPoll].Process(fEvents);
+            uint32_t fNewFlags = pThis->ipcClientArray[idPoll].Process(fEvents);
             if (!fNewFlags)
             {
                 /* Cleanup dead client. */
-                RemoveClient(hPollSet, idPoll);
+                RemoveClient(pThis, idPoll);
 
                 /* Shutdown if no clients. */
-                if (ipcClientCount == 0)
+                if (pThis->ipcClientCount == 0)
                 {
                     LogFlowFunc(("shutting down\n"));
@@ -388,10 +374,10 @@
                 }
             }
-            else if (ipcClientArray[idPoll].m_fPollEvts != fNewFlags)
+            else if (pThis->ipcClientArray[idPoll].m_fPollEvts != fNewFlags)
             {
                 /* Change flags. */
-                vrc = RTPollSetEventsChange(hPollSet, idPoll, fNewFlags);
+                vrc = RTPollSetEventsChange(pThis->hPollSet, idPoll, fNewFlags);
                 AssertRC(vrc);
-                ipcClientArray[idPoll].m_fPollEvts = fNewFlags;
+                pThis->ipcClientArray[idPoll].m_fPollEvts = fNewFlags;
             }
         }
@@ -425,6 +411,144 @@
 }
 
-//-----------------------------------------------------------------------------
-
+
+static int ipcdInit(PIPCDSTATE pThis, const char *pszSocketPath)
+{
+    pThis->fdListen       = 0;
+    pThis->hPollSet       = NIL_RTPOLLSET;
+    pThis->hSockListen    = NIL_RTSOCKET;
+    pThis->ipcLockFD      = 0;
+    pThis->ipcClientCount = 0;
+
+    struct sockaddr_un addr;
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+
+    // set socket address
+    if (!pszSocketPath)
+        IPC_GetDefaultSocketPath(addr.sun_path, sizeof(addr.sun_path));
+    else
+        RTStrCopy(addr.sun_path, sizeof(addr.sun_path), pszSocketPath);
+
+    Status status = InitDaemonDir(pThis, addr.sun_path);
+    if (status != EOk) {
+        if (status == ELockFileLock)
+            return VERR_ALREADY_EXISTS;
+        else
+        {
+            LogFlowFunc(("InitDaemonDir failed (status=%d)\n", status));
+            // don't notify the parent to cause it to fail in PR_Read() after
+            // we terminate
+            if (status != ELockFileOwner)
+                printf(("Cannot create a lock file for '%s'.\n"
+                        "Check permissions.\n", addr.sun_path));
+            return VERR_INVALID_PARAMETER;
+        }
+    }
+
+    pThis->fdListen = socket(PF_UNIX, SOCK_STREAM, 0);
+    if (pThis->fdListen == -1)
+    {
+        LogFlowFunc(("socket failed [%d]\n", errno));
+        return RTErrConvertFromErrno(errno);
+    }
+
+    if (bind(pThis->fdListen, (struct sockaddr *)&addr, sizeof(addr)))
+    {
+        LogFlowFunc(("bind failed [%d]\n", errno));
+        return RTErrConvertFromErrno(errno);
+    }
+
+    // Use large backlog, as otherwise local sockets can reject connection
+    // attempts. Usually harmless, but causes an unnecessary start attempt
+    // of IPCD (which will terminate straight away), and the next attempt
+    // usually succeeds. But better avoid unnecessary activities.
+    if (listen(pThis->fdListen, 128))
+    {
+        LogFlowFunc(("listen failed [%d]\n", errno));
+        return RTErrConvertFromErrno(errno);
+    }
+
+    // Increase the file table size to 10240 or as high as possible.
+    struct rlimit lim;
+    if (getrlimit(RLIMIT_NOFILE, &lim) == 0)
+    {
+        if (    lim.rlim_cur < 10240
+            &&  lim.rlim_cur < lim.rlim_max)
+        {
+            lim.rlim_cur = lim.rlim_max <= 10240 ? lim.rlim_max : 10240;
+            if (setrlimit(RLIMIT_NOFILE, &lim) == -1)
+                LogFlowFunc(("WARNING: failed to increase file descriptor limit. (%d)\n", errno));
+        }
+    }
+    else
+        LogFlowFunc(("WARNING: failed to obtain per-process file-descriptor limit (%d).\n", errno));
+
+    int vrc = RTSocketFromNative(&pThis->hSockListen, pThis->fdListen);
+    if (RT_FAILURE(vrc))
+    {
+        LogFlowFunc(("RTSocketFromNative() -> %Rrc\n", vrc));
+        return vrc;
+    }
+
+    pThis->fdListen = (int)RTSocketToNative(pThis->hSockListen);
+
+    vrc = RTPollSetCreate(&pThis->hPollSet);
+    if (RT_FAILURE(vrc))
+    {
+        LogFlowFunc(("RTPollSetCreate() -> %Rrc\n", vrc));
+        return vrc;
+    }
+
+    g_hPollSet = pThis->hPollSet;
+
+    vrc = RTPollSetAddSocket(pThis->hPollSet, pThis->hSockListen, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, UINT32_MAX - 1);
+    if (RT_FAILURE(vrc))
+    {
+        LogFlowFunc(("RTPollSetAddSocket() -> %Rrc\n", vrc));
+        return vrc;
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+static void ipcdTerm(PIPCDSTATE pThis)
+{
+    Assert(pThis->ipcClientCount == 0);
+
+    // it is critical that we release the lock before closing the socket,
+    // otherwise, a client might launch another daemon that would be unable
+    // to acquire the lock and would then leave the client without a daemon.
+
+    // deleting directory and files underneath it allows another process
+    // to think it has exclusive access.  better to just leave the hidden
+    // directory in /tmp and let the OS clean it up via the usual tmpdir
+    // cleanup cron job.
+
+    // this removes the advisory lock, allowing other processes to acquire it.
+    if (pThis->ipcLockFD) {
+        close(pThis->ipcLockFD);
+        pThis->ipcLockFD = 0;
+    }
+
+    int vrc = VINF_SUCCESS;
+    if (pThis->hPollSet != NIL_RTPOLLSET)
+    {
+        vrc = RTPollSetDestroy(pThis->hPollSet);
+        AssertRC(vrc);
+        pThis->hPollSet = NIL_RTPOLLSET;
+    }
+
+    if (pThis->hSockListen != NIL_RTSOCKET)
+    {
+        vrc = RTSocketClose(pThis->hSockListen);
+        AssertRC(vrc);
+        pThis->hSockListen = NIL_RTSOCKET;
+    }
+}
+
+
+//-----------------------------------------------------------------------------
+#ifndef VBOX_WITH_XPCOMIPCD_IN_VBOX_SVC
 int main(int argc, char **argv)
 {
@@ -482,119 +606,73 @@
     //IPC_Sleep(2);
 
-    struct sockaddr_un addr;
-    memset(&addr, 0, sizeof(addr));
-    addr.sun_family = AF_UNIX;
-
-    // set socket address
-    if (!pszSocketPath)
-        IPC_GetDefaultSocketPath(addr.sun_path, sizeof(addr.sun_path));
-    else
-        RTStrCopy(addr.sun_path, sizeof(addr.sun_path), pszSocketPath);
-
-#ifdef IPC_USE_FILE_LOCK
-    Status status = InitDaemonDir(addr.sun_path);
-    if (status != EOk) {
-        if (status == ELockFileLock) {
-            LogFlowFunc(("Another daemon is already running, exiting.\n"));
-            // send a signal to the blocked parent to indicate success
-            IPC_NotifyParent(uStartupPipeFd);
-            return 0;
-        }
-        else {
-            LogFlowFunc(("InitDaemonDir failed (status=%d)\n", status));
-            // don't notify the parent to cause it to fail in PR_Read() after
-            // we terminate
-            if (status != ELockFileOwner)
-                printf("Cannot create a lock file for '%s'.\n"
-                        "Check permissions.\n", addr.sun_path);
-            return 0;
-        }
-    }
+    IPCDSTATE IpcdState;
+    vrc = ipcdInit(&IpcdState, pszSocketPath);
+    if (vrc == VERR_ALREADY_EXISTS)
+    {
+        IPC_NotifyParent(uStartupPipeFd);
+        return 0;
+    }
+
+    if (RT_SUCCESS(vrc))
+    {
+        IPC_NotifyParent(uStartupPipeFd);
+        PollLoop(&IpcdState);
+    }
+
+    ipcdTerm(&IpcdState);
+    return 0;
+}
+
+#else
+
+static DECLCALLBACK(int) ipcdThread(RTTHREAD hThreadSelf, void *pvUser)
+{
+    IPCDSTATE IpcdState;
+
+    int vrc = ipcdInit(&IpcdState, NULL /*pszSocketPath*/);
+    *(int *)pvUser = vrc; /* Set the startup status code. */
+    RTThreadUserSignal(hThreadSelf);
+
+    if (RT_SUCCESS(vrc))
+        PollLoop(&IpcdState);
+
+    ipcdTerm(&IpcdState);
+    return VINF_SUCCESS;
+}
+
+
+DECL_EXPORT_NOTHROW(int) RTCALL VBoxXpcomIpcdCreate(PRTTHREAD phThrdIpcd)
+{
+    int vrcThrdStartup = VINF_SUCCESS;
+    int vrc = RTThreadCreate(phThrdIpcd, ipcdThread, &vrcThrdStartup, 0 /*cbStack*/, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "IPCD-Msg");
+    if (RT_FAILURE(vrc))
+        return vrc;
+
+    vrc = RTThreadUserWait(*phThrdIpcd, RT_MS_30SEC);
+    AssertRCReturn(vrc, vrc);
+
+    if (RT_FAILURE(vrcThrdStartup))
+    {
+        /* Wait for the thread to terminate. */
+        vrc = RTThreadWait(*phThrdIpcd, RT_MS_30SEC, NULL /*prc*/);
+        AssertRC(vrc);
+        *phThrdIpcd = NIL_RTTHREAD;
+        LogFlowFunc(("Creating daemon failed -> %Rrc\n", vrcThrdStartup));
+        return vrcThrdStartup;
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+DECL_EXPORT_NOTHROW(int) RTCALL VBoxXpcomIpcdDestroy(RTTHREAD hThrdIpcd)
+{
+    /* Normally just need to wait as this will get called when the last client has exited and VBoxSVC is shutting down. */
+    int vrcThrd = VINF_SUCCESS;
+    int vrc = RTThreadWait(hThrdIpcd, RT_MS_30SEC, &vrcThrd);
+    if (RT_FAILURE(vrc))
+        return vrc;
+
+    return vrcThrd;
+}
 #endif
-
-    int fdListen = socket(PF_UNIX, SOCK_STREAM, 0);
-    if (fdListen == -1)
-        LogFlowFunc(("socket failed [%d]\n", errno));
-    else
-    {
-        if (bind(fdListen, (struct sockaddr *)&addr, sizeof(addr)) == 0)
-        {
-            // Use large backlog, as otherwise local sockets can reject connection
-            // attempts. Usually harmless, but causes an unnecessary start attempt
-            // of IPCD (which will terminate straight away), and the next attempt
-            // usually succeeds. But better avoid unnecessary activities.
-            if (listen(fdListen, 128) == 0)
-            {
-                IPC_NotifyParent(uStartupPipeFd);
-
-#if defined(VBOX) && !defined(XP_OS2)
-                // Increase the file table size to 10240 or as high as possible.
-                struct rlimit lim;
-                if (getrlimit(RLIMIT_NOFILE, &lim) == 0)
-                {
-                    if (    lim.rlim_cur < 10240
-                        &&  lim.rlim_cur < lim.rlim_max)
-                    {
-                        lim.rlim_cur = lim.rlim_max <= 10240 ? lim.rlim_max : 10240;
-                        if (setrlimit(RLIMIT_NOFILE, &lim) == -1)
-                            printf("WARNING: failed to increase file descriptor limit. (%d)\n", errno);
-                    }
-                }
-                else
-                    printf("WARNING: failed to obtain per-process file-descriptor limit (%d).\n", errno);
-#endif
-
-                RTSOCKET hSockListen;
-                int vrc = RTSocketFromNative(&hSockListen, fdListen);
-                if (RT_SUCCESS(vrc))
-                {
-                    fdListen = (int)RTSocketToNative(hSockListen);
-
-                    RTPOLLSET hPollSet = NIL_RTPOLLSET;
-                    vrc = RTPollSetCreate(&hPollSet);
-                    if (RT_SUCCESS(vrc))
-                    {
-                        g_hPollSet = hPollSet;
-
-                        vrc = RTPollSetAddSocket(hPollSet, hSockListen, RTPOLL_EVT_READ | RTPOLL_EVT_ERROR, UINT32_MAX - 1);
-                        if (RT_SUCCESS(vrc))
-                            PollLoop(hPollSet, fdListen);
-                        else
-                            LogFlowFunc(("RTPollSetCreate() -> %Rrc\n", vrc));
-                    }
-                    else
-                        LogFlowFunc(("RTPollSetCreate() -> %Rrc\n", vrc));
-
-                    vrc = RTPollSetDestroy(hPollSet);
-                    AssertRC(vrc);
-                }
-                else
-                    LogFlowFunc(("RTSocketFromNative() -> %Rrc\n", vrc));
-
-                vrc = RTSocketClose(hSockListen);
-                AssertRC(vrc);
-                fdListen = -1;
-            }
-            else
-                LogFlowFunc(("listen failed [%d]\n", errno));
-        }
-        else
-            LogFlowFunc(("bind failed [%d]\n", errno));
-
-        LogFlowFunc(("closing socket\n"));
-        if (fdListen != -1)
-            close(fdListen);
-    }
-
-    //IPC_Sleep(5);
-
-#ifdef IPC_USE_FILE_LOCK
-    // it is critical that we release the lock before closing the socket,
-    // otherwise, a client might launch another daemon that would be unable
-    // to acquire the lock and would then leave the client without a daemon.
-
-    ShutdownDaemonDir();
-#endif
-
-    return 0;
-}
