@@ -102,24 +102,27 @@ def tmp_app_path(self):
102
102
return self ._tmp_app_path
103
103
104
104
105
- class StoppableThread (threading .Thread ):
106
- def get_id (self ): # pylint: disable=R1710
107
- if hasattr (self , "_thread_id" ):
108
- return self ._thread_id
109
- for thread_id , thread in threading ._active .items (): # pylint: disable=W0212
110
- if thread is self :
111
- return thread_id
105
+ class KillerThread (threading .Thread ):
106
+ def __init__ (self , ** kwargs ):
107
+ super ().__init__ (** kwargs )
108
+ self ._old_threads = list (threading ._active .keys ()) # pylint: disable=W0212
112
109
113
110
def kill (self ):
114
- thread_id = self .get_id ()
115
- res = ctypes .pythonapi .PyThreadState_SetAsyncExc (
116
- ctypes .c_long (thread_id ), ctypes .py_object (SystemExit )
117
- )
118
- if res == 0 :
119
- raise ValueError (f"Invalid thread id: { thread_id } " )
120
- if res > 1 :
121
- ctypes .pythonapi .PyThreadState_SetAsyncExc (ctypes .c_long (thread_id ), None )
122
- raise SystemExit ("Stopping thread failure" )
111
+ # Kill all the new threads.
112
+ for thread_id in threading ._active : # pylint: disable=W0212
113
+ if thread_id in self ._old_threads :
114
+ continue
115
+
116
+ res = ctypes .pythonapi .PyThreadState_SetAsyncExc (
117
+ ctypes .c_long (thread_id ), ctypes .py_object (SystemExit )
118
+ )
119
+ if res == 0 :
120
+ raise ValueError (f"Invalid thread id: { thread_id } " )
121
+ if res > 1 :
122
+ ctypes .pythonapi .PyThreadState_SetAsyncExc (
123
+ ctypes .c_long (thread_id ), None
124
+ )
125
+ raise SystemExit ("Stopping thread failure" )
123
126
124
127
125
128
class ThreadedRunner (BaseDashRunner ):
@@ -154,7 +157,7 @@ def run():
154
157
except SystemExit :
155
158
logger .info ("Server stopped" )
156
159
157
- self .thread = StoppableThread (target = run )
160
+ self .thread = KillerThread (target = run )
158
161
self .thread .daemon = True
159
162
try :
160
163
self .thread .start ()
0 commit comments