diff options
Diffstat (limited to 'lib/libc_r/uthread/uthread_fd.c')
-rw-r--r-- | lib/libc_r/uthread/uthread_fd.c | 89 |
1 files changed, 53 insertions, 36 deletions
diff --git a/lib/libc_r/uthread/uthread_fd.c b/lib/libc_r/uthread/uthread_fd.c index 541f92f..19b985f 100644 --- a/lib/libc_r/uthread/uthread_fd.c +++ b/lib/libc_r/uthread/uthread_fd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. + * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: uthread_fd.c,v 1.4 1997/04/01 22:49:58 jb Exp $ + * $Id: uthread_fd.c,v 1.5 1998/02/13 01:27:32 julian Exp $ * */ #include <errno.h> @@ -39,6 +39,9 @@ #include <pthread.h> #include "pthread_private.h" +/* Static variables: */ +static long fd_table_lock = 0; + /* * This function *must* return -1 and set the thread specific errno * as a system call. This is because the error return from this @@ -50,10 +53,9 @@ int _thread_fd_table_init(int fd) { int ret = 0; - int status; - /* Block signals: */ - _thread_kern_sig_block(&status); + /* Lock the file descriptor table: */ + _spinlock(&fd_table_lock); /* Check if the file descriptor is out of range: */ if (fd < 0 || fd >= _thread_dtablesize) { @@ -75,12 +77,12 @@ _thread_fd_table_init(int fd) /* Return a bad file descriptor error: */ errno = EBADF; ret = -1; - } - else { + } else { /* Assume that the operation will succeed: */ ret = 0; /* Initialise the file locks: */ + _thread_fd_table[fd]->access_lock = 0; _thread_fd_table[fd]->r_owner = NULL; _thread_fd_table[fd]->w_owner = NULL; _thread_fd_table[fd]->r_fname = NULL; @@ -134,8 +136,8 @@ _thread_fd_table_init(int fd) } } - /* Unblock signals: */ - _thread_kern_sig_unblock(status); + /* Unlock the file descriptor table: */ + _atomic_unlock(&fd_table_lock); /* Return the completion status: */ return (ret); @@ -145,17 +147,19 @@ void _thread_fd_unlock(int fd, int lock_type) { int ret; - int status; - - /* Block signals while the file descriptor lock is tested: */ - _thread_kern_sig_block(&status); /* * Check that the file descriptor table is initialised for this * entry: */ - if ((ret = _thread_fd_table_init(fd)) != 0) { - } else { + 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]->access_lock); + /* Check if the running thread owns the read lock: */ if (_thread_fd_table[fd]->r_owner == _thread_run) { /* Check the file descriptor and lock types: */ @@ -232,12 +236,12 @@ _thread_fd_unlock(int fd, int lock_type) } } } - } - /* Unblock signals again: */ - _thread_kern_sig_unblock(status); + /* Unlock the file descriptor table entry: */ + _atomic_unlock(&_thread_fd_table[fd]->access_lock); - /* Nothing to return. */ + } + /* Nothing to return. */ return; } @@ -246,17 +250,19 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout, char *fname, int lineno) { int ret; - int status; - - /* Block signals while the file descriptor lock is tested: */ - _thread_kern_sig_block(&status); /* * Check that the file descriptor table is initialised for this * entry: */ - if ((ret = _thread_fd_table_init(fd)) != 0) { - } else { + 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]->access_lock); + /* Check the file descriptor and lock types: */ if (lock_type == FD_READ || lock_type == FD_RDWR) { /* @@ -290,6 +296,12 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout, _thread_kern_set_timeout(timeout); /* + * Unlock the file descriptor + * table entry: + */ + _atomic_unlock(&_thread_fd_table[fd]->access_lock); + + /* * Schedule this thread to wait on * the read lock. It will only be * woken when it becomes the next in @@ -301,11 +313,11 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout, _thread_kern_sched_state(PS_FDLR_WAIT, __FILE__, __LINE__); /* - * Block signals so that the file - * descriptor lock can again be - * tested: + * Lock the file descriptor + * table entry again: */ - _thread_kern_sig_block(NULL); + _spinlock(&_thread_fd_table[fd]->access_lock); + } else { /* * The running thread now owns the @@ -365,6 +377,12 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout, _thread_kern_set_timeout(timeout); /* + * Unlock the file descriptor + * table entry: + */ + _atomic_unlock(&_thread_fd_table[fd]->access_lock); + + /* * Schedule this thread to wait on * the write lock. It will only be * woken when it becomes the next in @@ -375,11 +393,10 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout, _thread_kern_sched_state(PS_FDLW_WAIT, __FILE__, __LINE__); /* - * Block signals so that the file - * descriptor lock can again be - * tested: + * Lock the file descriptor + * table entry again: */ - _thread_kern_sig_block(NULL); + _spinlock(&_thread_fd_table[fd]->access_lock); } else { /* * The running thread now owns the @@ -406,10 +423,10 @@ _thread_fd_lock(int fd, int lock_type, struct timespec * timeout, /* Increment the write lock count: */ _thread_fd_table[fd]->w_lockcount++; } - } - /* Unblock signals again: */ - _thread_kern_sig_unblock(status); + /* Unlock the file descriptor table entry: */ + _atomic_unlock(&_thread_fd_table[fd]->access_lock); + } /* Return the completion status: */ return (ret); |