Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2004-01-28 04:00:37 +0300
committerJeff Johnston <jjohnstn@redhat.com>2004-01-28 04:00:37 +0300
commitd5b6c234830aea678be63b262b2233f945209490 (patch)
tree3dd85c17f1095a1f41850d755fe94e49457159a6 /newlib/libc/stdlib
parent01e0a777491a7d5bf48ea704df7bc0965d4e8883 (diff)
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')
-rw-r--r--newlib/libc/stdlib/atexit.c24
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;
}