Index: fusl/src/stdio/__lockfile.c |
diff --git a/fusl/src/stdio/__lockfile.c b/fusl/src/stdio/__lockfile.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9d967d6eb8860c0522b9fcd8505d6e52fad19b6b |
--- /dev/null |
+++ b/fusl/src/stdio/__lockfile.c |
@@ -0,0 +1,28 @@ |
+#include "stdio_impl.h" |
+#include "pthread_impl.h" |
+ |
+int __lockfile(FILE *f) |
+{ |
+ int owner, tid = __pthread_self()->tid; |
+ if (f->lock == tid) |
+ return 0; |
+ while ((owner = a_cas(&f->lock, 0, tid))) |
+ __wait(&f->lock, &f->waiters, owner, 1); |
+ return 1; |
+} |
+ |
+void __unlockfile(FILE *f) |
+{ |
+ a_store(&f->lock, 0); |
+ |
+ /* The following read is technically invalid under situations |
+ * of self-synchronized destruction. Another thread may have |
+ * called fclose as soon as the above store has completed. |
+ * Nonetheless, since FILE objects always live in memory |
+ * obtained by malloc from the heap, it's safe to assume |
+ * the dereferences below will not fault. In the worst case, |
+ * a spurious syscall will be made. If the implementation of |
+ * malloc changes, this assumption needs revisiting. */ |
+ |
+ if (f->waiters) __wake(&f->lock, 1, 1); |
+} |