Add missing files

This commit is contained in:
Tim Savannah 2016-03-18 14:03:48 -04:00
parent a8e096d528
commit ecef734547
3 changed files with 99 additions and 0 deletions

View File

@ -0,0 +1,35 @@
import ctypes
import threading
import time
class StoppableThread(threading.Thread):
'''
StoppableThread - A thread that can be stopped by forcing an exception in the execution context.
'''
def _stopThread(self, exception):
if self.isAlive() is False:
return True
joinThread = JoinThread(self, exception)
joinThread.start()
class JoinThread(threading.Thread):
'''
JoinThread - The workhouse that stops the StoppableThread
'''
def __init__(self, otherThread, exception):
threading.Thread.__init__(self)
self.otherThread = otherThread
self.exception = exception
self.daemon = True
def run(self):
while self.otherThread.isAlive():
# We loop raising exception incase it's caught hopefully this breaks us far out.
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(self.otherThread.ident), ctypes.py_object(self.exception))
self.otherThread.join(2)

60
func_timeout/dafunc.py Normal file
View File

@ -0,0 +1,60 @@
import threading
import time
from .exceptions import FunctionTimedOut
from .StoppableThread import StoppableThread
def func_timeout(timeout, func, args=(), kwargs=None):
'''
func_timeout - Runs the given function for up to #timeout# seconds.
Raises any exceptions #func# would raise, returns what #func# would return (unless timeout is exceeded), in which case it raises FunctionTimedOut
@param timeout <float> - Maximum number of seconds to run #func# before terminating
@param func <function> - The function to call
@param args <tuple> - Any ordered arguments to pass to the function
@param kwargs <dict/None> - Keyword arguments to pass to the function.
@raises - FunctionTimedOut if #timeout# is exceeded, otherwise anything #func# could raise will be raised
@return - The return value that #func# gives
'''
if not kwargs:
kwargs = {}
if not args:
args = ()
ret = []
exception = []
isStopped = False
def funcwrap(args2, kwargs2):
try:
ret.append( func(*args2, **kwargs2) )
except Exception as e:
if isStopped is False:
# Don't capture stopping exception
exception.append(e)
thread = StoppableThread(target=funcwrap, args=(args, kwargs))
thread.daemon = True
thread.start()
thread.join(timeout)
stopException = None
if thread.isAlive():
isStopped = True
stopException = FunctionTimedOut('Function %s (args=%s) (kwargs=%s) timed out after %f seconds.\n' %(func.__name__, str(args), str(kwargs), timeout))
thread._stopThread(stopException)
thread.join(.1)
raise stopException
if exception:
raise exception[0]
if ret:
return ret[0]

View File

@ -0,0 +1,4 @@
class FunctionTimedOut(Exception):
pass