diff --git a/src/commands.py b/src/commands.py index 45531d322..f1ec2ded6 100644 --- a/src/commands.py +++ b/src/commands.py @@ -69,6 +69,43 @@ def thread(f): f(self, irc, msg, args, *L, **kwargs) return utils.python.changeFunctionName(newf, f.func_name, f.__doc__) +class ProcessTimeoutError(Exception): + """Gets raised when a process is killed due to timeout.""" + pass + +def process(f, *args, **kwargs): + """Runs a function in a subprocess. + + Several extra keyword arguments can be supplied. + , the pluginname, and , the command name, are strings used to + create the process name, for identification purposes. + , if supplied, limits the length of execution of target + function to seconds.""" + timeout = kwargs.pop('timeout', None) + + q = multiprocessing.Queue() + def newf(f, q, *args, **kwargs): + try: + r = f(*args, **kwargs) + q.put(r) + except Exception as e: + q.put(e) + targetArgs = (f, q,) + args + p = callbacks.CommandProcess(target=newf, + args=targetArgs, kwargs=kwargs) + p.start() + p.join(timeout) + if p.is_alive(): + p.terminate() + raise ProcessTimeoutError, "%s aborted due to timeout." % (p.name,) + try: + v = q.get(block=False) + except Queue.Empty: + v = "Nothing returned." + if isinstance(v, Exception): + v = "Error: " + str(v) + return v + class UrlSnarfThread(world.SupyThread): def __init__(self, *args, **kwargs): assert 'url' in kwargs diff --git a/src/version.py b/src/version.py index c61e38303..1915fcd35 100644 --- a/src/version.py +++ b/src/version.py @@ -1,3 +1,3 @@ """stick the various versioning attributes in here, so we only have to change them once.""" -version = '0.83.4.1+limnoria (2011-08-12T18:51:40+0200)' +version = '0.83.4.1+limnoria (2011-08-13T01:53:58+0200)'