| 1 | """ |
|---|
| 2 | Kill a thread, from http://sebulba.wikispaces.com/recipe+thread2 |
|---|
| 3 | """ |
|---|
| 4 | import types |
|---|
| 5 | try: |
|---|
| 6 | import ctypes |
|---|
| 7 | except ImportError: |
|---|
| 8 | raise ImportError( |
|---|
| 9 | "You cannot use paste.util.killthread without ctypes installed") |
|---|
| 10 | |
|---|
| 11 | def async_raise(tid, exctype): |
|---|
| 12 | """raises the exception, performs cleanup if needed. |
|---|
| 13 | |
|---|
| 14 | tid is the value given by thread.get_ident() (an integer). |
|---|
| 15 | Raise SystemExit to kill a thread.""" |
|---|
| 16 | if not isinstance(exctype, (types.ClassType, type)): |
|---|
| 17 | raise TypeError("Only types can be raised (not instances)") |
|---|
| 18 | if not isinstance(tid, int): |
|---|
| 19 | raise TypeError("tid must be an integer") |
|---|
| 20 | res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype)) |
|---|
| 21 | if res == 0: |
|---|
| 22 | raise ValueError("invalid thread id") |
|---|
| 23 | elif res != 1: |
|---|
| 24 | # """if it returns a number greater than one, you're in trouble, |
|---|
| 25 | # and you should call it again with exc=NULL to revert the effect""" |
|---|
| 26 | ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0) |
|---|
| 27 | raise SystemError("PyThreadState_SetAsyncExc failed") |
|---|