Index: branches/libc-0.6/src/emx/include/InnoTekLIBC/sharedpm.h
===================================================================
--- branches/libc-0.6/src/emx/include/InnoTekLIBC/sharedpm.h	(revision 3640)
+++ branches/libc-0.6/src/emx/include/InnoTekLIBC/sharedpm.h	(revision 3643)
@@ -652,6 +652,4 @@
 
 
-
-
 /**
  * Gets the current process.
@@ -696,4 +694,13 @@
  */
 __LIBC_PSPMPROCESS __libc_spmCreateEmbryo(pid_t pidParent);
+
+/**
+ * Wait for a embryo to become a live process and complete 
+ * inheriting (file handles / sockets issues).
+ *
+ * @returns non-zero if the process has started.
+ * @param   pEmbryo         The embry process.
+ */
+int __libc_spmWaitForChildToBecomeAlive(__LIBC_PSPMPROCESS pEmbryo);
 
 /**
Index: branches/libc-0.6/src/emx/src/lib/sys/__spawnve.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/sys/__spawnve.c	(revision 3640)
+++ branches/libc-0.6/src/emx/src/lib/sys/__spawnve.c	(revision 3643)
@@ -514,38 +514,9 @@
 
                 /*
-                 * Delay a tiny bit while the child is starting up and doing the inheriting.
-                 * If we figure that it's a libc child, we can wait a good deal longer.
-                 */
-                /** @todo add a SPM notification for when inherit is completed. */
-                __LIBC_SPMLOADAVG LoadAvg;
-                unsigned uLoadAvgTS;
-                int fDoneInherit;
-                ULONG ulStart = fibGetMsCount();
-                rc = 0;
-                while (     (fDoneInherit = pEmbryo->enmState >= __LIBC_PROCSTATE_ALIVE
-                                         || (pEmbryo->pInherit == NULL && pEmbryo->pInheritLocked == NULL)
-                            ) == 0
-                       &&   fibGetMsCount() - ulStart <= 8)
-                {
-                    DosSleep(rc++ > 4);
-                    __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
-                }
-                if (    !fDoneInherit
-                    &&  pEmbryo->enmState == __LIBC_PROCSTATE_ALIVE)
-                {
-                    LIBCLOG_MSG("libc child - wait some more (rc=%d)\n", rc);
-                    rc = 0;
-                    __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
-                    while (     (fDoneInherit = pEmbryo->enmState >= __LIBC_PROCSTATE_ALIVE
-                                             || (pEmbryo->pInherit == NULL && pEmbryo->pInheritLocked == NULL)
-                                ) == 0
-                           &&   fibGetMsCount() - ulStart <= 100)
-                    {
-                        DosSleep(rc++ > 4);
-                        __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
-                    }
-                }
-                LIBCLOG_MSG("fDoneInherit=%d rc=%d enmState=%d inh=%p,%p - waited %d ms\n",
-                            fDoneInherit, rc, pEmbryo->enmState, pEmbryo->pInherit, pEmbryo->pInheritLocked, fibGetMsCount() - ulStart);
+                 * Wait for the child to become active and complete the inhertining.
+                 */
+                int fDoneInherit = __libc_spmWaitForChildToBecomeAlive(pEmbryo);
+                LIBCLOG_MSG("fDoneInherit=%d enmState=%d inh=%p,%p\n",
+                            fDoneInherit, pEmbryo->enmState, pEmbryo->pInherit, pEmbryo->pInheritLocked);
 
                 /*
@@ -620,14 +591,7 @@
                         {
                             LIBCLOG_MSG("waiting some more...\n");
-                            do
-                            {
-                                DosSleep(!(rc++ % 3));
-                                __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
-                                fDoneInherit = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE
-                                            || (pEmbryo->pInherit == NULL && pEmbryo->pInheritLocked == NULL);
-                            } while (!fDoneInherit
-                                  && fibGetMsCount() - ulStart <= 200);
-                            LIBCLOG_MSG("fDoneInherit=%d rc=%d enmState=%d inh=%p,%p - waited %d ms\n",
-                                        fDoneInherit, rc, pEmbryo->enmState, pEmbryo->pInherit, pEmbryo->pInheritLocked, fibGetMsCount() - ulStart);
+                            fDoneInherit = __libc_spmWaitForChildToBecomeAlive(pEmbryo);
+                            LIBCLOG_MSG("fDoneInherit=%d enmState=%d inh=%p,%p\n",
+                                        fDoneInherit, pEmbryo->enmState, pEmbryo->pInherit, pEmbryo->pInheritLocked);
                         }
 
Index: branches/libc-0.6/src/emx/src/lib/sys/sharedpm.c
===================================================================
--- branches/libc-0.6/src/emx/src/lib/sys/sharedpm.c	(revision 3640)
+++ branches/libc-0.6/src/emx/src/lib/sys/sharedpm.c	(revision 3643)
@@ -395,4 +395,10 @@
             DosGetInfoBlocks(&pTib, &pPib);
             pProcess = spmRegisterSelf(pPib->pib_ulpid, pPib->pib_ulppid, pLIS->sgCurrent);
+            if (pProcess)
+            {
+                LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
+                APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify);
+                LIBC_ASSERTM(!rc2, "rc2=%ld!\n", rc2); rc2 = rc2;
+            }
             FS_RESTORE();
         }
@@ -485,5 +491,8 @@
             LIBC_ASSERTM(!gpSPMSelf->pInheritLocked, "Trying to free a locked inherit struct!\n");
 
+            LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
+            APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify);
             spmReleaseMutex(&RegRec);
+            LIBC_ASSERTM(!rc2, "rc2=%ld!\n", rc2); rc2 = rc2;
         }
     }
@@ -620,4 +629,93 @@
 
 /**
+ * Wait for a embryo to become a live process and complete 
+ * inheriting (file handles / sockets issues).
+ *
+ * @returns non-zero if the process has started.
+ * @param   pEmbryo         The embry process.
+ */
+int __libc_spmWaitForChildToBecomeAlive(__LIBC_PSPMPROCESS pEmbryo)
+{
+    LIBCLOG_ENTER("pEmbryo=%p\n", pEmbryo);
+    int                     cLoops;
+    __LIBC_SPMXCPTREGREC    RegRec;
+    ULONG                   ulIgnored;
+    int                     fAlive = 0;
+    APIRET                  rc = 0;
+    ULONG                   ulStart = 0;
+    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulStart, sizeof(ulStart));
+
+    /* 
+     * Wait for the process to become ready, 8 ms max.
+     * However, if it becomes alive in that period we know it's a libc 
+     * process and will wait a bit more (130 ms) for it to finishing
+     * initialization and inheritance.
+     */
+    for (cLoops = 0; ; cLoops++) 
+    {
+        /* 
+         * Reset the notification event sem. 
+         */
+        spmRequestMutex(&RegRec);
+        fAlive = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE
+              || (   pEmbryo->pInherit == NULL 
+                  && pEmbryo->pInheritLocked == NULL
+                  && pEmbryo->enmState == __LIBC_PROCSTATE_ALIVE);
+        if (!fAlive)
+            DosResetEventSem(gpSPMHdr->hevNotify, &ulIgnored);
+        spmReleaseMutex(&RegRec);
+        if (fAlive)
+            break; /* done */
+
+        /* 
+         * Calc the time we should sleep. 
+         */
+        ULONG ulNow = 0;
+        DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &ulNow, sizeof(ulNow));
+        ULONG ulSleep = ulNow - ulStart;
+        if (ulSleep < 8)
+        {
+            ulSleep = 8 - ulSleep;
+            LIBCLOG_MSG("wait %lu ms (cLoops=%d rc=%ld)\n", ulSleep, cLoops, rc);
+        }
+        else if (pEmbryo->enmState != __LIBC_PROCSTATE_ALIVE)
+            break; /* giving up */
+        else if (ulSleep < 130)
+        {
+            ulSleep = 130 - ulSleep;
+            if (ulSleep > 8)
+                ulSleep = 8; /* reset race protection */
+            LIBCLOG_MSG("libc child - wait %lu ms (cLoops=%d rc=%ld)\n", ulSleep, cLoops, rc);
+        }
+        else 
+            break; /* giving up */
+
+        /* 
+         * Recheck before going to sleep on the event sem. 
+         */
+        fAlive = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE
+              || (   pEmbryo->pInherit == NULL 
+                  && pEmbryo->pInheritLocked == NULL
+                  && pEmbryo->enmState == __LIBC_PROCSTATE_ALIVE);
+        if (fAlive)
+            break; /* done */
+
+        if (    gpSPMHdr->hevNotify 
+            &&  (rc == NO_ERROR || rc == ERROR_TIMEOUT || rc == ERROR_SEM_TIMEOUT))
+            rc = DosWaitEventSem(gpSPMHdr->hevNotify, ulSleep);
+        else
+        {
+            /* fallback if the sem is busted or for old libc initializing spm. */
+            DosSleep(cLoops > 8);
+
+            __LIBC_SPMLOADAVG LoadAvg; /* SPM hack */
+            __libc_spmSetLoadAvg(&LoadAvg);
+        }
+    }
+    LIBCLOG_RETURN_INT(fAlive);
+}
+
+
+/**
  * Searches for a process given by pid.
  *
@@ -2121,5 +2219,5 @@
 
     /*
-     * Check if initatied.
+     * Check if initiated.
      */
     if (!ghmtxSPM || !gpSPMHdr)
@@ -2312,4 +2410,8 @@
             if (!gpSPMHdr->cSigMaxActive)
                 gpSPMHdr->cSigMaxActive = 1024;
+            if (gpSPMHdr->hevNotify)
+                rc = DosOpenEventSem(NULL, &gpSPMHdr->hevNotify);
+            else
+                rc = DosCreateEventSem(NULL, &gpSPMHdr->hevNotify, DC_SEM_SHARED, FALSE);
         }
         else
@@ -2373,10 +2475,17 @@
         {
             /*
-             * Register the current process and increment open counter.
+             * Register the current process, increment open counter,
+             * and notify everyone that spm data has changed.
              */
             PLINFOSEG pLIS = GETLINFOSEG();
             spmRegisterSelf(pPib->pib_ulpid, pPib->pib_ulppid, pLIS->sgCurrent);
             if (gpSPMSelf)
+            {
                 gpSPMSelf->cSPMOpens++;
+
+                LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
+                APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify);
+                LIBC_ASSERTM(!rc2, "rc2=%ld!\n", rc2); rc2 = rc2;
+            }
 
             /*
@@ -2558,5 +2667,8 @@
                     *pParent->ppChildNotifyTail = pTerm;
                     pParent->ppChildNotifyTail = &pTerm->pNext;
-                    DosPostEventSem(gpSPMHdr->hevNotify);
+                    
+                    LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
+                    APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify);
+                    LIBC_ASSERTM(!rc2, "rc2=%ld!\n", rc2); rc2 = rc2;
                 }
                 else
@@ -3180,5 +3292,7 @@
 
                 /* post notification sem. */
-                DosPostEventSem(gpSPMHdr->hevNotify);
+                LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
+                APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify);
+                LIBC_ASSERTM(!rc2, "rc2=%ld!\n", rc2); rc2 = rc2;
             }
             else
@@ -3382,4 +3496,9 @@
                     spmFreeProcess(pProcess);
                     pProcess = pProcessNext;
+                    
+                    /* Wake up the embryo waiters (paranoia). */
+                    LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
+                    APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify);
+                    LIBC_ASSERTM(!rc2, "rc2=%ld!\n", rc2); rc2 = rc2;
                     continue;
                 }
@@ -3473,4 +3592,9 @@
                         spmFreeProcess(pProcess);
                         pProcess = pProcessNext;
+                        
+                        /* Wake up the embryo waiters (paranoia). */
+                        LIBCLOG_MSG("posting %#lx\n", gpSPMHdr->hevNotify);
+                        APIRET rc2 = DosPostEventSem(gpSPMHdr->hevNotify);
+                        LIBC_ASSERTM(!rc2, "rc2=%ld!\n", rc2); rc2 = rc2;
                         continue;
                     }
