1 use crate::cell
::UnsafeCell
;
2 use crate::sys
::locks
::{Condvar, Mutex}
;
7 state
: UnsafeCell
<State
>,
10 pub type MovableRwLock
= RwLock
;
18 unsafe impl Send
for RwLock {}
19 unsafe impl Sync
for RwLock {}
21 // This rwlock implementation is a relatively simple implementation which has a
22 // condition variable for readers/writers as well as a mutex protecting the
23 // internal state of the lock. A current downside of the implementation is that
24 // unlocking the lock will notify *all* waiters rather than just readers or just
25 // writers. This can cause lots of "thundering stampede" problems. While
26 // hopefully correct this implementation is very likely to want to be changed in
30 pub const fn new() -> RwLock
{
31 RwLock { lock: Mutex::new(), cond: Condvar::new(), state: UnsafeCell::new(State::Unlocked) }
35 pub unsafe fn read(&self) {
37 while !(*self.state
.get()).inc_readers() {
38 self.cond
.wait(&self.lock
);
44 pub unsafe fn try_read(&self) -> bool
{
46 let ok
= (*self.state
.get()).inc_readers();
52 pub unsafe fn write(&self) {
54 while !(*self.state
.get()).inc_writers() {
55 self.cond
.wait(&self.lock
);
61 pub unsafe fn try_write(&self) -> bool
{
63 let ok
= (*self.state
.get()).inc_writers();
69 pub unsafe fn read_unlock(&self) {
71 let notify
= (*self.state
.get()).dec_readers();
74 // FIXME: should only wake up one of these some of the time
75 self.cond
.notify_all();
80 pub unsafe fn write_unlock(&self) {
82 (*self.state
.get()).dec_writers();
84 // FIXME: should only wake up one of these some of the time
85 self.cond
.notify_all();
89 pub unsafe fn destroy(&self) {
96 fn inc_readers(&mut self) -> bool
{
99 *self = State
::Reading(1);
102 State
::Reading(ref mut cnt
) => {
106 State
::Writing
=> false,
110 fn inc_writers(&mut self) -> bool
{
113 *self = State
::Writing
;
116 State
::Reading(_
) | State
::Writing
=> false,
120 fn dec_readers(&mut self) -> bool
{
121 let zero
= match *self {
122 State
::Reading(ref mut cnt
) => {
126 State
::Unlocked
| State
::Writing
=> invalid(),
129 *self = State
::Unlocked
;
134 fn dec_writers(&mut self) {
137 State
::Unlocked
| State
::Reading(_
) => invalid(),
139 *self = State
::Unlocked
;
144 panic
!("inconsistent rwlock");