Changeset 2211 for trunk


Ignore:
Timestamp:
Jul 6, 2005, 5:45:59 AM (20 years ago)
Author:
bird
Message:

o Fixed spawn/fork + fork() + exec/spawn/fork in the child.
o Kill any known decentants to prevent them from being

adopted by our parent. (On UNIX processes begin made
orphants are adopted and killed by the init process.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/src/lib/sys/b_processWait.c

    • Property cvs2svn:cvs-rev changed from 1.8 to 1.9
    r2210 r2211  
    5050#include <InnoTekLIBC/backend.h>
    5151#include <InnoTekLIBC/FastInfoBlocks.h>
     52#include <InnoTekLIBC/fork.h>
    5253#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_BACK_PROCESS
    5354#include <InnoTekLIBC/logstrict.h>
     
    119120/** List of known children. */
    120121static volatile PWAITCHILD  gpChildrenHead;
     122/** List of free known children. */
     123static volatile PWAITCHILD  gpChildrenFree;
    121124/** Number of known child processes. */
    122125static volatile unsigned    gcChildren;
     
    149152static int  waitAllocInsert(const PWAITINFO pWaitInsert);
    150153static inline void waitInfoToSigInfo(const PWAITINFO pWait, siginfo_t *pSigInfo);
     154static int processWaitForkChildHook(__LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation);
    151155
    152156
     
    192196    if (gtidThread)
    193197    {
    194         /* kill the thread */
     198        /* kill the thread - this is probably a waste of time in the exitlist handler... */
    195199        __atomic_xchg(&gfTerminate, 1);
    196200        DosKillThread(gtidThread);
     
    214218        DosPostEventSem(hev);
    215219        DosCloseEventSem(hev);
     220    }
     221
     222    /*
     223     * Kill all known decendants.
     224     */
     225    PWAITCHILD pChild = gpChildrenHead;
     226    if (pChild)
     227    {
     228        /*
     229         * Kill the process tree so we don't end up having childrens
     230         * children popping in behind us.
     231         *
     232         * We boots our priority trying to make sure we get the message
     233         * down fast. Going back to regular shouldn't be problem since we're
     234         * doing exit lists now anyways.
     235         */
     236        DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 1, 0);
     237        for (; pChild; pChild = pChild->pNext)
     238            DosKillProcess(DKP_PROCESSTREE, pChild->pid);
     239        DosSetPriority(PRTYS_THREAD, PRTYC_REGULAR, 0, 0);
     240        DosSleep(0);
     241
     242        /*
     243         * We reap all possible decendants to as much as possible prevent anyone
     244         * waitin for immediate children to not be bothered with it but just get
     245         * the heck out and terminate.
     246         */
     247        RESULTCODES res;
     248        PID pid;
     249        while (!DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &res, &pid, 0))
     250            /* nothing */;
     251        DosSleep(1); /* penalty / chance to exit */
     252        while (!DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &res, &pid, 0))
     253            /* nothing */;
     254        DosSleep(0);
     255        while (!DosWaitChild(DCWA_PROCESSTREE, DCWW_NOWAIT, &res, &pid, 0))
     256            /* nothing */;
    216257    }
    217258}
     
    328369                    else
    329370                        gpChildrenHead = pChild->pNext;
     371                    pChild->pNext = gpChildrenFree;
     372                    gpChildrenFree = pChild;
    330373                    __atomic_decrement_min(&gcChildren, 0);
    331374                    break;
     
    570613void __libc_back_processWaitNotifyExec(pid_t pid)
    571614{
    572     PWAITCHILD pChild = _hmalloc(sizeof(*pChild));
    573     waitSemRequest(0);
     615    /*
     616     * Allocate and enter semaphore protection.
     617     */
     618    PWAITCHILD pChild = NULL;
     619    if (gpChildrenFree)
     620    {
     621        waitSemRequest(0);
     622        pChild = gpChildrenFree;
     623        if (pChild)
     624            gpChildrenFree = pChild->pNext;
     625        else
     626            waitSemRelease();
     627    }
     628    if (!pChild)
     629    {
     630        pChild = _hmalloc(sizeof(*pChild));
     631        waitSemRequest(0);
     632    }
    574633
    575634    /*
     
    9791038                       rc, pSigInfo->si_pid, pSigInfo->si_code, pSigInfo->si_status);
    9801039}
     1040
     1041
     1042_FORK_CHILD1(0xf0010000, processWaitForkChildHook)
     1043
     1044/**
     1045 * Callback function for registration using _FORK_PARENT1()
     1046 * or _FORK_CHILD1().
     1047 *
     1048 * @returns 0 on success.
     1049 * @returns positive errno on warning.
     1050 * @returns negative errno on failure. Fork will be aborted.
     1051 * @param   pForkHandle     Pointer to fork handle.
     1052 * @param   enmOperation    Callback operation.
     1053 */
     1054static int processWaitForkChildHook(__LIBC_PFORKHANDLE pForkHandle, __LIBC_FORKOP enmOperation)
     1055{
     1056    switch (enmOperation)
     1057    {
     1058        /*
     1059         * Have to reset the globals to indicate no waiter thread.
     1060         */
     1061        case __LIBC_FORK_OP_FORK_CHILD:
     1062        {
     1063            PWAITINFO pInfo = gpWaitHead;
     1064            while (pInfo)
     1065            {
     1066                PWAITINFO p = pInfo;
     1067                pInfo = pInfo->pNext;
     1068                p->pNext = gpWaitFree;
     1069                gpWaitFree = pInfo;
     1070            }
     1071            gpWaitHead      = NULL;
     1072            gpWaitTail      = NULL;
     1073
     1074            PWAITCHILD pChild = gpChildrenHead;
     1075            if (pChild)
     1076            {
     1077                gpChildrenHead = NULL;
     1078                pChild->pNext = gpChildrenFree;
     1079                gpChildrenFree = pChild;
     1080            }
     1081            gcChildren      = 0;
     1082            gcBirths        = 0;
     1083            gcDeaths        = 0;
     1084            //gfNoWaitStatus ???
     1085            gtidThread      = 0;
     1086            gfTerminate     = 0;
     1087            break;
     1088        }
     1089
     1090        default:
     1091            break;
     1092    }
     1093    return 0;
     1094}
     1095
Note: See TracChangeset for help on using the changeset viewer.