summaryrefslogtreecommitdiff
path: root/lib/libpthread
diff options
context:
space:
mode:
authorMarco S Hyman <marc@cvs.openbsd.org>2002-10-30 20:05:13 +0000
committerMarco S Hyman <marc@cvs.openbsd.org>2002-10-30 20:05:13 +0000
commitf8e9b25d6e29e8455ce88fbd4d127f1479cb0e1e (patch)
treef0d70d7ebc0b8b157b34a471497c6854c3b4c5ba /lib/libpthread
parenta815f9179b6356b872c98792178860f0c06a7554 (diff)
removes duplicate functions and factor out common code so the needed (but
missing) _thread_fd_unlock_owned function can be added with minimal pain. The incorrect special handling of the stdio fds was also removed. Tested with the libc_r regression tests and the mysql regression tests. No complaints from any developers
Diffstat (limited to 'lib/libpthread')
-rw-r--r--lib/libpthread/uthread/pthread_private.h14
-rw-r--r--lib/libpthread/uthread/uthread_fd.c685
-rw-r--r--lib/libpthread/uthread/uthread_init.c12
3 files changed, 231 insertions, 480 deletions
diff --git a/lib/libpthread/uthread/pthread_private.h b/lib/libpthread/uthread/pthread_private.h
index 88341872451..9f64f0328e7 100644
--- a/lib/libpthread/uthread/pthread_private.h
+++ b/lib/libpthread/uthread/pthread_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pthread_private.h,v 1.36 2002/10/30 19:11:56 marc Exp $ */
+/* $OpenBSD: pthread_private.h,v 1.37 2002/10/30 20:05:11 marc Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
@@ -487,11 +487,8 @@ enum pthread_state {
/*
- * File descriptor locking definitions.
+ * File descriptor locking definitions are defined in "thread_private.h"
*/
-#define FD_READ 0x1
-#define FD_WRITE 0x2
-#define FD_RDWR (FD_READ | FD_WRITE)
/*
* File descriptor table structure.
@@ -929,13 +926,6 @@ SCLASS struct pthread_cond_attr pthread_condattr_default
;
#endif
-/*
- * Standard I/O file descriptors need special flag treatment since
- * setting one to non-blocking does all on *BSD. Sigh. This array
- * is used to store the initial flag settings.
- */
-SCLASS int _pthread_stdio_flags[3];
-
/* File table information: */
SCLASS struct fd_table_entry **_thread_fd_table
#ifdef GLOBAL_PTHREAD_PRIVATE
diff --git a/lib/libpthread/uthread/uthread_fd.c b/lib/libpthread/uthread/uthread_fd.c
index 0338ab4602e..d824a4c49d3 100644
--- a/lib/libpthread/uthread/uthread_fd.c
+++ b/lib/libpthread/uthread/uthread_fd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_fd.c,v 1.10 2001/09/04 22:17:45 fgsch Exp $ */
+/* $OpenBSD: uthread_fd.c,v 1.11 2002/10/30 20:05:11 marc Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -45,12 +45,13 @@
static spinlock_t fd_table_lock = _SPINLOCK_INITIALIZER;
/*
+ * Initialize the fd_table entry for the given fd.
+ *
* This function *must* return -1 and set the thread specific errno
* as a system call. This is because the error return from this
* function is propagated directly back from thread-wrapped system
* calls.
*/
-
int
_thread_fd_table_init(int fd)
{
@@ -58,118 +59,105 @@ _thread_fd_table_init(int fd)
struct fd_table_entry *entry;
int saved_errno;
- /* Check if the file descriptor is out of range: */
if (fd < 0 || fd >= _thread_dtablesize) {
- /* Return a bad file descriptor error: */
+ /*
+ * file descriptor is out of range, Return a bad file
+ * descriptor error:
+ */
errno = EBADF;
ret = -1;
- }
-
- /*
- * Check if memory has already been allocated for this file
- * descriptor:
- */
- else if (_thread_fd_table[fd] != NULL) {
- /* Memory has already been allocated. */
-
- /* Allocate memory for the file descriptor table entry: */
- } else if ((entry = (struct fd_table_entry *)
- malloc(sizeof(struct fd_table_entry))) == NULL) {
- /* Return an insufficient memory error: */
- errno = ENOMEM;
- ret = -1;
- } else {
- /* Initialise the file locks: */
- _SPINLOCK_INIT(&entry->lock);
- entry->r_owner = NULL;
- entry->w_owner = NULL;
- entry->r_fname = NULL;
- entry->w_fname = NULL;
- entry->r_lineno = 0;
- entry->w_lineno = 0;
- entry->r_lockcount = 0;
- entry->w_lockcount = 0;
-
- /* Initialise the read/write queues: */
- TAILQ_INIT(&entry->r_queue);
- TAILQ_INIT(&entry->w_queue);
-
- /* Get the flags for the file: */
- if (((fd >= 3) || (_pthread_stdio_flags[fd] == -1)) &&
- (entry->flags = _thread_sys_fcntl(fd, F_GETFL, 0)) == -1) {
+ } else if (_thread_fd_table[fd] == NULL) {
+ /* First time for this fd, build an entry */
+ entry = (struct fd_table_entry *)
+ malloc(sizeof(struct fd_table_entry));
+ if (entry == NULL) {
+ errno = ENOMEM;
ret = -1;
- }
- else {
- /* Check if a stdio descriptor: */
- if ((fd < 3) && (_pthread_stdio_flags[fd] != -1))
+ } else {
+ /* Initialise the file locks: */
+ _SPINLOCK_INIT(&entry->lock);
+ entry->r_owner = NULL;
+ entry->w_owner = NULL;
+ entry->r_fname = NULL;
+ entry->w_fname = NULL;
+ entry->r_lineno = 0;
+ entry->w_lineno = 0;
+ entry->r_lockcount = 0;
+ entry->w_lockcount = 0;
+
+ /* Initialise the read/write queues: */
+ TAILQ_INIT(&entry->r_queue);
+ TAILQ_INIT(&entry->w_queue);
+
+ /* Get the flags for the file: */
+ entry->flags = _thread_sys_fcntl(fd, F_GETFL, 0);
+ if (entry->flags == -1)
+ /* use the errno fcntl returned */
+ ret = -1;
+ else {
/*
- * Use the stdio flags read by
- * _pthread_init() to avoid
- * mistaking the non-blocking
- * flag that, when set on one
- * stdio fd, is set on all stdio
- * fds.
+ * Make the file descriptor non-blocking.
+ * This might fail if the device driver does
+ * not support non-blocking calls, or if the
+ * driver is naturally non-blocking.
*/
- entry->flags = _pthread_stdio_flags[fd];
+ saved_errno = errno;
+ _thread_sys_fcntl(fd, F_SETFL,
+ entry->flags | O_NONBLOCK);
+ errno = saved_errno;
- /*
- * Make the file descriptor non-blocking.
- * This might fail if the device driver does
- * not support non-blocking calls, or if the
- * driver is naturally non-blocking.
- */
- saved_errno = errno;
- _thread_sys_fcntl(fd, F_SETFL,
- entry->flags | O_NONBLOCK);
- errno = saved_errno;
+ /* Lock the file descriptor table: */
+ _SPINLOCK(&fd_table_lock);
- /* Lock the file descriptor table: */
- _SPINLOCK(&fd_table_lock);
+ /*
+ * Check if another thread allocated the
+ * file descriptor entry while this thread
+ * was doing the same thing. The table wasn't
+ * kept locked during this operation because
+ * it has the potential to recurse.
+ */
+ if (_thread_fd_table[fd] == NULL) {
+ /* This thread wins: */
+ _thread_fd_table[fd] = entry;
+ entry = NULL;
+ }
- /*
- * Check if another thread allocated the
- * file descriptor entry while this thread
- * was doing the same thing. The table wasn't
- * kept locked during this operation because
- * it has the potential to recurse.
- */
- if (_thread_fd_table[fd] == NULL) {
- /* This thread wins: */
- _thread_fd_table[fd] = entry;
- entry = NULL;
+ /* Unlock the file descriptor table: */
+ _SPINUNLOCK(&fd_table_lock);
}
- /* Unlock the file descriptor table: */
- _SPINUNLOCK(&fd_table_lock);
- }
-
- /*
- * Check if another thread initialised the table entry
- * before this one could:
- */
- if (entry != NULL)
/*
- * Throw away the table entry that this thread
- * prepared. The other thread wins.
+ * If there was an error in getting the flags for
+ * the file or if another thread initialized the
+ * table entry throw this entry away.
*/
- free(entry);
+ if (entry != NULL)
+ free(entry);
+ }
}
/* Return the completion status: */
return (ret);
}
+/*
+ * Unlock the fd table entry for a given thread, fd, and lock type.
+ */
void
-_thread_fd_unlock(int fd, int lock_type)
+_thread_fd_unlock_thread(struct pthread *thread, int fd, int lock_type,
+ char *fname, int lineno)
{
- struct pthread *curthread = _get_curthread();
+ struct fd_table_entry *entry;
int ret;
/*
* Check that the file descriptor table is initialised for this
* entry:
*/
- if ((ret = _thread_fd_table_init(fd)) == 0) {
+ ret = _thread_fd_table_init(fd);
+ if (ret == 0) {
+ entry = _thread_fd_table[fd];
+
/*
* Defer signals to protect the scheduling queues from
* access by the signal handler:
@@ -181,81 +169,72 @@ _thread_fd_unlock(int fd, int lock_type)
* other threads for clashing with the current
* thread's accesses:
*/
- _SPINLOCK(&_thread_fd_table[fd]->lock);
+ if (fname)
+ _spinlock_debug(&entry->lock, fname, lineno);
+ else
+ _SPINLOCK(&entry->lock);
/* Check if the running thread owns the read lock: */
- if (_thread_fd_table[fd]->r_owner == curthread) {
- /* Check the file descriptor and lock types: */
- if (lock_type == FD_READ || lock_type == FD_RDWR) {
- /*
- * Decrement the read lock count for the
- * running thread:
- */
- _thread_fd_table[fd]->r_lockcount--;
-
- /*
- * Check if the running thread still has read
- * locks on this file descriptor:
- */
- if (_thread_fd_table[fd]->r_lockcount != 0) {
- }
+ if (entry->r_owner == thread &&
+ (lock_type == FD_READ || lock_type == FD_RDWR)) {
+ /*
+ * Decrement the read lock count for the
+ * running thread:
+ */
+ entry->r_lockcount--;
+ if (entry->r_lockcount == 0) {
/*
- * Get the next thread in the queue for a
- * read lock on this file descriptor:
+ * no read locks, dequeue any threads
+ * waiting for a read lock
*/
- else if ((_thread_fd_table[fd]->r_owner = TAILQ_FIRST(&_thread_fd_table[fd]->r_queue)) == NULL) {
- } else {
- /* Remove this thread from the queue: */
- TAILQ_REMOVE(&_thread_fd_table[fd]->r_queue,
- _thread_fd_table[fd]->r_owner, qe);
+ entry->r_owner = TAILQ_FIRST(&entry->r_queue);
+ if (entry->r_owner != NULL) {
+ TAILQ_REMOVE(&entry->r_queue,
+ entry->r_owner, qe);
/*
* Set the state of the new owner of
- * the thread to running:
+ * the thread to running:
*/
- PTHREAD_NEW_STATE(_thread_fd_table[fd]->r_owner,PS_RUNNING);
+ PTHREAD_NEW_STATE(entry->r_owner,
+ PS_RUNNING);
/*
* Reset the number of read locks.
- * This will be incremented by the
- * new owner of the lock when it sees
- * that it has the lock.
+ * This will be incremented by the new
+ * owner of the lock when it sees that
+ *it has the lock.
*/
- _thread_fd_table[fd]->r_lockcount = 0;
+ entry->r_lockcount = 0;
}
}
+
}
/* Check if the running thread owns the write lock: */
- if (_thread_fd_table[fd]->w_owner == curthread) {
- /* Check the file descriptor and lock types: */
- if (lock_type == FD_WRITE || lock_type == FD_RDWR) {
- /*
- * Decrement the write lock count for the
- * running thread:
- */
- _thread_fd_table[fd]->w_lockcount--;
-
- /*
- * Check if the running thread still has
- * write locks on this file descriptor:
- */
- if (_thread_fd_table[fd]->w_lockcount != 0) {
- }
+ if (entry->w_owner == thread &&
+ (lock_type == FD_WRITE || lock_type == FD_RDWR)) {
+ /*
+ * Decrement the write lock count for the
+ * running thread:
+ */
+ entry->w_lockcount--;
+ if (entry->w_lockcount == 0) {
/*
- * Get the next thread in the queue for a
- * write lock on this file descriptor:
+ * no write locks, dequeue any threads
+ * waiting on a write lock.
*/
- else if ((_thread_fd_table[fd]->w_owner = TAILQ_FIRST(&_thread_fd_table[fd]->w_queue)) == NULL) {
- } else {
+ entry->w_owner = TAILQ_FIRST(&entry->w_queue);
+ if (entry->w_owner != NULL) {
/* Remove this thread from the queue: */
- TAILQ_REMOVE(&_thread_fd_table[fd]->w_queue,
- _thread_fd_table[fd]->w_owner, qe);
+ TAILQ_REMOVE(&entry->w_queue,
+ entry->w_owner, qe);
/*
* Set the state of the new owner of
* the thread to running:
*/
- PTHREAD_NEW_STATE(_thread_fd_table[fd]->w_owner,PS_RUNNING);
+ PTHREAD_NEW_STATE(entry->w_owner,
+ PS_RUNNING);
/*
* Reset the number of write locks.
@@ -263,13 +242,13 @@ _thread_fd_unlock(int fd, int lock_type)
* new owner of the lock when it
* sees that it has the lock.
*/
- _thread_fd_table[fd]->w_lockcount = 0;
+ entry->w_lockcount = 0;
}
}
}
/* Unlock the file descriptor table entry: */
- _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+ _SPINUNLOCK(&entry->lock);
/*
* Undefer and handle pending signals, yielding if
@@ -282,337 +261,113 @@ _thread_fd_unlock(int fd, int lock_type)
return;
}
-int
-_thread_fd_lock(int fd, int lock_type, struct timespec * timeout)
+/*
+ * Unlock an fd table entry for the given fd and lock type. Save
+ * fname and lineno (debug variables).
+ */
+void
+_thread_fd_unlock_debug(int fd, int lock_type, char *fname, int lineno)
{
struct pthread *curthread = _get_curthread();
- int ret;
-
- /*
- * Check that the file descriptor table is initialised for this
- * entry:
- */
- if ((ret = _thread_fd_table_init(fd)) == 0) {
- /*
- * Lock the file descriptor table entry to prevent
- * other threads for clashing with the current
- * thread's accesses:
- */
- _SPINLOCK(&_thread_fd_table[fd]->lock);
-
- /* Check the file descriptor and lock types: */
- if (lock_type == FD_READ || lock_type == FD_RDWR) {
- /*
- * Enter a loop to wait for the file descriptor to be
- * locked for read for the current thread:
- */
- while (_thread_fd_table[fd]->r_owner != curthread) {
- /*
- * Check if the file descriptor is locked by
- * another thread:
- */
- if (_thread_fd_table[fd]->r_owner != NULL) {
- /*
- * Another thread has locked the file
- * descriptor for read, so join the
- * queue of threads waiting for a
- * read lock on this file descriptor:
- */
- TAILQ_INSERT_TAIL(&_thread_fd_table[fd]->r_queue, curthread, qe);
-
- /*
- * Save the file descriptor details
- * in the thread structure for the
- * running thread:
- */
- curthread->data.fd.fd = fd;
-
- /* Set the timeout: */
- _thread_kern_set_timeout(timeout);
-
- /*
- * Unlock the file descriptor
- * table entry:
- */
- _SPINUNLOCK(&_thread_fd_table[fd]->lock);
-
- /*
- * Schedule this thread to wait on
- * the read lock. It will only be
- * woken when it becomes the next in
- * the queue and is granted access
- * to the lock by the thread
- * that is unlocking the file
- * descriptor.
- */
- _thread_kern_sched_state(PS_FDLR_WAIT, __FILE__, __LINE__);
-
- /*
- * Lock the file descriptor
- * table entry again:
- */
- _SPINLOCK(&_thread_fd_table[fd]->lock);
-
- } else {
- /*
- * The running thread now owns the
- * read lock on this file descriptor:
- */
- _thread_fd_table[fd]->r_owner = curthread;
-
- /*
- * Reset the number of read locks for
- * this file descriptor:
- */
- _thread_fd_table[fd]->r_lockcount = 0;
- }
- }
-
- /* Increment the read lock count: */
- _thread_fd_table[fd]->r_lockcount++;
- }
-
- /* Check the file descriptor and lock types: */
- if (lock_type == FD_WRITE || lock_type == FD_RDWR) {
- /*
- * Enter a loop to wait for the file descriptor to be
- * locked for write for the current thread:
- */
- while (_thread_fd_table[fd]->w_owner != curthread) {
- /*
- * Check if the file descriptor is locked by
- * another thread:
- */
- if (_thread_fd_table[fd]->w_owner != NULL) {
- /*
- * Another thread has locked the file
- * descriptor for write, so join the
- * queue of threads waiting for a
- * write lock on this file
- * descriptor:
- */
- TAILQ_INSERT_TAIL(&_thread_fd_table[fd]->w_queue, curthread, qe);
-
- /*
- * Save the file descriptor details
- * in the thread structure for the
- * running thread:
- */
- curthread->data.fd.fd = fd;
-
- /* Set the timeout: */
- _thread_kern_set_timeout(timeout);
-
- /*
- * Unlock the file descriptor
- * table entry:
- */
- _SPINUNLOCK(&_thread_fd_table[fd]->lock);
-
- /*
- * Schedule this thread to wait on
- * the write lock. It will only be
- * woken when it becomes the next in
- * the queue and is granted access to
- * the lock by the thread that is
- * unlocking the file descriptor.
- */
- _thread_kern_sched_state(PS_FDLW_WAIT, __FILE__, __LINE__);
-
- /*
- * Lock the file descriptor
- * table entry again:
- */
- _SPINLOCK(&_thread_fd_table[fd]->lock);
- } else {
- /*
- * The running thread now owns the
- * write lock on this file
- * descriptor:
- */
- _thread_fd_table[fd]->w_owner = curthread;
-
- /*
- * Reset the number of write locks
- * for this file descriptor:
- */
- _thread_fd_table[fd]->w_lockcount = 0;
- }
- }
-
- /* Increment the write lock count: */
- _thread_fd_table[fd]->w_lockcount++;
- }
-
- /* Unlock the file descriptor table entry: */
- _SPINUNLOCK(&_thread_fd_table[fd]->lock);
- }
-
- /* Return the completion status: */
- return (ret);
+ return (_thread_fd_unlock_thread(curthread, fd, lock_type,
+ fname, lineno));
}
+/*
+ * Unlock an fd table entry for the given fd and lock type (read,
+ * write, or read-write).
+ */
void
-_thread_fd_unlock_debug(int fd, int lock_type, char *fname, int lineno)
+_thread_fd_unlock(int fd, int lock_type)
{
struct pthread *curthread = _get_curthread();
- int ret;
-
- /*
- * Check that the file descriptor table is initialised for this
- * entry:
- */
- if ((ret = _thread_fd_table_init(fd)) == 0) {
- /*
- * Defer signals to protect the scheduling queues from
- * access by the signal handler:
- */
- _thread_kern_sig_defer();
-
- /*
- * Lock the file descriptor table entry to prevent
- * other threads for clashing with the current
- * thread's accesses:
- */
- _spinlock_debug(&_thread_fd_table[fd]->lock, fname, lineno);
-
- /* Check if the running thread owns the read lock: */
- if (_thread_fd_table[fd]->r_owner == curthread) {
- /* Check the file descriptor and lock types: */
- if (lock_type == FD_READ || lock_type == FD_RDWR) {
- /*
- * Decrement the read lock count for the
- * running thread:
- */
- _thread_fd_table[fd]->r_lockcount--;
-
- /*
- * Check if the running thread still has read
- * locks on this file descriptor:
- */
- if (_thread_fd_table[fd]->r_lockcount != 0) {
- }
- /*
- * Get the next thread in the queue for a
- * read lock on this file descriptor:
- */
- else if ((_thread_fd_table[fd]->r_owner = TAILQ_FIRST(&_thread_fd_table[fd]->r_queue)) == NULL) {
- } else {
- /* Remove this thread from the queue: */
- TAILQ_REMOVE(&_thread_fd_table[fd]->r_queue,
- _thread_fd_table[fd]->r_owner, qe);
-
- /*
- * Set the state of the new owner of
- * the thread to running:
- */
- PTHREAD_NEW_STATE(_thread_fd_table[fd]->r_owner,PS_RUNNING);
+ return (_thread_fd_unlock_thread(curthread, fd, lock_type, NULL, 0));
+}
- /*
- * Reset the number of read locks.
- * This will be incremented by the
- * new owner of the lock when it sees
- * that it has the lock.
- */
- _thread_fd_table[fd]->r_lockcount = 0;
- }
+/*
+ * Unlock all fd table entries owned by the given thread
+ */
+void
+_thread_fd_unlock_owned(pthread_t pthread)
+{
+ struct pthread *saved_thread = _get_curthread();
+ struct fd_table_entry *entry;
+ int do_unlock;
+ int fd;
+
+ for (fd = 0; fd < _thread_dtablesize; fd++) {
+ entry = _thread_fd_table[fd];
+ if (entry) {
+ _SPINLOCK(&entry->lock);
+ do_unlock = 0;
+ /* force an unlock regardless of the recursion level */
+ if (entry->r_owner == pthread) {
+ entry->r_lockcount = 1;
+ do_unlock++;
}
- }
- /* Check if the running thread owns the write lock: */
- if (_thread_fd_table[fd]->w_owner == curthread) {
- /* Check the file descriptor and lock types: */
- if (lock_type == FD_WRITE || lock_type == FD_RDWR) {
- /*
- * Decrement the write lock count for the
- * running thread:
- */
- _thread_fd_table[fd]->w_lockcount--;
-
- /*
- * Check if the running thread still has
- * write locks on this file descriptor:
- */
- if (_thread_fd_table[fd]->w_lockcount != 0) {
- }
- /*
- * Get the next thread in the queue for a
- * write lock on this file descriptor:
- */
- else if ((_thread_fd_table[fd]->w_owner = TAILQ_FIRST(&_thread_fd_table[fd]->w_queue)) == NULL) {
- } else {
- /* Remove this thread from the queue: */
- TAILQ_REMOVE(&_thread_fd_table[fd]->w_queue,
- _thread_fd_table[fd]->w_owner, qe);
-
- /*
- * Set the state of the new owner of
- * the thread to running:
- */
- PTHREAD_NEW_STATE(_thread_fd_table[fd]->w_owner,PS_RUNNING);
-
- /*
- * Reset the number of write locks.
- * This will be incremented by the
- * new owner of the lock when it
- * sees that it has the lock.
- */
- _thread_fd_table[fd]->w_lockcount = 0;
- }
+ if (entry->w_owner == pthread) {
+ entry->w_lockcount = 1;
+ do_unlock++;
}
+ _SPINUNLOCK(&entry->lock);
+ if (do_unlock)
+ _thread_fd_unlock_thread(pthread, fd, FD_RDWR,
+ __FILE__, __LINE__);
}
-
- /* Unlock the file descriptor table entry: */
- _SPINUNLOCK(&_thread_fd_table[fd]->lock);
-
- /*
- * Undefer and handle pending signals, yielding if
- * necessary.
- */
- _thread_kern_sig_undefer();
}
-
- /* Nothing to return. */
- return;
}
+/*
+ * Lock an fd table entry for the given fd and lock type. Save
+ * fname and lineno (debug variables). The debug variables may be
+ * null when called by the non-debug version of the function.
+ */
int
_thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout,
- char *fname, int lineno)
+ char *fname, int lineno)
{
struct pthread *curthread = _get_curthread();
+ struct fd_table_entry *entry;
int ret;
/*
* Check that the file descriptor table is initialised for this
* entry:
*/
- if ((ret = _thread_fd_table_init(fd)) == 0) {
+ ret = _thread_fd_table_init(fd);
+ if (ret == 0) {
+ entry = _thread_fd_table[fd];
+
/*
* Lock the file descriptor table entry to prevent
* other threads for clashing with the current
* thread's accesses:
*/
- _spinlock_debug(&_thread_fd_table[fd]->lock, fname, lineno);
+ if (fname)
+ _spinlock_debug(&entry->lock, fname, lineno);
+ else
+ _SPINLOCK(&entry->lock);
- /* Check the file descriptor and lock types: */
+ /* Handle read locks */
if (lock_type == FD_READ || lock_type == FD_RDWR) {
/*
* Enter a loop to wait for the file descriptor to be
* locked for read for the current thread:
*/
- while (_thread_fd_table[fd]->r_owner != curthread) {
+ while (entry->r_owner != curthread) {
/*
* Check if the file descriptor is locked by
* another thread:
*/
- if (_thread_fd_table[fd]->r_owner != NULL) {
+ if (entry->r_owner != NULL) {
/*
* Another thread has locked the file
* descriptor for read, so join the
* queue of threads waiting for a
* read lock on this file descriptor:
*/
- TAILQ_INSERT_TAIL(&_thread_fd_table[fd]->r_queue, curthread, qe);
+ TAILQ_INSERT_TAIL(&entry->r_queue,
+ curthread, qe);
/*
* Save the file descriptor details
@@ -630,63 +385,59 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout,
* Unlock the file descriptor
* table entry:
*/
- _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+ _SPINUNLOCK(&entry->lock);
/*
* Schedule this thread to wait on
* the read lock. It will only be
* woken when it becomes the next in
* the queue and is granted access
- * to the lock by the thread
- * that is unlocking the file
- * descriptor.
+ * to the lock by the thread that is
+ * unlocking the file descriptor.
*/
- _thread_kern_sched_state(PS_FDLR_WAIT, __FILE__, __LINE__);
+ _thread_kern_sched_state(PS_FDLR_WAIT,
+ __FILE__,
+ __LINE__);
/*
* Lock the file descriptor
* table entry again:
*/
- _SPINLOCK(&_thread_fd_table[fd]->lock);
+ _SPINLOCK(&entry->lock);
} else {
/*
* The running thread now owns the
* read lock on this file descriptor:
*/
- _thread_fd_table[fd]->r_owner = curthread;
+ entry->r_owner = curthread;
/*
* Reset the number of read locks for
* this file descriptor:
*/
- _thread_fd_table[fd]->r_lockcount = 0;
-
- /*
- * Save the source file details for
- * debugging:
- */
- _thread_fd_table[fd]->r_fname = fname;
- _thread_fd_table[fd]->r_lineno = lineno;
+ entry->r_lockcount = 0;
+ entry->r_fname = fname;
+ entry->r_lineno = lineno;
}
}
/* Increment the read lock count: */
- _thread_fd_table[fd]->r_lockcount++;
+ entry->r_lockcount++;
}
- /* Check the file descriptor and lock types: */
+ /* Handle write locks */
if (lock_type == FD_WRITE || lock_type == FD_RDWR) {
/*
* Enter a loop to wait for the file descriptor to be
* locked for write for the current thread:
*/
- while (_thread_fd_table[fd]->w_owner != curthread) {
+ while (entry->w_owner != curthread) {
/*
* Check if the file descriptor is locked by
* another thread:
*/
- if (_thread_fd_table[fd]->w_owner != NULL) {
+ if (entry->w_owner != NULL) {
/*
* Another thread has locked the file
* descriptor for write, so join the
@@ -694,7 +445,8 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout,
* write lock on this file
* descriptor:
*/
- TAILQ_INSERT_TAIL(&_thread_fd_table[fd]->w_queue, curthread, qe);
+ TAILQ_INSERT_TAIL(&entry->w_queue,
+ curthread, qe);
/*
* Save the file descriptor details
@@ -712,7 +464,7 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout,
* Unlock the file descriptor
* table entry:
*/
- _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+ _SPINUNLOCK(&entry->lock);
/*
* Schedule this thread to wait on
@@ -720,47 +472,54 @@ _thread_fd_lock_debug(int fd, int lock_type, struct timespec * timeout,
* woken when it becomes the next in
* the queue and is granted access to
* the lock by the thread that is
- * unlocking the file descriptor.
+ * unlocking the file descriptor.
*/
- _thread_kern_sched_state(PS_FDLW_WAIT, __FILE__, __LINE__);
+ _thread_kern_sched_state(PS_FDLW_WAIT,
+ __FILE__,
+ __LINE__);
/*
* Lock the file descriptor
* table entry again:
*/
- _SPINLOCK(&_thread_fd_table[fd]->lock);
+ _SPINLOCK(&entry->lock);
} else {
/*
* The running thread now owns the
- * write lock on this file
- * descriptor:
+ * write lock on this file descriptor:
*/
- _thread_fd_table[fd]->w_owner = curthread;
+ entry->w_owner = curthread;
/*
* Reset the number of write locks
* for this file descriptor:
*/
- _thread_fd_table[fd]->w_lockcount = 0;
-
- /*
- * Save the source file details for
- * debugging:
- */
- _thread_fd_table[fd]->w_fname = fname;
- _thread_fd_table[fd]->w_lineno = lineno;
+ entry->w_lockcount = 0;
+ entry->w_fname = fname;
+ entry->w_lineno = lineno;
}
}
/* Increment the write lock count: */
- _thread_fd_table[fd]->w_lockcount++;
+ entry->w_lockcount++;
}
/* Unlock the file descriptor table entry: */
- _SPINUNLOCK(&_thread_fd_table[fd]->lock);
+ _SPINUNLOCK(&entry->lock);
}
/* Return the completion status: */
return (ret);
}
+
+/*
+ * Non-debug version of fd locking. Just call the debug version
+ * passing a null file and line
+ */
+int
+_thread_fd_lock(int fd, int lock_type, struct timespec * timeout)
+{
+ return (_thread_fd_lock_debug(fd, lock_type, timeout, NULL, 0));
+}
+
#endif
diff --git a/lib/libpthread/uthread/uthread_init.c b/lib/libpthread/uthread/uthread_init.c
index 803e46e1fe8..858f6aebd34 100644
--- a/lib/libpthread/uthread/uthread_init.c
+++ b/lib/libpthread/uthread/uthread_init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_init.c,v 1.22 2002/10/30 19:11:56 marc Exp $ */
+/* $OpenBSD: uthread_init.c,v 1.23 2002/10/30 20:05:12 marc Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -105,13 +105,15 @@ _thread_init(void)
PANIC("Can't dup2");
}
- /* Get the standard I/O flags before messing with them : */
+ /*
+ * initialize the fd table for the stdio files. This grabs
+ * the file flags before we start messing with them.
+ */
for (i = 0; i < 3; i++)
- if (((_pthread_stdio_flags[i] =
- _thread_sys_fcntl(i,F_GETFL, NULL)) == -1) &&
- (errno != EBADF))
+ if (_thread_fd_table_init(i) == -1 && errno != EBADF)
PANIC("Cannot get stdio flags");
+
/*
* Create a pipe that is written to by the signal handler to prevent
* signals being missed in calls to _select: