diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2004-01-28 01:00:37 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2004-01-28 01:00:37 +0000 |
commit | d5b6c234830aea678be63b262b2233f945209490 (patch) | |
tree | 3dd85c17f1095a1f41850d755fe94e49457159a6 /newlib/libc/stdlib/atexit.c | |
parent | 01e0a777491a7d5bf48ea704df7bc0965d4e8883 (diff) | |
download | cygnal-d5b6c234830aea678be63b262b2233f945209490.tar.gz cygnal-d5b6c234830aea678be63b262b2233f945209490.tar.bz2 cygnal-d5b6c234830aea678be63b262b2233f945209490.zip |
2004-01-27 Jeff Johnston <jjohnstn@redhat.com>
* libc/stdlib/atexit.c: Protect global atexit list with a
lock when newlib is multithreaded.
Diffstat (limited to 'newlib/libc/stdlib/atexit.c')
-rw-r--r-- | newlib/libc/stdlib/atexit.c | 24 |
1 files changed, 22 insertions, 2 deletions
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: <<close>>, <<fstat>>, <<isatty>>, #include <stddef.h> #include <stdlib.h> #include <reent.h> +#include <sys/lock.h> /* * 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; } |