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.