1 """Multiprocessing utilities.
2 """
3 """
4 ============================== License ========================================
5 Copyright (C) 2008, 2010-12 University of Edinburgh, Mark Granroth-Wilding
6
7 This file is part of The Jazz Parser.
8
9 The Jazz Parser is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 The Jazz Parser is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with The Jazz Parser. If not, see <http://www.gnu.org/licenses/>.
21
22 ============================ End license ======================================
23
24 """
25 __author__ = "Mark Granroth-Wilding <mark.granroth-wilding@ed.ac.uk>"
26
27 from multiprocessing import TimeoutError
28 from threading import Thread
29
33
35 """
36 Decorator that applies a function with the given args and kwargs,
37 enforcing a timeout. Blocks until the function completes or the
38 timeout expires. If the timeout expires, raises a TimeoutError.
39
40 The intended use of this is to submit a job to a multiprocessing
41 pool with a timeout, after which the whole processing terminates.
42 This only makes sense if you have just one task per process or
43 set C{maxtasksperchild=1} on the pool.
44
45 @note: the function execution does not actually halt when the
46 exception is raised, but continues in another thread. There is
47 no way to terminate this thread from outside it.
48
49 """
50 result = Result()
51 timeout_length = kwargs.pop('timeout', 60)
52 def _get_target():
53
54 def _target(*args, **kwargs):
55 result.result = fun(*args, **kwargs)
56 return _target
57
58
59 runner = Thread(target=_get_target(), args=args, kwargs=kwargs)
60
61 runner.start()
62 runner.join(timeout_length)
63 if runner.is_alive():
64
65 raise TimeoutError, "call to %s timed out (%s secs)" % (fun,timeout_length)
66 else:
67 return result.result
68