| 14849 |      1 | (*  Title:      Pure/ML-Systems/polyml-time-limit.ML
 | 
|  |      2 |     ID:         $Id$
 | 
|  |      3 |     Author:     Tjark Weber
 | 
|  |      4 |     Copyright   2004
 | 
|  |      5 | 
 | 
|  |      6 | Bounded time execution (similar to SML/NJ's TimeLimit structure) for Poly/ML.
 | 
|  |      7 | *)
 | 
|  |      8 | 
 | 
| 16993 |      9 | structure TimeLimit:
 | 
|  |     10 | sig
 | 
|  |     11 |   exception TimeOut
 | 
|  |     12 |   val timeLimit : Time.time -> ('a -> 'b) -> 'a -> 'b
 | 
|  |     13 | end =
 | 
|  |     14 | struct
 | 
|  |     15 |   exception TimeOut
 | 
| 14849 |     16 | 
 | 
| 16993 |     17 |   fun timeLimit t f x =
 | 
|  |     18 |     let
 | 
|  |     19 |       datatype ('a, 'b) union = INL of 'a | INR of 'b
 | 
|  |     20 |       val result = Process.channel ()
 | 
|  |     21 |       fun workerThread () =
 | 
|  |     22 |         Process.send (result, SOME (INL (f x) handle exn => INR exn))
 | 
|  |     23 |       val interrupt = Process.console workerThread
 | 
|  |     24 |       val old_handle = Signal.signal (Posix.Signal.alrm,
 | 
|  |     25 |         Signal.SIG_HANDLE (fn _ => (Process.send (result, NONE)) before (interrupt ())))
 | 
|  |     26 |     in
 | 
|  |     27 |       Posix.Process.alarm t;
 | 
|  |     28 |       case Process.receive result of
 | 
|  |     29 |         SOME (INL fx) =>
 | 
|  |     30 |           (Posix.Process.alarm Time.zeroTime; Signal.signal (Posix.Signal.alrm, old_handle); fx)
 | 
|  |     31 |       | SOME (INR exn) =>
 | 
|  |     32 |           (Posix.Process.alarm Time.zeroTime; Signal.signal (Posix.Signal.alrm, old_handle);
 | 
|  |     33 |            raise exn)
 | 
|  |     34 |       | NONE => (Signal.signal (Posix.Signal.alrm, old_handle); raise TimeOut)
 | 
|  |     35 |     end
 | 
| 14849 |     36 | 
 | 
|  |     37 | end;
 |