Change implementation of timing out to not leave lingering threads
This commit is contained in:
parent
edfc9b8d4a
commit
a8e096d528
@ -1,3 +1,6 @@
|
|||||||
|
* 2.0.0 - Mar 18 2016
|
||||||
|
- Change implementation to not leave lingering threads after a timeout occurs
|
||||||
|
|
||||||
* 1.0.1 - Mar 15 2016
|
* 1.0.1 - Mar 15 2016
|
||||||
- Remove debugging print
|
- Remove debugging print
|
||||||
- Note that it has been explicitly tested on 2.7, 3.4, and 3.5 in README.
|
- Note that it has been explicitly tested on 2.7, 3.4, and 3.5 in README.
|
||||||
|
|||||||
@ -5,73 +5,11 @@
|
|||||||
LICENSE, otherwise it is available at https://github.com/kata198/func_timeout/LICENSE
|
LICENSE, otherwise it is available at https://github.com/kata198/func_timeout/LICENSE
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import threading
|
|
||||||
import time
|
|
||||||
|
|
||||||
__version__ = '1.0.1'
|
__version__ = '2.0.0'
|
||||||
__version_tuple__ = (1, 0, 1)
|
__version_tuple__ = (2, 0, 0)
|
||||||
|
|
||||||
__all__ = ('func_timeout', 'FunctionTimedOut')
|
__all__ = ('func_timeout', 'FunctionTimedOut')
|
||||||
|
|
||||||
def func_timeout(timeout, func, args=(), kwargs=None):
|
from .exceptions import FunctionTimedOut
|
||||||
'''
|
from .dafunc import func_timeout
|
||||||
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 = []
|
|
||||||
|
|
||||||
def funcwrap(args2, kwargs2):
|
|
||||||
try:
|
|
||||||
ret.append( func(*args2, **kwargs2) )
|
|
||||||
except Exception as e:
|
|
||||||
exception.append(e)
|
|
||||||
|
|
||||||
thread = threading.Thread(target=funcwrap, args=(args, kwargs))
|
|
||||||
|
|
||||||
thread.start()
|
|
||||||
thread.join(timeout)
|
|
||||||
|
|
||||||
if thread.isAlive():
|
|
||||||
doRaiseCantStop = False
|
|
||||||
thread.isDaemon = True
|
|
||||||
try:
|
|
||||||
if hasattr(thread, '_tstate_lock'):
|
|
||||||
# 3.5
|
|
||||||
thread._tstate_lock.release()
|
|
||||||
elif hasattr(thread, '_Thread__stop'):
|
|
||||||
# 2.7
|
|
||||||
thread._Thread__stop()
|
|
||||||
else:
|
|
||||||
doRaiseCantStop = True
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
if doRaiseCantStop is True:
|
|
||||||
raise NotImplementedError('function timeouts not supported on this system.\n')
|
|
||||||
|
|
||||||
if exception:
|
|
||||||
raise exception[0]
|
|
||||||
|
|
||||||
if ret:
|
|
||||||
return ret[0]
|
|
||||||
|
|
||||||
raise FunctionTimedOut('Function %s (args=%s) (kwargs=%s) timed out after %f seconds.\n' %(func.__name__, str(args), str(kwargs), timeout))
|
|
||||||
|
|
||||||
class FunctionTimedOut(Exception):
|
|
||||||
pass
|
|
||||||
|
|||||||
2
setup.py
2
setup.py
@ -30,7 +30,7 @@ if __name__ == '__main__':
|
|||||||
log_description = summary
|
log_description = summary
|
||||||
|
|
||||||
setup(name='func_timeout',
|
setup(name='func_timeout',
|
||||||
version='1.0.1',
|
version='2.0.0',
|
||||||
packages=['func_timeout'],
|
packages=['func_timeout'],
|
||||||
author='Tim Savannah',
|
author='Tim Savannah',
|
||||||
author_email='kata198@gmail.com',
|
author_email='kata198@gmail.com',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user