Changeset 3373 for trunk


Ignore:
Timestamp:
May 27, 2007, 1:03:27 PM (18 years ago)
Author:
bird
Message:

Wait for spawned/execed child so it can finish inherting us. Close file handles on exec. Fixes #168.Fixes #167.

Location:
trunk/libc/src/kNIX
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/libc/src/kNIX/filehandles.c

    r3097 r3373  
    560560
    561561
     562/**
     563 * Called as a response to a successful exec so we can close
     564 * all open files.
     565 */
     566void        __libc_fhExecDone(void)
     567{
     568    LIBCLOG_ENTER("");
     569
     570    /*
     571     * This isn't thread safe, but there shouldn't be any threads
     572     * around so it'll have to do for now.
     573     */
     574    unsigned iFH;
     575    for (iFH = 0; iFH < gcFHs; iFH++)
     576    {
     577        __LIBC_PFH pFH = gpapFHs[iFH];
     578        if (pFH)
     579            __libc_FHClose(iFH);
     580    }
     581
     582    LIBCLOG_RETURN_VOID();
     583}
     584
     585
    562586
    563587#undef  __LIBC_LOG_GROUP
  • trunk/libc/src/kNIX/os2/__spawnve.c

    r2938 r3373  
    517517                __atomic_cmpxchg32((volatile uint32_t *)(void *)&pEmbryo->pid, (uint32_t)resc.codeTerminate, ~0);
    518518                LIBCLOG_MSG("Spawned pid=%04lx (%ld)\n", resc.codeTerminate, resc.codeTerminate);
    519                 __libc_back_processWaitNotifyExec(resc.codeTerminate);
    520 
    521                 /* cleanup embryo and other stuff. */
    522                 __libc_spmRelease(pEmbryo);
    523                 doInheritDone();
     519
     520                /*
     521                 * If the service is running, notify it now. Otherwise wait until
     522                 * we're done waiting for the child finish inheriting us.
     523                 */
     524                int fDoneNotifyExec = __libc_back_processWaitNotifyAlreadyStarted();
     525                if (fDoneNotifyExec)
     526                    __libc_back_processWaitNotifyExec(resc.codeTerminate);
     527
     528                /*
     529                 * Delay a tiny bit while the child is starting up and doing the inheriting.
     530                 * If we figure that it's a libc child, we can wait a good deal longer.
     531                 */
     532                /** @todo add a SPM notification for when inherit is completed. */
     533                __LIBC_SPMLOADAVG LoadAvg;
     534                unsigned uLoadAvgTS;
     535                int fDoneInherit;
     536                ULONG ulStart = fibGetMsCount();
     537                rc = 0;
     538                while (     (fDoneInherit = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE
     539                                         || (pEmbryo->pInherit == NULL && pEmbryo->pInheritLocked == NULL)
     540                            ) == 0
     541                       &&   fibGetMsCount() - ulStart <= 8)
     542                {
     543                    DosSleep(!(rc++ % 7));
     544                    __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
     545                }
     546                if (    !fDoneInherit
     547                    &&  pEmbryo->enmState == __LIBC_PROCSTATE_ALIVE)
     548                {
     549                    LIBCLOG_MSG("libc child - wait some more (rc=%d)\n", rc);
     550                    rc = 0;
     551                    __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
     552                    while (     (fDoneInherit = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE
     553                                             || (pEmbryo->pInherit == NULL && pEmbryo->pInheritLocked == NULL)
     554                                ) == 0
     555                           &&   fibGetMsCount() - ulStart <= 100)
     556                    {
     557                        DosSleep(!(rc++ % 7));
     558                        __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
     559                    }
     560                }
     561                LIBCLOG_MSG("fDoneInherit=%d rc=%d enmState=%d inh=%p,%p - waited %d ms\n",
     562                            fDoneInherit, rc, pEmbryo->enmState, pEmbryo->pInherit, pEmbryo->pInheritLocked, fibGetMsCount() - ulStart);
     563
     564                /*
     565                 * Do cleanups unless we're in an exec in which case we wish to
     566                 * get some more stuff done before we do the clean ups.
     567                 */
     568                if ((ulMode & 0xff) != P_OVERLAY)
     569                {
     570                    doInheritDone();
     571                    if (!fDoneNotifyExec)
     572                        __libc_back_processWaitNotifyExec(resc.codeTerminate);
     573                    __libc_spmRelease(pEmbryo);
     574                    _fmutex_release(&__libc_gmtxExec);
     575                }
    524576                if (pszArgsBuf != NULL)
    525577                    _tfree(pszArgsBuf);
    526                 _fmutex_release(&__libc_gmtxExec);
    527578
    528579                /*
     
    575626
    576627                        /*
    577                          * Wait
     628                         * Wait a bit more for the child to catch on since we're going to
     629                         * close all file handles next and that we certainly screw up tcpip
     630                         * handles in the child if they aren't already passed along.
     631                         */
     632                        if (!fDoneInherit)
     633                        {
     634                            LIBCLOG_MSG("waiting some more...\n");
     635                            do
     636                            {
     637                                DosSleep(!(rc++ % 3));
     638                                __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
     639                                fDoneInherit = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE
     640                                            || (pEmbryo->pInherit == NULL && pEmbryo->pInheritLocked == NULL);
     641                            } while (!fDoneInherit
     642                                  && fibGetMsCount() - ulStart <= 200);
     643                            LIBCLOG_MSG("fDoneInherit=%d rc=%d enmState=%d inh=%p,%p - waited %d ms\n",
     644                                        fDoneInherit, rc, pEmbryo->enmState, pEmbryo->pInherit, pEmbryo->pInheritLocked, fibGetMsCount() - ulStart);
     645                        }
     646
     647                        if (!fDoneNotifyExec)
     648                            __libc_back_processWaitNotifyExec(resc.codeTerminate);
     649                        __libc_spmRelease(pEmbryo);
     650                        doInheritDone();
     651                        _fmutex_release(&__libc_gmtxExec);
     652
     653                        /*
     654                         * Shut down the process...
     655                         */
     656                        _rmtmp();
     657                        __libc_fhExecDone();
     658
     659                        /*
     660                         * Wait for the child to complete and forward stuff while doing so...
    578661                         */
    579662                        pid_t pid = resc.codeTerminate;
  • trunk/libc/src/kNIX/os2/b_processWait.c

    r2929 r3373  
    584584    }
    585585    return -ENOMEM;
     586}
     587
     588
     589/**
     590 * Checks whether the service has already been started.
     591 *
     592 * @return 1 if started, 0 if not.
     593 */
     594int __libc_back_processWaitNotifyAlreadyStarted(void)
     595{
     596    return gtidThread != 0;
    586597}
    587598
  • trunk/libc/src/kNIX/os2/kNIX-os2.h

    r2942 r3373  
    245245
    246246void __libc_back_processWaitNotifyTerm(void);
     247int  __libc_back_processWaitNotifyAlreadyStarted(void);
    247248void __libc_back_processWaitNotifyExec(pid_t pid);
    248249void __libc_back_processWaitNotifyChild(siginfo_t *pSigInfo);
  • trunk/libc/src/kNIX/os2/sharedpm.c

    r2937 r3373  
    27622762
    27632763        /* update state and insert at head of that state list. */
    2764         pProcess->enmState = __LIBC_PROCSTATE_ALIVE;
     2764        LIBC_ASSERT(sizeof(pProcess->enmState) == sizeof(int));
     2765        __lxchg((int volatile *)&pProcess->enmState, __LIBC_PROCSTATE_ALIVE);
    27652766        pProcess->pNext = gpSPMHdr->apHeads[__LIBC_PROCSTATE_ALIVE];
    27662767        if (pProcess->pNext)
  • trunk/libc/src/kNIX/os2/syscalls.h

    r2936 r3373  
    6464EXTERN _fmutex          __libc_gmtxExec INIT({0});
    6565#endif
     66void                    __libc_fhExecDone(void);
    6667/** @} */
    6768
Note: See TracChangeset for help on using the changeset viewer.