From f3e4148511643afb5a7dbeed4be8ec693430732b Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Thu, 21 May 2009 00:39:57 -0500 Subject: [PATCH] fix bad behavior of time_out by making sure interrupts are disabled during critical operation, up to setting a throw. --- library/timeout.yap | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/library/timeout.yap b/library/timeout.yap index 607e73f20..c821f06d9 100644 --- a/library/timeout.yap +++ b/library/timeout.yap @@ -24,15 +24,38 @@ % % not the nicest program I've ever seen. % +% +% I cannot use setup_call_cleanup because I can only take interrupts *after* I set up +% the catcher, so I have to do the dirty deed myself. +% time_out(Goal, Time, Result) :- T is Time//1000, UT is (Time mod 1000)*1000, + yap_hacks:disable_interrupts, % enable alarm alarm(T.UT,throw(time_out),_), % launch goal and wait for signal - call_cleanup( - catch( ( Result0 = success, once(Goal) ), - time_out, - Result0 = time_out ), - alarm(0,_,_) ), + catch( run_goal(Goal, Result0), + time_out, + Result0 = time_out ), Result = Result0. + +run_goal(Goal, Result0) :- + % we can only enable interrupts after alarm was been enabled. + yap_hacks:enable_interrupts, + Result0 = success, + call(Goal), + !, + % make sure we're not getting an extraneous interrupt if we terminate early.... + yap_hacks:disable_interrupts. + alarm(0,_,_), + true. +run_goal(Goal, Result0) :- + yap_hacks:disable_interrupts, + % make sure we're not getting an extraneous interrupt if we terminate early.... + alarm(0,_,_), + fail. + +complete_time_out :- + alarm(0,_,_), + yap_hacks:enable_interrupts.