diff options
author | Marco S Hyman <marc@cvs.openbsd.org> | 2002-10-30 20:05:13 +0000 |
---|---|---|
committer | Marco S Hyman <marc@cvs.openbsd.org> | 2002-10-30 20:05:13 +0000 |
commit | f8e9b25d6e29e8455ce88fbd4d127f1479cb0e1e (patch) | |
tree | f0d70d7ebc0b8b157b34a471497c6854c3b4c5ba /lib/libpthread | |
parent | a815f9179b6356b872c98792178860f0c06a7554 (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.h | 14 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_fd.c | 685 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_init.c | 12 |
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: |