|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| import logging
|
| import os
|
|
|
| from math_verify.errors import TimeoutException
|
|
|
| TIMEOUT_WARNING_SHOWN = False
|
| logger = logging.getLogger(__name__)
|
|
|
|
|
| def timeout(timeout_seconds: int | None = 10):
|
| """A decorator that applies a timeout to the decorated function.
|
|
|
| Args:
|
| timeout_seconds (int): Number of seconds before timing out the decorated function.
|
| Defaults to 10 seconds.
|
|
|
| Notes:
|
| On Unix systems, uses a signal-based alarm approach which is more efficient as it doesn't require spawning a new process.
|
| On Windows systems, uses a multiprocessing-based approach since signal.alarm is not available. This will incur a huge performance penalty.
|
| """
|
| if timeout_seconds is None or timeout_seconds <= 0:
|
|
|
| def no_timeout_decorator(func):
|
| return func
|
|
|
| return no_timeout_decorator
|
|
|
| if os.name == "posix":
|
|
|
| import signal
|
|
|
| def decorator(func):
|
| def handler(signum, frame):
|
| raise TimeoutException("Operation timed out!")
|
|
|
| def wrapper(*args, **kwargs):
|
| old_handler = signal.getsignal(signal.SIGALRM)
|
| signal.signal(signal.SIGALRM, handler)
|
| signal.alarm(timeout_seconds)
|
| try:
|
| return func(*args, **kwargs)
|
| finally:
|
|
|
| signal.alarm(0)
|
| signal.signal(signal.SIGALRM, old_handler)
|
|
|
| return wrapper
|
|
|
| return decorator
|
|
|
| else:
|
|
|
| from multiprocessing import Process, Queue
|
|
|
| def decorator(func):
|
| def wrapper(*args, **kwargs):
|
| q = Queue()
|
|
|
| def run_func(q, args, kwargs):
|
| try:
|
| result = func(*args, **kwargs)
|
| q.put((True, result))
|
| except Exception as e:
|
| q.put((False, e))
|
|
|
| p = Process(target=run_func, args=(q, args, kwargs))
|
| p.start()
|
| p.join(timeout_seconds)
|
|
|
| if p.is_alive():
|
|
|
| p.terminate()
|
| p.join()
|
| raise TimeoutException("Operation timed out!")
|
|
|
|
|
| success, value = q.get()
|
| if success:
|
| return value
|
| else:
|
|
|
| raise value
|
|
|
| return wrapper
|
|
|
| return decorator
|
|
|