#include "futex_impl.h" #include "threads_impl.h" #include "stdio_impl.h" int __lockfile(FILE* f) { int owner, tid = __thread_get_tid(); if (atomic_load(&f->lock) == tid) return 0; while ((owner = a_cas_shim(&f->lock, 0, tid))) __wait(&f->lock, &f->waiters, owner); return 1; } void __unlockfile(FILE* f) { atomic_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 (atomic_load(&f->waiters)) _zx_futex_wake(&f->lock, 1); }