33import traceback , signal as _signal
44from threading import Event
55from time import monotonic , sleep
6- from typing import Callable , Dict , Any , Iterator , Iterable , Optional , Union , Type
6+ from typing import Callable , Dict , Any , Iterator , Iterable , Optional , Union , cast
77# Third party modules
88# Local modules
9+ from .abcs import T_Signal , T_Locker , T_Lock
910# Program
1011class KillSignal (Exception ): pass
1112
@@ -30,74 +31,117 @@ def __next__(self) -> Any:
3031 raise KillSignal
3132 return self .it .__next__ ()
3233
33- class BaseSignal :
34- _force :bool
35- @classmethod
34+ class ExtendedLocker (T_Locker ):
35+ def __init__ (self , lock :T_Lock ) -> None :
36+ self .lock = lock
37+ def __del__ (self ) -> None :
38+ if self .locked ():
39+ self .release ()
40+ def acquire (self , blocking :bool = True , timeout :float = - 1.0 ) -> bool :
41+ return self .lock .acquire (blocking , timeout )
42+ def release (self ) -> None :
43+ self .lock .release ()
44+ def owned (self ) -> bool :
45+ if hasattr (self .lock , "locked" ):
46+ return self .lock .locked ()
47+ return self .lock ._is_owned ()
48+ def locked (self ) -> bool :
49+ if hasattr (self .lock , "locked" ):
50+ return self .lock .locked ()
51+ r = self .lock ._is_owned ()
52+ if r :
53+ return True
54+ r = self .lock .acquire (False )
55+ if r :
56+ self .lock .release ()
57+ return False
58+ return True
59+ def __enter__ (self ) -> Any :
60+ self .lock .acquire ()
61+ def __exit__ (self , type :Any , value :Any , traceback :Any ) -> Any :
62+ self .lock .release ()
63+
64+ class SignalLocker (ExtendedLocker ):
65+ event :Event
66+ def __init__ (self , event :Event , lock :T_Lock ) -> None :
67+ self .event = event
68+ self .lock = lock
69+ def acquire (self , blocking :bool = True , timeout :float = - 1.0 ) -> bool :
70+ r :bool
71+ if blocking :
72+ if timeout is not None and timeout > 0 :
73+ for _ in range (5 ):
74+ r = self .lock .acquire (True , timeout / 5 )
75+ if r :
76+ return r
77+ if self .event .is_set ():
78+ raise KillSignal
79+ return False
80+ else :
81+ while True :
82+ if self .event .is_set ():
83+ raise KillSignal
84+ r = self .lock .acquire (True , 1 )
85+ if r :
86+ return r
87+ else :
88+ return self .lock .acquire (False )
89+
90+ class BaseSignal (T_Signal ):
3691 def get (self ) -> bool :
3792 if isinstance (Signal ._handler , Signal ):
3893 return Signal ._handler ._get (self ._force )
3994 return False
40- @classmethod
4195 def getSoft (self ) -> bool :
4296 if isinstance (Signal ._handler , Signal ):
4397 return Signal ._handler ._get (False )
4498 return False
45- @classmethod
4699 def getHard (self ) -> bool :
47100 if isinstance (Signal ._handler , Signal ):
48101 return Signal ._handler ._get (True )
49102 return False
50- @classmethod
51103 def check (self ) -> None :
52104 if isinstance (Signal ._handler , Signal ):
53105 return Signal ._handler ._check (self ._force )
54- @classmethod
55106 def checkSoft (self ) -> None :
56107 if isinstance (Signal ._handler , Signal ):
57108 return Signal ._handler ._check (False )
58- @classmethod
59109 def checkHard (self ) -> None :
60110 if isinstance (Signal ._handler , Signal ):
61111 return Signal ._handler ._check (True )
62- @classmethod
63112 def sleep (self , seconds :Union [int , float ], raiseOnKill :bool = False ) -> None :
64113 if isinstance (Signal ._handler , Signal ):
65114 return Signal ._handler ._sleep (seconds , raiseOnKill , self ._force )
66115 return sleep (seconds )
67- @classmethod
68116 def signalSoftKill (self , * args :Any , ** kwargs :Any ) -> None :
69117 if isinstance (Signal ._handler , Signal ):
70118 return Signal ._handler ._signalSoftKill (* args , ** kwargs )
71- @classmethod
72119 def signalHardKill (self , * args :Any , ** kwargs :Any ) -> None :
73120 if isinstance (Signal ._handler , Signal ):
74121 return Signal ._handler ._signalHardKill (* args , ** kwargs )
75- @classmethod
76122 def iter (self , it :Iterable [Any ], checkDelay :float = 1.0 ) -> Iterable [Any ]:
77123 if isinstance (Signal ._handler , Signal ):
78124 return Signal ._handler ._iter (it , checkDelay , self ._force )
79125 return it
80- @classmethod
81126 def softKill (self ) -> None :
82127 if isinstance (Signal ._handler , Signal ):
83128 return Signal ._handler ._softKill ()
84- @classmethod
85129 def hardKill (self ) -> None :
86130 if isinstance (Signal ._handler , Signal ):
87131 return Signal ._handler ._hardKill ()
88- @classmethod
89132 def reset (self ) -> None :
90133 if isinstance (Signal ._handler , Signal ):
91134 return Signal ._handler ._reset ()
92- @classmethod
93- def getSoftSignal (self ) -> Type [BaseSignal ]:
94- return SoftSignal
95- @classmethod
96- def getHardSignal (self ) -> Type [BaseSignal ]:
97- return HardSignal
98- @classmethod
135+ def getSoftSignal (self ) -> T_Signal :
136+ return SoftSignal ()
137+ def getHardSignal (self ) -> T_Signal :
138+ return HardSignal ()
99139 def isActivated (self ) -> bool :
100140 return isinstance (Signal ._handler , Signal )
141+ def warpLock (self , lock :Any ) -> T_Locker :
142+ if isinstance (Signal ._handler , Signal ):
143+ return Signal ._handler ._warpLock (lock , self ._force )
144+ return ExtendedLocker (lock )
101145
102146class SoftSignal (BaseSignal ):
103147 _force :bool = False
@@ -143,8 +187,8 @@ def __setstate__(self, states:Dict[str, Any]) -> None:
143187 self .eHard = states ["eHard" ]
144188 self ._activate ()
145189 def _activate (self ) -> None :
146- _signal .signal (_signal .SIGINT , Signal .signalSoftKill )
147- _signal .signal (_signal .SIGTERM , Signal .signalHardKill )
190+ _signal .signal (_signal .SIGINT , self .signalSoftKill )
191+ _signal .signal (_signal .SIGTERM , self .signalHardKill )
148192 def _get (self , force :bool = True ) -> bool :
149193 if force :
150194 return self .eHard .is_set ()
@@ -159,6 +203,8 @@ def _sleep(self, seconds:Union[int, float], raiseOnKill:bool=False, force:bool=T
159203 return None
160204 def _iter (self , it :Iterable [Any ], checkDelay :float = 1.0 , force :bool = True ) -> Iterator [Any ]:
161205 return SignalIterator (self .eHard if force else self .eSoft , it , checkDelay )
206+ def _warpLock (self , lock :Any , force :bool = True ) -> T_Locker :
207+ return SignalLocker (self .eHard if force else self .eSoft , cast (T_Lock , lock ))
162208 def _signalSoftKill (self , * args :Any , ** kwargs :Any ) -> None :
163209 self ._softKill ()
164210 if not self .eHard .is_set ():
@@ -193,5 +239,3 @@ def _reset(self) -> None:
193239 self .eSoft .clear ()
194240 self .eHard .clear ()
195241 self .counter = 0
196-
197- T_Signal = Union [Signal , Type [BaseSignal ]]
0 commit comments