summaryrefslogtreecommitdiffstats
path: root/lib/libc_r/uthread/uthread_fd.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc_r/uthread/uthread_fd.c')
-rw-r--r--lib/libc_r/uthread/uthread_fd.c89
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);
OpenPOWER on IntegriCloud