Skip to content

Commit 2dd31fd

Browse files
+ yielding on kill method
1 parent f3ec68f commit 2dd31fd

File tree

1 file changed

+38
-6
lines changed

1 file changed

+38
-6
lines changed

src/thread/thread.py

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import os
12
import sys
3+
import time
24
import signal
35
import threading
46

@@ -13,7 +15,16 @@
1315
)
1416

1517

16-
ThreadStatus = Literal['Idle', 'Running', 'Invoking hooks', 'Completed', 'Errored', 'Killed']
18+
ThreadStatus = Literal[
19+
'Idle',
20+
'Running',
21+
'Invoking hooks',
22+
'Completed',
23+
24+
'Errored',
25+
'Kill Scheduled',
26+
'Killed'
27+
]
1728
Data_In = Any
1829
Data_Out = Any
1930
Overflow_In = Any
@@ -143,9 +154,10 @@ def global_trace(self, frame, event: str, arg) -> Callable | None:
143154
if event == 'call':
144155
return self.local_trace
145156

146-
def local_trace(self, frame, event, arg):
147-
if self.status == 'Killed' and event == 'line':
157+
def local_trace(self, frame, event: str, arg):
158+
if self.status == 'Kill Scheduled' and event == 'line':
148159
print('KILLED ident:%s' % self.ident)
160+
self.status = 'Killed'
149161
raise SystemExit()
150162
return self.local_trace
151163

@@ -248,9 +260,18 @@ def get_return_value(self) -> Data_Out:
248260
return self.result
249261

250262

251-
def kill(self) -> None:
263+
def kill(self, yielding: bool = False, timeout: float = 5) -> bool:
252264
"""
253-
Kills the thread
265+
Schedules a thread to be killed
266+
267+
Parameters
268+
----------
269+
:param yielding: If true, halts the current thread execution until the thread is killed
270+
:param timeout: The maximum number of seconds to wait before exiting
271+
272+
Returns
273+
-------
274+
:returns bool: False if the it exceeded the timeout
254275
255276
Raises
256277
------
@@ -259,7 +280,18 @@ def kill(self) -> None:
259280
"""
260281
if not self.is_alive():
261282
raise exceptions.ThreadNotRunningError()
262-
self.status = 'Killed'
283+
284+
self.status = 'Kill Scheduled'
285+
if not yielding:
286+
return True
287+
288+
start = time.perf_counter()
289+
while self.status != 'Killed':
290+
time.sleep(0.01)
291+
if (time.perf_counter() - start) >= timeout:
292+
return False
293+
294+
return True
263295

264296

265297
def start(self) -> None:

0 commit comments

Comments
 (0)