1010
1111from typing_extensions import final
1212from functools import total_ordering
13+ import threading
14+ from queue import Queue
1315
14- __all__ = ["IOTag" , "ContTag" , "ResultTag" , "Scheduled" ]
16+ __all__ = ["IOTag" , "ContTag" , "ResultTag" , "Scheduled" , "Lock" , "Semaphore" ]
1517
1618
1719@final
@@ -43,6 +45,7 @@ class IOTag(Enum):
4345 WAIT = 24 # FIBERS
4446 SLEEP_UNTIL = 25 # EPOCH IN SECONDS
4547 REC = 26 # FUN
48+ LOCK = 27 # LOCK
4649
4750
4851@final
@@ -86,3 +89,60 @@ def __lt__(self, other):
8689 if self .__schedule == other .__schedule :
8790 return hash (self .__fiber ) < hash (other .__fiber )
8891 return self .__schedule < other .__schedule
92+
93+
94+ @final
95+ class Lock :
96+
97+ __slots__ = ["lock" , "fiber" , "__nb_taken" , "waiting" ]
98+
99+ def __init__ (self ):
100+ self .lock = threading .Lock ()
101+ self .fiber = None
102+ self .__nb_taken = 0
103+ self .waiting = Queue ()
104+
105+ def acquire (self , fiber ) -> bool :
106+ if self .fiber is None :
107+ self .__nb_taken = 1
108+ return True
109+ if self .fiber is fiber :
110+ self .fiber = fiber
111+ self .__nb_taken += 1
112+ return True
113+ return False
114+
115+ def release (self ):
116+ with self .lock :
117+ self .__nb_taken -= 1
118+ if self .__nb_taken == 0 :
119+ if self .waiting .empty ():
120+ self .fiber = None
121+ return
122+ self .fiber = self .waiting .get ()
123+ self .__nb_taken = 1
124+ self .fiber ._Fiber__monitor ._Monitor__resume (self .fiber )
125+
126+ @final
127+ class Semaphore :
128+
129+ __slots__ = ["lock" , "tokens" , "waiting" ]
130+
131+ def __init__ (self , tokens : int ):
132+ self .lock = threading .Lock ()
133+ self .tokens = tokens
134+ self .waiting = Queue ()
135+
136+ def acquire (self , fiber ) -> bool :
137+ if self .tokens > 0 :
138+ self .tokens -= 1
139+ return True
140+ return False
141+
142+ def release (self ):
143+ with self .lock :
144+ if self .waiting .empty ():
145+ self .tokens += 1
146+ return
147+ fiber = self .waiting .get ()
148+ fiber ._Fiber__monitor ._Monitor__resume (fiber )
0 commit comments