summaryrefslogtreecommitdiff
path: root/lib/libpthread
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2009-10-21 16:05:03 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2009-10-21 16:05:03 +0000
commit92e808ed2dc8ad17d5f1f10661ea55c6ed182b9c (patch)
treeb34c5079455c41818b17ed4a6363cb0c856e45e4 /lib/libpthread
parent41f63f502ca80eb7786b814aad26bbb067f253ce (diff)
Change libpthread's f*lockfile() routines to stop acting as no-ops
for FILEs that don't have real file-descriptors: the fake FILEs used internally by snprintf/asprintf/vfprintf and friends now avoid unnecessary locking by calling the internal __vfprintf() routine directly and we do want to do locking on FILEs created with funopen(). ok kurt@
Diffstat (limited to 'lib/libpthread')
-rw-r--r--lib/libpthread/uthread/uthread_file.c253
1 files changed, 122 insertions, 131 deletions
diff --git a/lib/libpthread/uthread/uthread_file.c b/lib/libpthread/uthread/uthread_file.c
index b7a0552ccff..83bbefadd63 100644
--- a/lib/libpthread/uthread/uthread_file.c
+++ b/lib/libpthread/uthread/uthread_file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_file.c,v 1.14 2008/03/23 00:51:57 deraadt Exp $ */
+/* $OpenBSD: uthread_file.c,v 1.15 2009/10/21 16:05:02 guenther Exp $ */
/*
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -41,6 +41,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <sys/queue.h>
#ifdef _THREAD_SAFE
#include <pthread.h>
@@ -173,68 +174,65 @@ do_lock(int idx, FILE *fp)
return(p);
}
+
void
flockfile(FILE * fp)
{
int idx = file_idx(fp);
struct file_lock *p;
- /* Check if this is a real file: */
- if (fileno(fp) >= 0) {
- /* Lock the hash table: */
- _SPINLOCK(&hash_lock);
+ /* Lock the hash table: */
+ _SPINLOCK(&hash_lock);
- /* Check if the static array has not been initialised: */
- if (!init_done) {
- /* Initialise the global array: */
- memset(flh,0,sizeof(flh));
+ /* Check if the static array has not been initialised: */
+ if (!init_done) {
+ /* Initialise the global array: */
+ memset(flh,0,sizeof(flh));
- /* Flag the initialisation as complete: */
- init_done = 1;
- }
+ /* Flag the initialisation as complete: */
+ init_done = 1;
+ }
- /* Get a pointer to any existing lock for the file: */
- if ((p = find_lock(idx, fp)) == NULL) {
- /*
- * The file is not locked, so this thread can
- * grab the lock:
- */
- p = do_lock(idx, fp);
+ /* Get a pointer to any existing lock for the file: */
+ if ((p = find_lock(idx, fp)) == NULL) {
+ /*
+ * The file is not locked, so this thread can
+ * grab the lock:
+ */
+ p = do_lock(idx, fp);
- /* Unlock the hash table: */
- _SPINUNLOCK(&hash_lock);
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
+ /*
+ * The file is already locked, so check if the
+ * running thread is the owner:
+ */
+ } else if (p->owner == _thread_run) {
/*
- * The file is already locked, so check if the
- * running thread is the owner:
+ * The running thread is already the
+ * owner, so increment the count of
+ * the number of times it has locked
+ * the file:
*/
- } else if (p->owner == _thread_run) {
- /*
- * The running thread is already the
- * owner, so increment the count of
- * the number of times it has locked
- * the file:
- */
- p->count++;
+ p->count++;
- /* Unlock the hash table: */
- _SPINUNLOCK(&hash_lock);
- } else {
- /*
- * The file is locked for another thread.
- * Append this thread to the queue of
- * threads waiting on the lock.
- */
- TAILQ_INSERT_TAIL(&p->l_head,_thread_run,qe);
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
+ } else {
+ /*
+ * The file is locked for another thread.
+ * Append this thread to the queue of
+ * threads waiting on the lock.
+ */
+ TAILQ_INSERT_TAIL(&p->l_head,_thread_run,qe);
- /* Unlock the hash table: */
- _SPINUNLOCK(&hash_lock);
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
- /* Wait on the FILE lock: */
- _thread_kern_sched_state(PS_FILE_WAIT, "", 0);
- }
+ /* Wait on the FILE lock: */
+ _thread_kern_sched_state(PS_FILE_WAIT, "", 0);
}
- return;
}
int
@@ -244,48 +242,45 @@ ftrylockfile(FILE * fp)
int idx = file_idx(fp);
struct file_lock *p;
- /* Check if this is a real file: */
- if (fileno(fp) >= 0) {
- /* Lock the hash table: */
- _SPINLOCK(&hash_lock);
+ /* Lock the hash table: */
+ _SPINLOCK(&hash_lock);
- /* Get a pointer to any existing lock for the file: */
- if ((p = find_lock(idx, fp)) == NULL) {
- /*
- * The file is not locked, so this thread can
- * grab the lock:
- */
- p = do_lock(idx, fp);
+ /* Get a pointer to any existing lock for the file: */
+ if ((p = find_lock(idx, fp)) == NULL) {
+ /*
+ * The file is not locked, so this thread can
+ * grab the lock:
+ */
+ p = do_lock(idx, fp);
+ /*
+ * The file is already locked, so check if the
+ * running thread is the owner:
+ */
+ } else if (p->owner == _thread_run) {
/*
- * The file is already locked, so check if the
- * running thread is the owner:
+ * The running thread is already the
+ * owner, so increment the count of
+ * the number of times it has locked
+ * the file:
*/
- } else if (p->owner == _thread_run) {
- /*
- * The running thread is already the
- * owner, so increment the count of
- * the number of times it has locked
- * the file:
- */
- p->count++;
- } else {
- /*
- * The file is locked for another thread,
- * so this try fails.
- */
- p = NULL;
- }
+ p->count++;
+ } else {
+ /*
+ * The file is locked for another thread,
+ * so this try fails.
+ */
+ p = NULL;
+ }
- /* Check if the lock was obtained: */
- if (p != NULL)
- /* Return success: */
- ret = 0;
+ /* Check if the lock was obtained: */
+ if (p != NULL)
+ /* Return success: */
+ ret = 0;
- /* Unlock the hash table: */
- _SPINUNLOCK(&hash_lock);
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
- }
return (ret);
}
@@ -295,68 +290,64 @@ funlockfile(FILE * fp)
int idx = file_idx(fp);
struct file_lock *p;
- /* Check if this is a real file: */
- if (fileno(fp) >= 0) {
- /*
- * Defer signals to protect the scheduling queues from
- * access by the signal handler:
- */
- _thread_kern_sig_defer();
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
- /* Lock the hash table: */
- _SPINLOCK(&hash_lock);
+ /* Lock the hash table: */
+ _SPINLOCK(&hash_lock);
+ /*
+ * Get a pointer to the lock for the file and check that
+ * the running thread is the one with the lock:
+ */
+ if ((p = find_lock(idx, fp)) != NULL &&
+ p->owner == _thread_run) {
/*
- * Get a pointer to the lock for the file and check that
- * the running thread is the one with the lock:
+ * Check if this thread has locked the FILE
+ * more than once:
*/
- if ((p = find_lock(idx, fp)) != NULL &&
- p->owner == _thread_run) {
+ if (p->count > 1)
/*
- * Check if this thread has locked the FILE
- * more than once:
+ * Decrement the count of the number of
+ * times the running thread has locked this
+ * file:
*/
- if (p->count > 1)
- /*
- * Decrement the count of the number of
- * times the running thread has locked this
- * file:
- */
- p->count--;
- else {
+ p->count--;
+ else {
+ /*
+ * The running thread will release the
+ * lock now:
+ */
+ p->count = 0;
+
+ /* Get the new owner of the lock: */
+ if ((p->owner = TAILQ_FIRST(&p->l_head)) != NULL) {
+ /* Pop the thread off the queue: */
+ TAILQ_REMOVE(&p->l_head,p->owner,qe);
+
/*
- * The running thread will release the
- * lock now:
+ * This is the first lock for the new
+ * owner:
*/
- p->count = 0;
-
- /* Get the new owner of the lock: */
- if ((p->owner = TAILQ_FIRST(&p->l_head)) != NULL) {
- /* Pop the thread off the queue: */
- TAILQ_REMOVE(&p->l_head,p->owner,qe);
-
- /*
- * This is the first lock for the new
- * owner:
- */
- p->count = 1;
-
- /* Allow the new owner to run: */
- PTHREAD_NEW_STATE(p->owner,PS_RUNNING);
- }
+ p->count = 1;
+
+ /* Allow the new owner to run: */
+ PTHREAD_NEW_STATE(p->owner,PS_RUNNING);
}
}
+ }
- /* Unlock the hash table: */
- _SPINUNLOCK(&hash_lock);
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
- /*
- * Undefer and handle pending signals, yielding if
- * necessary:
- */
- _thread_kern_sig_undefer();
- }
- return;
+ /*
+ * Undefer and handle pending signals, yielding if
+ * necessary:
+ */
+ _thread_kern_sig_undefer();
}
#endif