Ignore:
Timestamp:
Aug 27, 2006, 4:26:13 PM (19 years ago)
Author:
bird
Message:

Fixed problems with fork() and module loading/unloading. Fixes #76.
Fixed atexit() and on_exit() problem with callbacks in unloaded DLLs. Fixes #103.

Location:
branches/libc-0.6/src/emx
Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • branches/libc-0.6/src/emx/ChangeLog.LIBC

    r2685 r2786  
    22
    33TODO: open replace on RAMFS fails with error 32!
     4
     52006-08-27: knut st. osmundsen <bird-gccos2-spam@anduin.net>
     6    - libc:
     7        o Fixed problems with fork() and module loading/unloading. Fixes #76.
     8        o Fixed atexit() and on_exit() problem with callbacks in unloaded DLLs. Fixes #103.
     9        o Added usage counting to _CRT_init and _CRT_term. Fixing #114.
    410
    5112006-03-26: knut st. osmundsen <bird-gccos2-spam@anduin.net>
  • branches/libc-0.6/src/emx/include/InnoTekLIBC/atexit.h

    r1905 r2786  
    3737    __LIBC_ATEXITTYPE_ONEXIT,
    3838    /** State transition state. */
    39     __LIBC_ATEXITTYPE_TRANS
     39    __LIBC_ATEXITTYPE_TRANS,
     40    /** The module containing the callback was unloaded. */
     41    __LIBC_ATEXITTYPE_UNLOADED
    4042} __LIBC_ATEXITTYPE;
    4143
     
    4749    /** Entry type. */
    4850    __LIBC_ATEXITTYPE volatile enmType;
     51    /** The (native) module handle this callback is connected to.
     52     * This will be 0 if no such association. */
     53    uintptr_t                  hmod;
    4954    union
    5055    {
     
    9297 * @returns Pointer to new entry.
    9398 * @returns NULL on failure.
     99 *
     100 * @param   pvCallback      The callback address.
     101 *                          This used to initialize the __LIBC_AT_EXIT::hmod field.
    94102 */
    95 __LIBC_PATEXIT __libc_atexit_new(void);
     103__LIBC_PATEXIT __libc_atexit_new(void *pvCallback);
     104
     105/**
     106 * Invalidate all atexit and on_exit callback for a
     107 * module which is being unloaded.
     108 *
     109 * @param   hmod        The module handle.
     110 */
     111void __libc_atexit_unload(uintptr_t hmod);
    96112
    97113__END_DECLS
  • branches/libc-0.6/src/emx/include/InnoTekLIBC/fork.h

    r2320 r2786  
    575575/** Indicates that the module is an executable. */
    576576#define __LIBC_FORKMODULE_FLAGS_EXECUTABLE      0x00000001
    577 /** Indicates that the module was dynamically loaded. */
    578 #define __LIBC_FORKMODULE_FLAGS_DYNAMIC         0x00010000
     577/** Indicates that the module already has been deregistered (libc termination). */
     578#define __LIBC_FORKMODULE_FLAGS_DEREGISTERED    0x00010000
    579579/** @} */
    580580
     
    606606 */
    607607int __libc_ForkRegisterModule(__LIBC_PFORKMODULE pModule, int fExecutable);
     608
     609
     610/**
     611 * Deregister a forkable module. Called by dll0.
     612 *
     613 * The call links pModule out of the list of forkable modules
     614 * which is maintained in the process block.
     615 *
     616 * @param   pModule     Pointer to the fork module structure for the
     617 *                      module which is to registered.
     618 */
     619void __libc_ForkDeregisterModule(__LIBC_PFORKMODULE pModule);
    608620
    609621
  • branches/libc-0.6/src/emx/src/lib/libc.def

    r2685 r2786  
    19531953    "__std_getdirents" @1951
    19541954    "___libc_Back_ioFileControlStandard" @1952
     1955    "___libc_Back_termDll" @1953
     1956    "___libc_ForkDeregisterModule" @1954
  • branches/libc-0.6/src/emx/src/lib/libc.smak

    r2495 r2786  
    7575include mklib.smak
    7676
    77                                        
     77
    7878#------------------------------------------------------
    7979# Now define the rules for building libc$(VERSION).dll
     
    178178endef
    179179$(foreach o,$(LIBC.OBJS.COMMON),$(eval $(call def_libc_omf_dep,$(o),$(patsubst %.obj,%.o,$(o)))))
    180                                                        
    181                        
     180
     181
    182182# LIBC linking.
    183183$(LIBC.DLL): $(LIBC.OBJS) $(LIBC.LIBS) $(LIBC.DEF) $(LIBC.DEPS)
     
    188188                $(filter %.lib,$(LIBC.DEPS)) \
    189189                -L$.omf -lgcc -lgcc_eh $(LIBC.STUBARG)
    190 ifeq ($(MODE),opt)     
     190ifeq ($(MODE),opt)
    191191        cp $@ $(@:.dll=.dbg)
    192192        lxlite $(LXLITE.FLAGS) $(subst /,\\,$@)
     
    194194
    195195# LIBC .def file
    196 $(LIBC.DEF): $(LIBC.LIBS) src/lib/libc.def
     196$(LIBC.DEF): $(LIBC.LIBS) src/lib/libc.def version.smak
    197197        $(call RM,$@)
    198198        @$(call FECHO,$@,LIBRARY libc$(VH)$(VM)$(VL) INITINSTANCE TERMINSTANCE)
     
    239239                $(filter %.lib,$(LIBC.LOG.DEPS)) \
    240240                -L$.omf -lgcc -lgcc_eh $(LIBC.STUBARG)
    241         echo $@         
     241        echo $@
    242242
    243243# LIBC.PRF - Profiling version of libcXY.dll
     
    249249                $(filter %.lib,$(LIBC.PRF.DEPS)) \
    250250                -L$.omf-prof -L$.omf -lgcc -lgcc_eh $(LIBC.STUBARG)
    251         echo $@         
     251        echo $@
    252252
    253253# LIBC.PREF .def file
     
    260260        @$(call FECHO,$@,"")
    261261
    262        
     262
    263263# LIBC.ELH - Electric Heap version of libcXY.dll
    264264$(LIBC.ELH.DLL): $(LIBC.ELH.OBJS) $(LIBC.ELH.LIBS) $(LIBC.ELH.DEF) $(LIBC.ELH.DEPS)
     
    269269                $(filter %.lib,$(LIBC.ELH.DEPS)) \
    270270                -L$.omf -lgcc -lgcc_eh $(LIBC.STUBARG)
    271         echo $@         
     271        echo $@
    272272
    273273# LIBC.ELH .def file
     
    280280        @$(call FECHO,$@,"")
    281281        @$(call FECHO,$@,"IMPORTS");
    282         @$(call FECHO,$@,"  kHeapDbgException              = KLIBDBG.kHeapDbgException")       
     282        @$(call FECHO,$@,"  kHeapDbgException              = KLIBDBG.kHeapDbgException")
    283283        @$(call FECHO,$@,"  __std_calloc                   = KLIBDBG._gcc__std_calloc")
    284284        @$(call FECHO,$@,"  __um_default_alloc             = KLIBDBG._gcc__um_default_alloc")
     
    344344        @$(call FECHO,$@,"  __um_tiled_heap                = KLIBDBG._gcc__um_tiled_heap")
    345345
    346                                        
     346
    347347# Put libc into the big picture. (semihacks)
    348348DO.HELP.MODULES += $(call ECHO,    libc-dll - The dynamic C library (.dll))$(NL)
     
    380380        if test -f $@; then rm -f $@ || (unlock $(subst /,\\,$@) && rm -f $@); fi
    381381        cp $< $@
    382        
     382
    383383$(INS)lib/$(notdir $(LIBC.DLL:.dll=.map)): $(LIBC.DLL:.dll=.map)
    384384        $(call CP,$<,$@)
    385        
     385
    386386$(INS)lib/$(notdir $(LIBC.LOG.DLL)): $(LIBC.LOG.DLL)
    387387        $(call CP,$<,$@)
    388388$(INS)lib/$(notdir $(LIBC.LOG.DLL).map): $(LIBC.LOG.DLL).map
    389389        $(call CP,$<,$@)
    390                                                
     390
    391391$(INS)lib/$(notdir $(LIBC.PRF.DLL)): $(LIBC.PRF.DLL)
    392392        $(call CP,$<,$@)
     
    440440$.omf-prof/src/lib/startup/dllinit.obj: $.aout-prof/src/lib/startup/dllinit.o
    441441        $(DO.EMXOMF)
    442                        
     442
    443443# Forget temporary variables
    444444include comend.smak
     
    452452#
    453453# Forwarder DLLs for backward compatibility.
    454 #                       
     454#
    455455$.omf/fwdstub.obj: src/lib/fwdstub.asm
    456456        $(call DO.COMPILE.asm)
    457        
    458 ## libc06b4                                             
     457
     458## libc06b4
    459459#$.omf/libc06b4.dll: src/lib/libc06b4.def $.omf/fwdstub.obj $.omf/libc_dll.lib
    460460#       gcc -Zomf -o $@ -nostdlib -Zdll $^
     
    464464#libc-dll: $.omf/libc06b4.dll
    465465
    466 ## libc06b5                                             
     466## libc06b5
    467467#$.omf/libc06b5.dll: src/lib/libc06b5.def $.omf/fwdstub.obj $.omf/libc_dll.lib
    468468#       gcc -Zomf -o $@ -nostdlib -Zdll  $^
  • branches/libc-0.6/src/emx/src/lib/misc/atexit.c

    r2254 r2786  
    44 * LIBC atexit().
    55 *
    6  * Copyright (c) 2005 knut st. osmundsen <bird@anduin.net>
     6 * Copyright (c) 2005-2006 knut st. osmundsen <bird@anduin.net>
    77 *
    88 *
     
    3030*******************************************************************************/
    3131#include "libc-alias.h"
     32#ifdef __OS2__
     33# define INCL_DOSMODULEMGR
     34# define INCL_ERRORS
     35# define INCL_FSMACROS
     36# include <os2emx.h>
     37#endif
    3238#include <stdlib.h>
    3339#include <InnoTekLIBC/atexit.h>
    34 #include <386/builtin.h>
     40#include <sys/builtin.h>
    3541#include <emx/umalloc.h>
    3642#define __LIBC_LOG_GROUP __LIBC_LOG_GRP_INITTERM
     
    4147{
    4248    LIBCLOG_ENTER("pfnCallback=%p\n", (void *)pfnCallback);
    43     __LIBC_PATEXIT pCur = __libc_atexit_new();
     49    __LIBC_PATEXIT pCur = __libc_atexit_new((void *)pfnCallback);
    4450    if (pCur)
    4551    {
     
    5763 * @returns Pointer to new entry.
    5864 * @returns NULL on failure.
     65 *
     66 * @param   pvCallback      The callback address.
     67 *                          This used to initialize the __LIBC_AT_EXIT::hmod field.
    5968 */
    60 __LIBC_PATEXIT __libc_atexit_new(void)
     69__LIBC_PATEXIT __libc_atexit_new(void *pvCallback)
    6170{
     71    /*
     72     * Try find the module this callback belongs to.
     73     */
     74    uintptr_t   hmod = 0;
     75    /** @todo generalize DosQueryModFromEIP and let the (loader) backend do that kind of job. */
     76#ifdef __OS2__
     77    HMODULE     hmodOS2;
     78    ULONG       iObj, offObj;
     79    FS_VAR_SAVE_LOAD();
     80    APIRET rc = DosQueryModFromEIP(&hmodOS2, &iObj, 0, NULL, &offObj, (uintptr_t)pvCallback);
     81    if (rc == NO_ERROR)
     82        hmod = hmodOS2;
     83    FS_RESTORE();
     84#else
     85    /** @todo port to NT and other target platforms. */
     86#endif
     87
    6288    /*
    6389     * Search existing chunks.
     
    7298            if (__atomic_cmpxchg32(&pChunk->c, i + 1, i))
    7399            {
     100                pChunk->a[i].hmod = hmod;
    74101                pChunk->a[i].enmType = __LIBC_ATEXITTYPE_TRANS;
    75102                return &pChunk->a[i];
     
    84111    if (!pChunk)
    85112        return NULL;
     113    /** @todo There is a chance that the exit list order could be screwed up here if two threads get here at the same time. (bird, 2006-08-21) */
    86114    pChunk->c = 1;
     115    pChunk->a[0].hmod = hmod;
    87116    pChunk->a[0].enmType = __LIBC_ATEXITTYPE_TRANS;
    88117    do
     
    94123}
    95124
     125
     126/**
     127 * Invalidate all atexit and on_exit callback for a
     128 * module which is being unloaded.
     129 *
     130 * @param   hmod        The module handle.
     131 */
     132void __libc_atexit_unload(uintptr_t hmod)
     133{
     134    /*
     135     * Search existing chunks.
     136     * (This is made simple by us not freeing anything.)
     137     */
     138    __LIBC_PATEXITCHUNK pChunk;
     139    for (pChunk = __libc_gAtExitHead; pChunk; pChunk = pChunk->pNext)
     140    {
     141        uint32_t i = pChunk->c;
     142        while (i-- > 0)
     143        {
     144            if (    pChunk->a[i].hmod == hmod
     145                &&  pChunk->a[i].enmType > __LIBC_ATEXITTYPE_FREE
     146                &&  pChunk->a[i].enmType < __LIBC_ATEXITTYPE_TRANS)
     147                pChunk->a[i].enmType = __LIBC_ATEXITTYPE_UNLOADED;
     148        }
     149    }
     150}
     151
  • branches/libc-0.6/src/emx/src/lib/misc/on_exit.c

    r2254 r2786  
    44 * LIBC on_exit().
    55 *
    6  * Copyright (c) 2005 knut st. osmundsen <bird@anduin.net>
     6 * Copyright (c) 2005-2006 knut st. osmundsen <bird@anduin.net>
    77 *
    88 *
     
    3939{
    4040    LIBCLOG_ENTER("pfnCallback=%p pvUser=%p\n", (void *)pfnCallback, pvUser);
    41     __LIBC_PATEXIT pCur = __libc_atexit_new();
     41    __LIBC_PATEXIT pCur = __libc_atexit_new((void *)pfnCallback);
    4242    if (pCur)
    4343    {
  • branches/libc-0.6/src/emx/src/lib/startup/386/dll0.s

    r2289 r2786  
    5050#endif
    5151
     52#if defined(NOFORK)
     53#define FLAG_NOFORK     4
     54#else
     55#define FLAG_NOFORK     0
     56#endif
     57
     58    /*
     59     * The DLL Entry Point.
     60     */
    5261__text:
    5362    cmpl    $0, 8(%esp)
    54     jz      do_common_init
    55     jmp     do_initterm
     63    je      do_init
     64    cmpl    $1, 8(%esp)
     65    je      do_term
     66    jmp     _DLL_InitTerm
     67
    5668
    5769    /*
    58      * Nonstandard: we're doing some early initializations.
     70     * DLL Initialization.
    5971     */
    60 do_common_init:
     72do_init:
    6173#if !defined(NOFORK) && !defined(NOUNIX)
    6274    pushl   $0
     
    6577    addl    $8, %esp
    6678    cmpl    $0, %eax
    67     je      do_init
    68     jg      do_fork
    69 
    70     /* return failure (eax < 0). */
     79    je      do_init_not_forking
     80    jg      do_return_success   /* we're forking; no init. */
     81    /* else: eax < 0 - failure. */
     82do_return_failure:
    7183    xorl    %eax, %eax
    7284    ret
    73 
    74     /* return success - we're forking; no init. */
    75 do_fork:
     85do_return_success:
    7686    xorl    %eax, %eax
    7787    inc     %al
     
    7989
    8090    /* normal dll init. */
    81 do_init:
     91do_init_not_forking:
    8292#endif
     93    /* call __init_dll() */
    8394    pushl   4(%esp)
    84     pushl   $(FLAG_HIGHMEM + FLAG_NOUNIX)
     95    pushl   $(FLAG_HIGHMEM + FLAG_NOUNIX + FLAG_NOFORK)
    8596    call    ___init_dll
    8697    add     $8, %esp
    8798    orl     %eax, %eax
    88     jz      do_initterm
     99    jnz     do_return_failure
     100
     101    /* call _DLL_InitTerm */
     102    cld
     103    pushl   8(%esp)
     104    pushl   8(%esp)
     105    call    _DLL_InitTerm
     106    add     $8, %esp
     107    orl     %eax, %eax
     108    jnz     do_return_success
     109
     110    /* _DLL_InitTerm failed, undo the module registration. */
     111#if !defined(NOFORK) && !defined(NOUNIX)
     112    pushl   $ForkModule
     113    call    ___libc_ForkRegisterModule
     114    addl    $4, %esp
     115#endif
     116    jmp     do_return_failure;
     117
     118
    89119    /*
    90      * __init_dll() failed - fail the dll loading.
     120     * DLL Termination.
    91121     */
    92     xorl    %eax, %eax
     122do_term:
     123    /* do init term first */
     124    cld
     125    pushl   8(%esp)
     126    pushl   8(%esp)
     127    call    _DLL_InitTerm
     128    add     $8, %esp
     129    orl     %eax, %eax
     130    jnz     do_term_dll
    93131    ret
    94132
    95     /*
    96      * Standard initialization.
    97      */
    98 do_initterm:
    99     cld
    100     jmp     _DLL_InitTerm
     133do_term_dll:
     134    /* call __libc_Back_termDll() */
     135    pushl   4(%esp)
     136    pushl   $(FLAG_HIGHMEM + FLAG_NOUNIX + FLAG_NOFORK)
     137    call    ___libc_Back_termDll
     138    add     $8, %esp
     139
     140    /* call __libc_ForkDeregisterModule */
     141#if !defined(NOFORK) && !defined(NOUNIX)
     142    pushl   $ForkModule
     143    call    ___libc_ForkDeregisterModule
     144    addl    $4, %esp
     145#endif
     146    jmp     do_return_success
    101147
    102148
  • branches/libc-0.6/src/emx/src/lib/sys/b_processWait.c

    r2254 r2786  
    124124/** Number of known child processes. */
    125125static volatile unsigned    gcChildren;
    126 /** Total number of born child processes. */
     126/** Total number of born child processes. (For statistical purposes only.) */
    127127static volatile unsigned    gcBirths;
    128128/** Total number of died child processes. */
     
    171171         * Create the fmutex.
    172172         */
    173         _fmutex_checked_create(&gmtxWait, 0);
     173        _fmutex_checked_create2(&gmtxWait, _FMC_MUST_COMPLETE, "b_processWait.c: gmtxWait");
    174174        int rc = DosCreateEventSemEx(NULL, (PHEV)&ghevWait, 0, TRUE);
    175175        if (rc)
     
    194194void __libc_back_processWaitNotifyTerm(void)
    195195{
     196    __atomic_xchg(&gfTerminate, 1);
     197
     198    /* kill the thread - this is probably a waste of time in the exitlist handler... */
    196199    if (gtidThread)
    197200    {
    198         /* kill the thread - this is probably a waste of time in the exitlist handler... */
    199         __atomic_xchg(&gfTerminate, 1);
    200201        DosKillThread(gtidThread);
    201202        gtidThread = 0;
     
    223224     * Kill all known decendants.
    224225     */
     226    /** @todo We should really reparent them to the init process, but only the session manager can do that. */
    225227    PWAITCHILD pChild = gpChildrenHead;
    226228    if (pChild)
    227229    {
     230        gpChildrenHead = NULL;
     231        gcChildren = 0;
     232
    228233        /*
    229234         * Kill the process tree so we don't end up having childrens
     
    268273    int rc = _fmutex_request(&gmtxWait, fNoInterrupts ? _FMR_IGNINT : 0);
    269274    if (!rc)
    270     {
    271         ULONG cIgnore = 0;
    272         DosEnterMustComplete(&cIgnore);
    273275        return 0;
    274     }
    275276    LIBC_ASSERTM_FAILED("_fmutex_request -> %d\n", rc);
    276277    return -__libc_native2errno(rc);
     
    284285    int rc = _fmutex_release(&gmtxWait);
    285286    LIBC_ASSERTM(!rc, "_fmutex_release -> %d\n", rc);
    286     ULONG cIgnore = 0;
    287     DosExitMustComplete(&cIgnore);
    288287    rc = rc;
    289288}
     
    652651    if (!gtidThread)
    653652    {
     653        gfTerminate = 0;
     654
    654655        /*
    655656         * Create the internal thread for dealing with waiting.
  • branches/libc-0.6/src/emx/src/lib/sys/libcfork.c

    r2289 r2786  
    314314
    315315    /*
    316      * Install exceptionhandler.
     316     * Install an exceptionhandler.
    317317     */
    318318    DosGetInfoBlocks(&pTib, &pPib);
     
    346346
    347347    /*
    348      * Check if dynamically loaded or not.
    349      */
    350     /** @todo! */
    351 
    352     /*
    353348     * Register the module.
    354      */
     349     * (We're hoping for OS/2 to indirectly serialize this... not properly verified yet.)
     350     */
     351    if (pModule->fFlags & __LIBC_FORKMODULE_FLAGS_DEREGISTERED)
     352        LIBCLOG_MSG("__LIBC_FORKMODULE_FLAGS_DEREGISTERED!\n");
     353    pModule->fFlags &= ~__LIBC_FORKMODULE_FLAGS_DEREGISTERED;
    355354    pModule->pNext = NULL;
    356355    if (pProcess->pvModuleHead)
     
    433432    pTib->tib_pexchain = XcptRegRec.prev_structure;
    434433    LIBCLOG_RETURN_INT(1);
     434}
     435
     436
     437/**
     438 * Deregister a forkable module. Called by dll0.
     439 *
     440 * The call links pModule out of the list of forkable modules
     441 * which is maintained in the process block.
     442 *
     443 * @param   pModule     Pointer to the fork module structure for the
     444 *                      module which is to registered.
     445 */
     446void __libc_ForkDeregisterModule(__LIBC_PFORKMODULE pModule)
     447{
     448    LIBCLOG_ENTER("pModule=%p:{.uVersion=%#x, .pfnAtFork=%p, .papParent1=%p, .papChild1=%p, .pvDataSegBase=%p, .pvDataSegEnd=%p, .fFlags=%#x, .pNext=%p}\n",
     449                  (void *)pModule, pModule->uVersion, (void *)pModule->pfnAtFork, (void *)pModule->papParent1, (void *)pModule->papChild1,
     450                  (void *)pModule->pvDataSegBase, (void *)pModule->pvDataSegEnd, pModule->fFlags, (void *)pModule->pNext);
     451
     452    /*
     453     * Don't deregister modules which has already been deregistered.
     454     * Don't deregister if we're in shutting down the process (waste of time and
     455     * SPM might already be shut down).
     456     */
     457    if (pModule->fFlags & __LIBC_FORKMODULE_FLAGS_DEREGISTERED)
     458        LIBCLOG_RETURN_MSG_VOID( "ret void (__LIBC_FORKMODULE_FLAGS_DEREGISTERD)\n");
     459    if (!__libc_GpFIBLIS)
     460        LIBCLOG_RETURN_MSG_VOID( "ret void (__libc_GpFIBLIS)\n");
     461    if (fibIsInExit())
     462        LIBCLOG_RETURN_MSG_VOID( "ret void (fibIsInExit)\n");
     463
     464    /*
     465     * Find the SPM process.
     466     */
     467    __LIBC_PSPMPROCESS pProcess = __libc_spmSelf();
     468    if (!pProcess)
     469    {
     470        LIBC_ASSERTM_FAILED("can't find the process! weird!\n");
     471        LIBCLOG_RETURN_VOID();
     472    }
     473
     474    /*
     475     * Deregister the module.
     476     * (We're hoping for OS/2 to indirectly serialize this... not properly verified yet.)
     477     */
     478    if ((__LIBC_PFORKMODULE)pProcess->pvModuleHead == pModule)
     479    {
     480        pProcess->pvModuleHead = pModule->pNext;
     481        if (!pModule->pNext)
     482            pProcess->ppvModuleTail = &pProcess->pvModuleHead;
     483    }
     484    else
     485    {
     486        __LIBC_PFORKMODULE pPrev = (__LIBC_PFORKMODULE)pProcess->pvModuleHead;
     487        while (pPrev && pPrev->pNext != pModule)
     488            pPrev = pPrev->pNext;
     489        if (!pPrev)
     490        {
     491            LIBC_ASSERTM_FAILED("can't find the module! weird!\n");
     492            LIBCLOG_RETURN_VOID();
     493        }
     494
     495        pPrev->pNext = pModule->pNext;
     496        if (!pModule->pNext)
     497            pProcess->ppvModuleTail = (void **)&pPrev->pNext;
     498    }
     499
     500    pModule->pNext = NULL;
     501    pModule->fFlags |= __LIBC_FORKMODULE_FLAGS_DEREGISTERED;
     502
     503    LIBCLOG_RETURN_VOID();
    435504}
    436505
     
    12801349    /*
    12811350     * Open and process the buffer on first call.
     1351     *
     1352     * Because of DosLoadModuleEx processing, we can end up here in while
     1353     * processing the initial fork buffer. This means that if any of those
     1354     * DLLS tries to talk to the parent at __LIBC_FORK_EXEC_CHILD time the
     1355     * fork() will fail. Fortunately, this is very unlikely. (Otherwise, we
     1356     * should've delayed those pfnAtFork() calls.)
    12821357     */
    12831358    if (pForkHandle->enmStage == __LIBC_FORK_STAGE_EXEC)
     
    12891364            LIBCLOG_RETURN_INT(rc);
    12901365        }
     1366        pForkHandle->enmStage = __LIBC_FORK_STAGE_INIT_CHILD;
    12911367        rc = forkBthBufferProcess(pForkHandle, __LIBC_FORK_CTX_CHILD, NULL);
    12921368        if (rc < 0)
     
    12951371            LIBCLOG_RETURN_INT(rc);
    12961372        }
    1297 
    1298         /* next stage */
    1299         pForkHandle->enmStage = __LIBC_FORK_STAGE_INIT_CHILD;
    13001373    }
    13011374
Note: See TracChangeset for help on using the changeset viewer.