Changeset 1905


Ignore:
Timestamp:
Apr 24, 2005, 2:11:40 PM (20 years ago)
Author:
bird
Message:

Rewrote atexit() fixing recursive exit() calling. Added on_exit().

Location:
trunk/src/emx
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/include/emx/startup.h

    • Property cvs2svn:cvs-rev changed from 1.5 to 1.6
    r1904 r1905  
    5050#define _CRT_EXIT1(fun) __asm__ (".stabs \"___crtexit1__\", 23, 0, 0, _" #fun);
    5151
    52 extern void (*_atexit_v[64])(void);
    53 extern int _atexit_n;
    54 
    5552extern char ** _org_environ;
    5653
  • trunk/src/emx/include/stdlib.h

    • Property cvs2svn:cvs-rev changed from 1.30 to 1.31
    r1904 r1905  
    299299void    *valloc(size_t);
    300300#endif
     301int      on_exit(void (*)(int, void *), void *);
    301302/* bird: LIBC stuff - end  */
    302303
  • trunk/src/emx/src/lib/libc.def

    • Property cvs2svn:cvs-rev changed from 1.100 to 1.101
    r1904 r1905  
    3131    "___stdinp" @9
    3232    "___stdoutp" @10
    33     "__atexit_n" @11
    34     "__atexit_v" @12
     33    "___hexdig_D2A" @11
     34    "__nl_current_default_domain" @12
    3535    "__emx_optarg" @13
    3636    "__emx_opterr" @14
     
    7474    "___gettext_germanic_plural" @52
    7575    "__nl_msg_cat_cntr" @53
     76    "__nl_domain_bindings" @54
    7677
    7778
     
    14291430    "___g_xfmt" @1438
    14301431    "___hdtoa" @1439
    1431     "___hexdig_D2A" @1440
     1432    "__std_on_exit" @1440               ; april coding
    14321433    "___hexdig_init_D2A" @1441
    14331434    "___hexnan_D2A" @1442
     
    14891490    "__std_gethrtime" @1497
    14901491    ; more intl (configure tests checks for internal variables, arg!)
    1491     "__nl_current_default_domain" @1498
    1492     "__nl_default_default_domain" @1499
    1493     "__nl_default_dirname" @1500
    1494     "__nl_domain_bindings" @1501
    1495     "__nl_expand_alias" @1502
    1496     "__nl_explode_name" @1503
    1497     "__nl_normalize_codeset" @1504
     1492    "__nl_default_default_domain" @1498
     1493    "__nl_default_dirname" @1499
     1494    "__nl_expand_alias" @1500
     1495    "__nl_explode_name" @1501
     1496    "__nl_normalize_codeset" @1502
  • trunk/src/emx/src/lib/libc06b4.def

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r1904 r1905  
    3232    "___stdinp" @9
    3333    "___stdoutp" @10
    34     "__atexit_n" @11
    35     "__atexit_v" @12
     34    "__atexit_n" = __osmajor @11        ; removed in libc06b5, never used outside exit() and atexit().
     35    "__atexit_v" = __osmajor @12        ; removed in libc06b5, never used outside exit() and atexit().
    3636    "__emx_optarg" @13
    3737    "__emx_opterr" @14
  • trunk/src/emx/src/lib/misc/atexit.c

    • Property cvs2svn:cvs-rev changed from 1.3 to 1.4
    r1904 r1905  
    1 /* atexit.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * LIBC atexit().
     5 *
     6 * Copyright (c) 2005 knut st. osmundsen <bird@anduin.net>
     7 *
     8 *
     9 * This file is part of InnoTek LIBC.
     10 *
     11 * InnoTek LIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * InnoTek LIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with InnoTek LIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
    226
     27
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
    331#include "libc-alias.h"
    432#include <stdlib.h>
    5 #include <emx/startup.h>
     33#include <InnoTekLIBC/atexit.h>
     34#include <386/builtin.h>
     35#include <emx/umalloc.h>
    636
    7 int _STD(atexit) (void (*func)(void))
     37
     38int _STD(atexit)(void (*pfnCallback)(void))
    839{
    9   if (_atexit_n >= sizeof (_atexit_v) / sizeof (_atexit_v[0]))
     40    __LIBC_PATEXIT pCur = __libc_atexit_new();
     41    if (pCur)
     42    {
     43        pCur->u.AtExit.pfnCallback = pfnCallback;
     44        pCur->enmType = __LIBC_ATEXITTYPE_ATEXIT;
     45        return 0;
     46    }
    1047    return -1;
    11   _atexit_v[_atexit_n++] = func;
    12   return 0;
    1348}
     49
     50
     51/**
     52 * Allocate a new atexit entry.
     53 *
     54 * @returns Pointer to new entry.
     55 * @returns NULL on failure.
     56 */
     57__LIBC_PATEXIT __libc_atexit_new(void)
     58{
     59    /*
     60     * Search existing chunks.
     61     * (This is made simple by us not freeing anything.)
     62     */
     63    __LIBC_PATEXITCHUNK pChunk;
     64    for (pChunk = __libc_gAtExitHead; pChunk; pChunk = pChunk->pNext)
     65    {
     66        uint32_t i;
     67        while ((i = pChunk->c) < sizeof(pChunk->a) / sizeof(pChunk->a[0]))
     68        {
     69            if (__atomic_cmpxchg32(&pChunk->c, i + 1, i))
     70            {
     71                pChunk->a[i].enmType = __LIBC_ATEXITTYPE_TRANS;
     72                return &pChunk->a[i];
     73            }
     74        }
     75    }
     76
     77    /*
     78     * Add a new chunk.
     79     */
     80    pChunk = _hcalloc(1, sizeof(*pChunk));
     81    if (!pChunk)
     82        return NULL;
     83    pChunk->c = 1;
     84    pChunk->a[0].enmType = __LIBC_ATEXITTYPE_TRANS;
     85    do
     86    {
     87        pChunk->pNext = __libc_gAtExitHead;
     88    } while (__atomic_cmpxchg32((uint32_t volatile *)(void *)&__libc_gAtExitHead, (uint32_t)pChunk, (uint32_t)pChunk->pNext)); /** @todo atomic cmpxchg for ptrs! */
     89
     90    return &pChunk->a[0];
     91}
     92
  • trunk/src/emx/src/lib/startup/exit.c

    • Property cvs2svn:cvs-rev changed from 1.6 to 1.7
    r1904 r1905  
    1 /* exit.c (emx+gcc) -- Copyright (c) 1990-1998 by Eberhard Mattes */
     1/* $Id: $ */
     2/** @file
     3 *
     4 * LIBC exit().
     5 *
     6 * Copyright (c) 2005 knut st. osmundsen <bird@anduin.net>
     7 *
     8 *
     9 * This file is part of InnoTek LIBC.
     10 *
     11 * InnoTek LIBC is free software; you can redistribute it and/or modify
     12 * it under the terms of the GNU Lesser General Public License as published
     13 * by the Free Software Foundation; either version 2 of the License, or
     14 * (at your option) any later version.
     15 *
     16 * InnoTek LIBC is distributed in the hope that it will be useful,
     17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     19 * GNU Lesser General Public License for more details.
     20 *
     21 * You should have received a copy of the GNU Lesser General Public License
     22 * along with InnoTek LIBC; if not, write to the Free Software
     23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     24 *
     25 */
    226
    327
     28/*******************************************************************************
     29*   Header Files                                                               *
     30*******************************************************************************/
    431#include "libc-alias.h"
    532#include <stdlib.h>
    633#include <emx/startup.h>
     34#include <InnotekLIBC/atexit.h>
    735#define __LIBC_LOG_GROUP  __LIBC_LOG_GRP_INITTERM
    836#include <InnotekLIBC/logstrict.h>
    937
    10 void (*_atexit_v[64])(void);
    11 int _atexit_n = 0;
    1238
    13 void _STD(exit) (int ret)
     39/*******************************************************************************
     40*   Global Variables                                                           *
     41*******************************************************************************/
     42/** Static exit list entry. */
     43static __LIBC_ATEXITCHUNK gAtExitChunk;
     44/** Pointer to the head of the exit list chain - LIFO. */
     45__LIBC_PATEXITCHUNK __libc_gAtExitHead = &gAtExitChunk;
     46
     47
     48void _STD(exit)(int ret)
    1449{
    15   LIBCLOG_ENTER("ret=%d\n", ret);
    16   int i;
     50    LIBCLOG_ENTER("ret=%d\n", ret);
    1751
    18   for (i = _atexit_n-1; i >= 0; --i)
     52    /*
     53     * Call registered at exit callbacks.
     54     *
     55     * These are called in reverse registration order and we're
     56     * removing them from the list as we move along to prevent endless recursions.
     57     * (It is allowed to call exit() from a handler, but we must not call that handler again!)
     58     */
     59    for (__LIBC_PATEXITCHUNK pChunk = __libc_gAtExitHead; pChunk; pChunk = pChunk->pNext)
    1960    {
    20       LIBCLOG_MSG("calling _atexit[%d] %p\n", i, _atexit_v[i]);
    21       _atexit_v[i]();
     61        while (pChunk->c > 0)
     62        {
     63            __LIBC_PATEXIT pCur = &pChunk->a[--pChunk->c];
     64            switch (pCur->enmType)
     65            {
     66                case __LIBC_ATEXITTYPE_ATEXIT:
     67                    LIBCLOG_MSG("calling atexit: %p()\n", (void *)pCur->u.AtExit.pfnCallback);
     68                    pCur->u.AtExit.pfnCallback();
     69                    break;
     70
     71                case __LIBC_ATEXITTYPE_ONEXIT:
     72                    LIBCLOG_MSG("calling onexit: %p(%d,%p)\n", (void *)pCur->u.OnExit.pfnCallback, ret, pCur->u.OnExit.pvUser);
     73                    pCur->u.OnExit.pfnCallback(ret, pCur->u.OnExit.pvUser);
     74                    break;
     75
     76                default:
     77                    break;
     78            }
     79        }
    2280    }
    23   _CRT_term ();
    24   LIBCLOG_MSG("calling _exit\n");
    25   _exit (ret);
     81
     82    /*
     83     * Terminate the CRT and do the real exit.
     84     */
     85    _CRT_term ();
     86    LIBCLOG_MSG("calling _exit(%d)\n", ret);
     87    _exit (ret);
    2688}
Note: See TracChangeset for help on using the changeset viewer.