def _async_raise(tid, exctype):
"""raises the exception, performs cleanup if needed"""
if not inspect.isclass(exctype):
raise TypeError("Only types can be raised (not instances)")
if not issubclass(exctype, BaseException):
raise ValueError("Only sub classes of BaseException can be raised")
# PyThreadState_SetAsyncExc requires GIL to be held
gil_state = ctypes.pythonapi.PyGILState_Ensure()
try:
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid),
ctypes.py_object(exctype))
if res == 0:
# The thread is likely dead already.
raise InvalidThreadIdError(tid)
elif res != 1:
# If more than one threads are affected (WTF?), we're in trouble, and
# we try our best to revert the effect, although this may not work.
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), None)
raise AsyncRaiseError("PyThreadState_SetAsyncExc failed", res)
finally:
ctypes.pythonapi.PyGILState_Release(gil_state)
评论列表
文章目录