3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 from __future__ import print_function
15 from eventlet import greenthread, hubs
18 class CMEventletRWLock(object):
21 self._read_waiters = set()
22 self._write_waiters = set()
25 return self.Reader(self)
28 return self.Writer(self)
31 def __init__(self, parent):
34 def _acquire(self, waiters):
35 waiters.add(greenthread.getcurrent())
38 while self.parent.counter != 0:
39 hubs.get_hub().switch()
41 waiters.discard(greenthread.getcurrent())
45 (self.parent._read_waiters, lambda x: x >= 0),
46 (self.parent._write_waiters, lambda x: x == 0),
51 hubs.get_hub().schedule_call_global(
52 0, self._release, waiters, fn,
55 def _release(self, waiters, fn):
56 if waiters and fn(self.parent.counter):
57 waiters.pop().switch()
61 if self.parent.counter < 0:
62 self._acquire(self.parent._read_waiters)
63 self.parent.counter += 1
65 def __exit__(self, *args, **kwargs):
66 self.parent.counter -= 1
71 if self.parent.counter != 0:
72 self._acquire(self.parent._write_waiters)
73 self.parent.counter -= 1
75 def __exit__(self, *args, **kwargs):
76 self.parent.counter += 1
81 lock = CMEventletRWLock()
83 print('Got reader lock')
86 print('Got write lock')
89 if __name__ == '__main__':