Changeset 3373


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.

Files:
12 edited

Legend:

Unmodified
Added
Removed
  • branches/libc-0.6/src/emx/src/lib/sys/__spawnve.c

    r2540 r3373  
    504504                __atomic_cmpxchg32((volatile uint32_t *)(void *)&pEmbryo->pid, (uint32_t)resc.codeTerminate, ~0);
    505505                LIBCLOG_MSG("Spawned pid=%04lx (%ld)\n", resc.codeTerminate, resc.codeTerminate);
    506                 __libc_back_processWaitNotifyExec(resc.codeTerminate);
    507 
    508                 /* cleanup embryo and other stuff. */
    509                 __libc_spmRelease(pEmbryo);
    510                 doInheritDone();
     506
     507                /*
     508                 * If the service is running, notify it now. Otherwise wait until
     509                 * we're done waiting for the child finish inheriting us.
     510                 */
     511                int fDoneNotifyExec = __libc_back_processWaitNotifyAlreadyStarted();
     512                if (fDoneNotifyExec)
     513                    __libc_back_processWaitNotifyExec(resc.codeTerminate);
     514
     515                /*
     516                 * Delay a tiny bit while the child is starting up and doing the inheriting.
     517                 * If we figure that it's a libc child, we can wait a good deal longer.
     518                 */
     519                /** @todo add a SPM notification for when inherit is completed. */
     520                __LIBC_SPMLOADAVG LoadAvg;
     521                unsigned uLoadAvgTS;
     522                int fDoneInherit;
     523                ULONG ulStart = fibGetMsCount();
     524                rc = 0;
     525                while (     (fDoneInherit = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE
     526                                         || (pEmbryo->pInherit == NULL && pEmbryo->pInheritLocked == NULL)
     527                            ) == 0
     528                       &&   fibGetMsCount() - ulStart <= 8)
     529                {
     530                    DosSleep(!(rc++ % 7));
     531                    __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
     532                }
     533                if (    !fDoneInherit
     534                    &&  pEmbryo->enmState == __LIBC_PROCSTATE_ALIVE)
     535                {
     536                    LIBCLOG_MSG("libc child - wait some more (rc=%d)\n", rc);
     537                    rc = 0;
     538                    __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
     539                    while (     (fDoneInherit = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE
     540                                             || (pEmbryo->pInherit == NULL && pEmbryo->pInheritLocked == NULL)
     541                                ) == 0
     542                           &&   fibGetMsCount() - ulStart <= 100)
     543                    {
     544                        DosSleep(!(rc++ % 7));
     545                        __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
     546                    }
     547                }
     548                LIBCLOG_MSG("fDoneInherit=%d rc=%d enmState=%d inh=%p,%p - waited %d ms\n",
     549                            fDoneInherit, rc, pEmbryo->enmState, pEmbryo->pInherit, pEmbryo->pInheritLocked, fibGetMsCount() - ulStart);
     550
     551                /*
     552                 * Do cleanups unless we're in an exec in which case we wish to
     553                 * get some more stuff done before we do the clean ups.
     554                 */
     555                if ((ulMode & 0xff) != P_OVERLAY)
     556                {
     557                    doInheritDone();
     558                    if (!fDoneNotifyExec)
     559                        __libc_back_processWaitNotifyExec(resc.codeTerminate);
     560                    __libc_spmRelease(pEmbryo);
     561                    _fmutex_release(&__libc_gmtxExec);
     562                }
    511563                if (pszArgsBuf != NULL)
    512564                    _tfree(pszArgsBuf);
    513                 _fmutex_release(&__libc_gmtxExec);
    514565
    515566                /*
     
    562613
    563614                        /*
    564                          * Wait
     615                         * Wait a bit more for the child to catch on since we're going to
     616                         * close all file handles next and that we certainly screw up tcpip
     617                         * handles in the child if they aren't already passed along.
     618                         */
     619                        if (!fDoneInherit)
     620                        {
     621                            LIBCLOG_MSG("waiting some more...\n");
     622                            do
     623                            {
     624                                DosSleep(!(rc++ % 3));
     625                                __libc_spmGetLoadAvg(&LoadAvg, &uLoadAvgTS); /* SMP HACK */
     626                                fDoneInherit = pEmbryo->enmState > __LIBC_PROCSTATE_ALIVE
     627                                            || (pEmbryo->pInherit == NULL && pEmbryo->pInheritLocked == NULL);
     628                            } while (!fDoneInherit
     629                                  && fibGetMsCount() - ulStart <= 200);
     630                            LIBCLOG_MSG("fDoneInherit=%d rc=%d enmState=%d inh=%p,%p - waited %d ms\n",
     631                                        fDoneInherit, rc, pEmbryo->enmState, pEmbryo->pInherit, pEmbryo->pInheritLocked, fibGetMsCount() - ulStart);
     632                        }
     633
     634                        if (!fDoneNotifyExec)
     635                            __libc_back_processWaitNotifyExec(resc.codeTerminate);
     636                        __libc_spmRelease(pEmbryo);
     637                        doInheritDone();
     638                        _fmutex_release(&__libc_gmtxExec);
     639
     640                        /*
     641                         * Shut down the process...
     642                         */
     643                        _rmtmp();
     644                        __libc_fhExecDone();
     645
     646                        /*
     647                         * Wait for the child to complete and forward stuff while doing so...
    565648                         */
    566649                        pid_t pid = resc.codeTerminate;
  • branches/libc-0.6/src/emx/src/lib/sys/b_process.h

    r1631 r3373  
    44 * LIBC Backend - Process Internals.
    55 *
    6  * Copyright (c) 2004 knut st. osmundsen <bird-srcspam@anduin.net>
     6 * Copyright (c) 2004-2007 knut st. osmundsen <bird-srcspam@anduin.net>
    77 *
    88 *
     
    3737
    3838void __libc_back_processWaitNotifyTerm(void);
     39int  __libc_back_processWaitNotifyAlreadyStarted(void);
    3940void __libc_back_processWaitNotifyExec(pid_t pid);
    4041void __libc_back_processWaitNotifyChild(siginfo_t *pSigInfo);
  • branches/libc-0.6/src/emx/src/lib/sys/b_processWait.c

    r2786 r3373  
    603603    }
    604604    return -ENOMEM;
     605}
     606
     607
     608/**
     609 * Checks whether the service has already been started.
     610 *
     611 * @return 1 if started, 0 if not.
     612 */
     613int __libc_back_processWaitNotifyAlreadyStarted(void)
     614{
     615    return gtidThread != 0;
    605616}
    606617
  • branches/libc-0.6/src/emx/src/lib/sys/filehandles.c

    r3098 r3373  
    552552
    553553
     554/**
     555 * Called as a response to a successful exec so we can close
     556 * all open files.
     557 */
     558void        __libc_fhExecDone(void)
     559{
     560    LIBCLOG_ENTER("");
     561
     562    /*
     563     * This isn't thread safe, but there shouldn't be any threads
     564     * around so it'll have to do for now.
     565     */
     566    unsigned iFH;
     567    for (iFH = 0; iFH < gcFHs; iFH++)
     568    {
     569        __LIBC_PFH pFH = gpapFHs[iFH];
     570        if (pFH)
     571            __libc_FHClose(iFH);
     572    }
     573
     574    LIBCLOG_RETURN_VOID();
     575}
     576
     577
    554578
    555579#undef  __LIBC_LOG_GROUP
  • branches/libc-0.6/src/emx/src/lib/sys/sharedpm.c

    r2425 r3373  
    27912791
    27922792        /* update state and insert at head of that state list. */
    2793         pProcess->enmState = __LIBC_PROCSTATE_ALIVE;
     2793        LIBC_ASSERT(sizeof(pProcess->enmState) == sizeof(int));
     2794        __lxchg((int volatile *)&pProcess->enmState, __LIBC_PROCSTATE_ALIVE);
    27942795        pProcess->pNext = gpSPMHdr->apHeads[__LIBC_PROCSTATE_ALIVE];
    27952796        if (pProcess->pNext)
  • branches/libc-0.6/src/emx/src/lib/sys/syscalls.h

    r2323 r3373  
    146146EXTERN _fmutex          __libc_gmtxExec INIT({0});
    147147#endif
     148void                    __libc_fhExecDone(void);
    148149/** @} */
    149150
  • 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.