summaryrefslogtreecommitdiffstats
path: root/lib/libc_r/uthread/uthread_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc_r/uthread/uthread_file.c')
-rw-r--r--lib/libc_r/uthread/uthread_file.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/lib/libc_r/uthread/uthread_file.c b/lib/libc_r/uthread/uthread_file.c
index 88b6a8f..8f1afcd 100644
--- a/lib/libc_r/uthread/uthread_file.c
+++ b/lib/libc_r/uthread/uthread_file.c
@@ -245,6 +245,8 @@ _flockfile_debug(FILE * fp, char *fname, int lineno)
/* Unlock the hash table: */
_SPINUNLOCK(&hash_lock);
+ _thread_run->data.fp = fp;
+
/* Wait on the FILE lock: */
_thread_kern_sched_state(PS_FILE_WAIT, fname, lineno);
@@ -260,14 +262,12 @@ _flockfile_debug(FILE * fp, char *fname, int lineno)
_thread_run->continuation((void *)_thread_run);
}
}
- return;
}
void
_flockfile(FILE * fp)
{
_flockfile_debug(fp, __FILE__, __LINE__);
- return;
}
int
@@ -398,7 +398,6 @@ _funlockfile(FILE * fp)
*/
_thread_kern_sig_undefer();
}
- return;
}
void
@@ -469,4 +468,39 @@ _funlock_owned(pthread_t pthread)
_thread_kern_sig_undefer();
}
+void
+_flockfile_backout(pthread_t pthread)
+{
+ int idx = file_idx(pthread->data.fp);
+ struct file_lock *p;
+
+ /*
+ * Defer signals to protect the scheduling queues from
+ * access by the signal handler:
+ */
+ _thread_kern_sig_defer();
+
+ /*
+ * Get a pointer to the lock for the file and check that
+ * the running thread is the one with the lock:
+ */
+ if (((pthread->flags & PTHREAD_FLAGS_IN_FILEQ) != 0) &&
+ ((p = find_lock(idx, pthread->data.fp)) != NULL)) {
+ /* Lock the hash table: */
+ _SPINLOCK(&hash_lock);
+
+ /* Remove the thread from the queue: */
+ TAILQ_REMOVE(&p->l_head, pthread, qe);
+ pthread->flags &= ~PTHREAD_FLAGS_IN_FILEQ;
+
+ /* Unlock the hash table: */
+ _SPINUNLOCK(&hash_lock);
+ }
+
+ /*
+ * Undefer and handle pending signals, yielding if necessary:
+ */
+ _thread_kern_sig_undefer();
+}
+
#endif
OpenPOWER on IntegriCloud