diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-10-26 02:42:26 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2017-10-26 02:42:26 +0200 |
commit | 4fc4b0dda73c8a04caff079ea358c53ed3dbfc71 (patch) | |
tree | cfdb2dda4fbee86b540c13888582646f6c99bc61 /lib/namespace | |
parent | 83fe7aaa5ce4776c394cb9edd89189b62efb89a9 (diff) | |
download | plan9front-4fc4b0dda73c8a04caff079ea358c53ed3dbfc71.tar.xz |
libc: wunlock() part 2
the initial issue was that wunlock() would wakeup readers while
holding the spinlock causing deadlock in libthread programs where
rendezvous() would do a thread switch within the same process
which then can acquire the RWLock again.
the first fix tried to prevent holding the spinlock, waking up
one reader at a time with releasing an re-acquiering the spinlock.
this violates the invariant that readers can only wakup writers
in runlock() when multiple readers where queued at the time of
wunlock(). at the first wakeup, q->head != nil so runlock() would
find a reader queued on runlock() when it expected a writer.
this (hopefully last) fix unlinks *all* the reader QLp's atomically
and in order while holding the spinlock and then traverses the
dequeued chain of QLp structures again to call rendezvous() so
the invariant described above holds.
Diffstat (limited to 'lib/namespace')
0 files changed, 0 insertions, 0 deletions