thread_exception.py
Go to the documentation of this file.
00001 def _async_raise(tid, exctype):
00002     '''Raises an exception in the threads with id tid'''
00003     if not inspect.isclass(exctype):
00004         raise TypeError("Only types can be raised (not instances)")
00005     res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
00006                                                   ctypes.py_object(exctype))
00007     if res == 0:
00008         raise ValueError("invalid thread id")
00009     elif res != 1:
00010         # "if it returns a number greater than one, you're in trouble,
00011         # and you should call it again with exc=NULL to revert the effect"
00012         ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
00013         raise SystemError("PyThreadState_SetAsyncExc failed")
00014 
00015 class ThreadWithExc(threading.Thread):
00016     '''A thread class that supports raising exception in the thread from
00017        another thread.
00018     '''
00019     def _get_my_tid(self):
00020         """determines this (self's) thread id
00021 
00022         CAREFUL : this function is executed in the context of the caller
00023         thread, to get the identity of the thread represented by this
00024         instance.
00025         """
00026         if not self.isAlive():
00027             raise threading.ThreadError("the thread is not active")
00028 
00029         # do we have it cached?
00030         if hasattr(self, "_thread_id"):
00031             return self._thread_id
00032 
00033         # no, look for it in the _active dict
00034         for tid, tobj in threading._active.items():
00035             if tobj is self:
00036                 self._thread_id = tid
00037                 return tid
00038 
00039         # TODO: in python 2.6, there's a simpler way to do : self.ident
00040 
00041         raise AssertionError("could not determine the thread's id")
00042 
00043     def raiseExc(self, exctype):
00044         """Raises the given exception type in the context of this thread.
00045 
00046         If the thread is busy in a system call (time.sleep(),
00047         socket.accept(), ...), the exception is simply ignored.
00048 
00049         If you are sure that your exception should terminate the thread,
00050         one way to ensure that it works is:
00051 
00052             t = ThreadWithExc( ... )
00053             ...
00054             t.raiseExc( SomeException )
00055             while t.isAlive():
00056                 time.sleep( 0.1 )
00057                 t.raiseExc( SomeException )
00058 
00059         If the exception is to be caught by the thread, you need a way to
00060         check that your thread has caught it.
00061 
00062         CAREFUL : this function is executed in the context of the
00063         caller thread, to raise an excpetion in the context of the
00064         thread represented by this instance.
00065         """
00066         _async_raise( self._get_my_tid(), exctype )


rcommander
Author(s): Hai Nguyen (haidai@gmail.com)
autogenerated on Thu Nov 28 2013 11:46:34