3
3
import traceback , signal as _signal
4
4
from threading import Event
5
5
from 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
7
7
# Third party modules
8
8
# Local modules
9
+ from .abcs import T_Signal , T_Locker , T_Lock
9
10
# Program
10
11
class KillSignal (Exception ): pass
11
12
@@ -30,74 +31,117 @@ def __next__(self) -> Any:
30
31
raise KillSignal
31
32
return self .it .__next__ ()
32
33
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 ):
36
91
def get (self ) -> bool :
37
92
if isinstance (Signal ._handler , Signal ):
38
93
return Signal ._handler ._get (self ._force )
39
94
return False
40
- @classmethod
41
95
def getSoft (self ) -> bool :
42
96
if isinstance (Signal ._handler , Signal ):
43
97
return Signal ._handler ._get (False )
44
98
return False
45
- @classmethod
46
99
def getHard (self ) -> bool :
47
100
if isinstance (Signal ._handler , Signal ):
48
101
return Signal ._handler ._get (True )
49
102
return False
50
- @classmethod
51
103
def check (self ) -> None :
52
104
if isinstance (Signal ._handler , Signal ):
53
105
return Signal ._handler ._check (self ._force )
54
- @classmethod
55
106
def checkSoft (self ) -> None :
56
107
if isinstance (Signal ._handler , Signal ):
57
108
return Signal ._handler ._check (False )
58
- @classmethod
59
109
def checkHard (self ) -> None :
60
110
if isinstance (Signal ._handler , Signal ):
61
111
return Signal ._handler ._check (True )
62
- @classmethod
63
112
def sleep (self , seconds :Union [int , float ], raiseOnKill :bool = False ) -> None :
64
113
if isinstance (Signal ._handler , Signal ):
65
114
return Signal ._handler ._sleep (seconds , raiseOnKill , self ._force )
66
115
return sleep (seconds )
67
- @classmethod
68
116
def signalSoftKill (self , * args :Any , ** kwargs :Any ) -> None :
69
117
if isinstance (Signal ._handler , Signal ):
70
118
return Signal ._handler ._signalSoftKill (* args , ** kwargs )
71
- @classmethod
72
119
def signalHardKill (self , * args :Any , ** kwargs :Any ) -> None :
73
120
if isinstance (Signal ._handler , Signal ):
74
121
return Signal ._handler ._signalHardKill (* args , ** kwargs )
75
- @classmethod
76
122
def iter (self , it :Iterable [Any ], checkDelay :float = 1.0 ) -> Iterable [Any ]:
77
123
if isinstance (Signal ._handler , Signal ):
78
124
return Signal ._handler ._iter (it , checkDelay , self ._force )
79
125
return it
80
- @classmethod
81
126
def softKill (self ) -> None :
82
127
if isinstance (Signal ._handler , Signal ):
83
128
return Signal ._handler ._softKill ()
84
- @classmethod
85
129
def hardKill (self ) -> None :
86
130
if isinstance (Signal ._handler , Signal ):
87
131
return Signal ._handler ._hardKill ()
88
- @classmethod
89
132
def reset (self ) -> None :
90
133
if isinstance (Signal ._handler , Signal ):
91
134
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 ()
99
139
def isActivated (self ) -> bool :
100
140
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 )
101
145
102
146
class SoftSignal (BaseSignal ):
103
147
_force :bool = False
@@ -143,8 +187,8 @@ def __setstate__(self, states:Dict[str, Any]) -> None:
143
187
self .eHard = states ["eHard" ]
144
188
self ._activate ()
145
189
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 )
148
192
def _get (self , force :bool = True ) -> bool :
149
193
if force :
150
194
return self .eHard .is_set ()
@@ -159,6 +203,8 @@ def _sleep(self, seconds:Union[int, float], raiseOnKill:bool=False, force:bool=T
159
203
return None
160
204
def _iter (self , it :Iterable [Any ], checkDelay :float = 1.0 , force :bool = True ) -> Iterator [Any ]:
161
205
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 ))
162
208
def _signalSoftKill (self , * args :Any , ** kwargs :Any ) -> None :
163
209
self ._softKill ()
164
210
if not self .eHard .is_set ():
@@ -193,5 +239,3 @@ def _reset(self) -> None:
193
239
self .eSoft .clear ()
194
240
self .eHard .clear ()
195
241
self .counter = 0
196
-
197
- T_Signal = Union [Signal , Type [BaseSignal ]]
0 commit comments