summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdio/findfp.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2012-04-24 17:51:36 +0000
committerkib <kib@FreeBSD.org>2012-04-24 17:51:36 +0000
commitfa609f4d93f798de2153e04476f9b825aa469491 (patch)
tree4dea6a5419824f6e6fbe0ef07f6465bd4906fa87 /lib/libc/stdio/findfp.c
parentf0cabca1b818ea8a0563c3640eddf186f272a402 (diff)
downloadFreeBSD-src-fa609f4d93f798de2153e04476f9b825aa469491.zip
FreeBSD-src-fa609f4d93f798de2153e04476f9b825aa469491.tar.gz
Take the spinlock around clearing of the fp->_flags in fclose(3), which
indicates the avaliability of FILE, to prevent possible reordering of the writes as seen by other CPUs. Reported by: Fengwei yin <yfw.bsd gmail com> Reviewed by: jhb MFC after: 1 week
Diffstat (limited to 'lib/libc/stdio/findfp.c')
-rw-r--r--lib/libc/stdio/findfp.c16
1 files changed, 7 insertions, 9 deletions
diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c
index 89c0536..6d0b673 100644
--- a/lib/libc/stdio/findfp.c
+++ b/lib/libc/stdio/findfp.c
@@ -82,9 +82,7 @@ static struct glue *lastglue = &uglue;
static struct glue * moreglue(int);
-static spinlock_t thread_lock = _SPINLOCK_INITIALIZER;
-#define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&thread_lock)
-#define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&thread_lock)
+spinlock_t __stdio_thread_lock = _SPINLOCK_INITIALIZER;
#if NOT_YET
#define SET_GLUE_PTR(ptr, val) atomic_set_rel_ptr(&(ptr), (uintptr_t)(val))
@@ -127,22 +125,22 @@ __sfp()
/*
* The list must be locked because a FILE may be updated.
*/
- THREAD_LOCK();
+ STDIO_THREAD_LOCK();
for (g = &__sglue; g != NULL; g = g->next) {
for (fp = g->iobs, n = g->niobs; --n >= 0; fp++)
if (fp->_flags == 0)
goto found;
}
- THREAD_UNLOCK(); /* don't hold lock while malloc()ing. */
+ STDIO_THREAD_UNLOCK(); /* don't hold lock while malloc()ing. */
if ((g = moreglue(NDYNAMIC)) == NULL)
return (NULL);
- THREAD_LOCK(); /* reacquire the lock */
+ STDIO_THREAD_LOCK(); /* reacquire the lock */
SET_GLUE_PTR(lastglue->next, g); /* atomically append glue to list */
lastglue = g; /* not atomic; only accessed when locked */
fp = g->iobs;
found:
fp->_flags = 1; /* reserve this slot; caller sets real flags */
- THREAD_UNLOCK();
+ STDIO_THREAD_UNLOCK();
fp->_p = NULL; /* no current pointer */
fp->_w = 0; /* nothing to read or write */
fp->_r = 0;
@@ -183,10 +181,10 @@ f_prealloc(void)
for (g = &__sglue; (n -= g->niobs) > 0 && g->next; g = g->next)
/* void */;
if ((n > 0) && ((g = moreglue(n)) != NULL)) {
- THREAD_LOCK();
+ STDIO_THREAD_LOCK();
SET_GLUE_PTR(lastglue->next, g);
lastglue = g;
- THREAD_UNLOCK();
+ STDIO_THREAD_UNLOCK();
}
}
OpenPOWER on IntegriCloud