1 use crate::cell
::UnsafeCell
;
2 use crate::sys
::condvar
::Condvar
;
3 use crate::sys
::mutex
::Mutex
;
8 state
: UnsafeCell
<State
>,
11 pub type MovableRWLock
= Box
<RWLock
>;
19 unsafe impl Send
for RWLock {}
20 unsafe impl Sync
for RWLock {}
22 // This rwlock implementation is a relatively simple implementation which has a
23 // condition variable for readers/writers as well as a mutex protecting the
24 // internal state of the lock. A current downside of the implementation is that
25 // unlocking the lock will notify *all* waiters rather than just readers or just
26 // writers. This can cause lots of "thundering stampede" problems. While
27 // hopefully correct this implementation is very likely to want to be changed in
31 pub const fn new() -> RWLock
{
32 RWLock { lock: Mutex::new(), cond: Condvar::new(), state: UnsafeCell::new(State::Unlocked) }
36 pub unsafe fn read(&self) {
38 while !(*self.state
.get()).inc_readers() {
39 self.cond
.wait(&self.lock
);
45 pub unsafe fn try_read(&self) -> bool
{
47 let ok
= (*self.state
.get()).inc_readers();
53 pub unsafe fn write(&self) {
55 while !(*self.state
.get()).inc_writers() {
56 self.cond
.wait(&self.lock
);
62 pub unsafe fn try_write(&self) -> bool
{
64 let ok
= (*self.state
.get()).inc_writers();
70 pub unsafe fn read_unlock(&self) {
72 let notify
= (*self.state
.get()).dec_readers();
75 // FIXME: should only wake up one of these some of the time
76 self.cond
.notify_all();
81 pub unsafe fn write_unlock(&self) {
83 (*self.state
.get()).dec_writers();
85 // FIXME: should only wake up one of these some of the time
86 self.cond
.notify_all();
90 pub unsafe fn destroy(&self) {
97 fn inc_readers(&mut self) -> bool
{
100 *self = State
::Reading(1);
103 State
::Reading(ref mut cnt
) => {
107 State
::Writing
=> false,
111 fn inc_writers(&mut self) -> bool
{
114 *self = State
::Writing
;
117 State
::Reading(_
) | State
::Writing
=> false,
121 fn dec_readers(&mut self) -> bool
{
122 let zero
= match *self {
123 State
::Reading(ref mut cnt
) => {
127 State
::Unlocked
| State
::Writing
=> invalid(),
130 *self = State
::Unlocked
;
135 fn dec_writers(&mut self) {
138 State
::Unlocked
| State
::Reading(_
) => invalid(),
140 *self = State
::Unlocked
;
145 panic
!("inconsistent rwlock");