diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 4a52dee22..5757512f2 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,8 @@ +2004-01-27 Jeff Johnston + + * libc/stdlib/atexit.c: Protect global atexit list with a + lock when newlib is multithreaded. + 2004-01-27 Artem B. Bityuckiy * configure.in: Add support to generate iconv converter flags diff --git a/newlib/libc/stdlib/atexit.c b/newlib/libc/stdlib/atexit.c index 97424da81..3a9cdc6a3 100644 --- a/newlib/libc/stdlib/atexit.c +++ b/newlib/libc/stdlib/atexit.c @@ -53,6 +53,7 @@ Supporting OS subroutines required: <>, <>, <>, #include #include #include +#include /* * Register a function to be performed at exit. @@ -65,6 +66,12 @@ _DEFUN (atexit, { register struct _atexit *p; +#ifndef __SINGLE_THREAD__ + __LOCK_INIT(static, lock); + + __lock_acquire(lock); +#endif + /* _REENT_SMALL atexit() doesn't allow more than the required 32 entries. */ #ifndef _REENT_SMALL if ((p = _GLOBAL_REENT->_atexit) == NULL) @@ -72,7 +79,12 @@ _DEFUN (atexit, if (p->_ind >= _ATEXIT_SIZE) { if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL) - return -1; + { +#ifndef __SINGLE_THREAD__ + __lock_release(lock); +#endif + return -1; + } p->_ind = 0; p->_on_exit_args._fntypes = 0; p->_next = _GLOBAL_REENT->_atexit; @@ -81,8 +93,16 @@ _DEFUN (atexit, #else p = &_GLOBAL_REENT->_atexit; if (p->_ind >= _ATEXIT_SIZE) - return -1; + { +#ifndef __SINGLE_THREAD__ + __lock_release(lock); +#endif + return -1; + } #endif p->_fns[p->_ind++] = fn; +#ifndef __SINGLE_THREAD__ + __lock_release(lock); +#endif return 0; }