src/Pure/Concurrent/timeout.ML
changeset 74870 d54b3c96ee50
parent 73388 a40e69fde2b4
child 78648 852ec09aef13
equal deleted inserted replaced
74850:c5ce1e2f26ab 74870:d54b3c96ee50
    12   val ignored: Time.time -> bool
    12   val ignored: Time.time -> bool
    13   val scale: unit -> real
    13   val scale: unit -> real
    14   val scale_time: Time.time -> Time.time
    14   val scale_time: Time.time -> Time.time
    15   val end_time: Time.time -> Time.time
    15   val end_time: Time.time -> Time.time
    16   val apply: Time.time -> ('a -> 'b) -> 'a -> 'b
    16   val apply: Time.time -> ('a -> 'b) -> 'a -> 'b
       
    17   val apply_physical: Time.time -> ('a -> 'b) -> 'a -> 'b
    17   val print: Time.time -> string
    18   val print: Time.time -> string
    18 end;
    19 end;
    19 
    20 
    20 structure Timeout: TIMEOUT =
    21 structure Timeout: TIMEOUT =
    21 struct
    22 struct
    27 fun scale () = Options.default_real "timeout_scale";
    28 fun scale () = Options.default_real "timeout_scale";
    28 fun scale_time t = Time.scale (scale ()) t;
    29 fun scale_time t = Time.scale (scale ()) t;
    29 
    30 
    30 fun end_time timeout = Time.now () + scale_time timeout;
    31 fun end_time timeout = Time.now () + scale_time timeout;
    31 
    32 
    32 fun apply timeout f x =
    33 fun apply' {physical, timeout} f x =
    33   if ignored timeout then f x
    34   if ignored timeout then f x
    34   else
    35   else
    35     Thread_Attributes.with_attributes Thread_Attributes.no_interrupts (fn orig_atts =>
    36     Thread_Attributes.with_attributes Thread_Attributes.no_interrupts (fn orig_atts =>
    36       let
    37       let
    37         val self = Thread.self ();
    38         val self = Thread.self ();
    38         val start = Time.now ();
    39         val start = Time.now ();
    39 
    40 
    40         val request =
    41         val request =
    41           Event_Timer.request {physical = false} (start + scale_time timeout)
    42           Event_Timer.request {physical = physical} (start + scale_time timeout)
    42             (fn () => Isabelle_Thread.interrupt_unsynchronized self);
    43             (fn () => Isabelle_Thread.interrupt_unsynchronized self);
    43         val result =
    44         val result =
    44           Exn.capture (fn () => Thread_Attributes.with_attributes orig_atts (fn _ => f x)) ();
    45           Exn.capture (fn () => Thread_Attributes.with_attributes orig_atts (fn _ => f x)) ();
    45 
    46 
    46         val stop = Time.now ();
    47         val stop = Time.now ();
    50         if was_timeout andalso (Exn.is_interrupt_exn result orelse Exn.is_interrupt_exn test)
    51         if was_timeout andalso (Exn.is_interrupt_exn result orelse Exn.is_interrupt_exn test)
    51         then raise TIMEOUT (stop - start)
    52         then raise TIMEOUT (stop - start)
    52         else (Exn.release test; Exn.release result)
    53         else (Exn.release test; Exn.release result)
    53       end);
    54       end);
    54 
    55 
       
    56 fun apply timeout f x = apply' {physical = false, timeout = timeout} f x;
       
    57 fun apply_physical timeout f x = apply' {physical = true, timeout = timeout} f x;
       
    58 
    55 fun print t = "Timeout after " ^ Value.print_time t ^ "s";
    59 fun print t = "Timeout after " ^ Value.print_time t ^ "s";
    56 
    60 
    57 end;
    61 end;