src/Pure/Concurrent/par_exn.ML
changeset 44249 64620f1d6f87
parent 44248 6a3541412b23
child 44264 c21ecbb028b6
equal deleted inserted replaced
44248:6a3541412b23 44249:64620f1d6f87
     5 evaluations.  Interrupt counts as neutral element.
     5 evaluations.  Interrupt counts as neutral element.
     6 *)
     6 *)
     7 
     7 
     8 signature PAR_EXN =
     8 signature PAR_EXN =
     9 sig
     9 sig
       
    10   val serial: exn -> serial * exn
    10   val make: exn list -> exn
    11   val make: exn list -> exn
    11   val dest: exn -> (serial * exn) list option
    12   val dest: exn -> exn list option
    12   val release_all: 'a Exn.result list -> 'a list
    13   val release_all: 'a Exn.result list -> 'a list
    13   val release_first: 'a Exn.result list -> 'a list
    14   val release_first: 'a Exn.result list -> 'a list
    14 end;
    15 end;
    15 
    16 
    16 structure Par_Exn =
    17 structure Par_Exn =
    17 struct
    18 struct
    18 
    19 
       
    20 (* identification via serial numbers *)
       
    21 
       
    22 fun serial exn =
       
    23   (case get_exn_serial exn of
       
    24     SOME i => (i, exn)
       
    25   | NONE => let val i = Library.serial () in (i, set_exn_serial i exn) end);
       
    26 
       
    27 val exn_ord = rev_order o int_ord o pairself (the o get_exn_serial);
       
    28 
       
    29 
    19 (* parallel exceptions *)
    30 (* parallel exceptions *)
    20 
    31 
    21 exception Par_Exn of (serial * exn) Ord_List.T;
    32 exception Par_Exn of exn Ord_List.T;
    22 
       
    23 fun exn_ord ((i, _), (j, _)) = int_ord (j, i);
       
    24 
    33 
    25 fun par_exns (Par_Exn exns) = SOME exns
    34 fun par_exns (Par_Exn exns) = SOME exns
    26   | par_exns exn = if Exn.is_interrupt exn then NONE else SOME [(serial (), exn)];
    35   | par_exns exn = if Exn.is_interrupt exn then NONE else SOME [#2 (serial exn)];
    27 
    36 
    28 fun make exns =
    37 fun make exns =
    29   (case map_filter par_exns exns of
    38   (case map_filter par_exns exns of
    30     [] => Exn.Interrupt
    39     [] => Exn.Interrupt
    31   | e :: es => Par_Exn (Library.foldl (Ord_List.merge exn_ord) (e, es)));
    40   | e :: es => Par_Exn (Library.foldl (Ord_List.merge exn_ord) (e, es)));