| 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);
|
| +}
|
|
|