fix bad behavior of time_out by making sure interrupts are disabled during critical operation, up

to setting a throw.
This commit is contained in:
Vitor Santos Costa 2009-05-21 00:39:57 -05:00
parent c3974d49eb
commit f3e4148511
1 changed files with 28 additions and 5 deletions

View File

@ -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.