@@ -603,7 +603,8 @@ safe_apply(M, F, A) ->
603603% % concurrent tasks.</li>
604604% % <li>`Result' specifies the outcome of the attemp to serialize command
605605% % execution, based on the results observed. It can be one of the following:
606- % % <ul><li> `ok' </li><li> `no_possible_interleaving' </li></ul> </li>
606+ % % <ul><li> `ok' </li><li> `no_possible_interleaving' </li>
607+ % % <li> `{exception, Kind, Reason, StackTrace}' </li></ul> </li>
607608% % </ul>
608609
609610-spec run_parallel_commands (mod_name (), parallel_testcase ()) ->
@@ -622,28 +623,42 @@ run_parallel_commands(Mod, {Sequential, Parallel}, Env) ->
622623 case run (Mod , Sequential , Env ) of
623624 {{Seq_history , State , ok }, SeqEnv } ->
624625 F = fun (T ) -> execute (T , SeqEnv , Mod ) end ,
625- Parallel_history = pmap (F , Parallel ),
626+ case pmap (F , Parallel ) of
627+ {ok , Parallel_history } ->
626628 case check (Mod , State , SeqEnv , false , [], Parallel_history ) of
627629 true ->
628630 {Seq_history , Parallel_history , ok };
629631 false ->
630632 {Seq_history , Parallel_history , no_possible_interleaving }
631633 end ;
634+ {error , Exc , Parallel_history } ->
635+ {Seq_history , Parallel_history , Exc }
636+ end ;
632637 {{Seq_history , _ , Res }, _ } ->
633638 {Seq_history , [], Res }
634639 end .
635640
636641% % @private
637642-spec execute (command_list (), proper_symb :var_values (), mod_name ()) ->
638- parallel_history ().
639- execute ([], _Env , _Mod ) -> [];
640- execute ([{set , {var ,V }, {call ,M ,F ,A }} = Cmd |Rest ], Env , Mod ) ->
643+ {ok , parallel_history ()} | {error , any , parallel_history ()}.
644+ execute (Cmds , Env , Mod ) -> execute (Cmds , Env , Mod , []).
645+
646+ -spec execute (command_list (), proper_symb :var_values (), mod_name (),
647+ parallel_history ()) -> {ok , parallel_history ()} |
648+ {error , proper :exception (), parallel_history ()}.
649+ execute ([], _Env , _Mod , Hist ) -> {ok ,lists :reverse (Hist )};
650+ execute ([{set , {var ,V }, {call ,M ,F ,A }} = Cmd |Rest ], Env , Mod , Hist ) ->
641651 M2 = proper_symb :eval (Env , M ),
642652 F2 = proper_symb :eval (Env , F ),
643653 A2 = proper_symb :eval (Env , A ),
644- Res = apply (M2 , F2 , A2 ),
654+
655+ case safe_apply (M2 , F2 , A2 ) of
656+ {ok ,Res } ->
645657 Env2 = [{V ,Res }|Env ],
646- [{Cmd ,Res }|execute (Rest , Env2 , Mod )].
658+ execute (Rest , Env2 , Mod , [{Cmd ,Res }|Hist ]);
659+ {error , Exc } ->
660+ {error , Exc , lists :reverse (Hist )}
661+ end .
647662
648663-spec pmap (fun ((command_list ()) -> parallel_history ()), [command_list ()]) ->
649664 [parallel_history ()].
@@ -654,18 +669,28 @@ pmap(F, L) ->
654669 [command_list ()]) -> [pid ()].
655670spawn_jobs (F , L ) ->
656671 Parent = self (),
657- [spawn_link_cp (fun () -> Parent ! {self (),catch {ok ,F (X )}} end ) || X <- L ].
658-
659- -spec await ([pid ()]) -> [parallel_history ()].
660- await ([]) -> [];
661- await ([H |T ]) ->
672+ [spawn_link_cp (fun () -> Parent ! {self (), F (X )} end ) || X <- L ].
673+
674+ -spec await ([pid ()]) ->
675+ {ok , [parallel_history ()]} |
676+ {error , proper :exception (), [parallel_history ()]}.
677+ await (Pids ) -> await (Pids , [], false ).
678+
679+ -spec await ([pid ()], [parallel_history ()], false | proper :exception ()) ->
680+ {ok , [parallel_history ()]} |
681+ {error , proper :exception (), [parallel_history ()]}.
682+ await ([], Hist , false ) -> {ok , lists :reverse (Hist )};
683+ await ([], Hist , Exc ) -> {error , Exc , lists :reverse (Hist )};
684+ await ([H |T ], Hist , MaybeExc ) ->
662685 receive
663686 {H , {ok , Res }} ->
664- [Res |await (T )];
665- {H , {'EXIT' ,_ } = Err } ->
666- _ = [exit (Pid , kill ) || Pid <- T ],
667- _ = [receive {P ,_ } -> d_ after 0 -> i_ end || P <- T ],
668- erlang :error (Err )
687+ await (T , [Res |Hist ], MaybeExc );
688+ {H , {error , Exc , Res }} ->
689+ Exc2 = case MaybeExc of
690+ false -> Exc ;
691+ E -> E
692+ end ,
693+ await (T , [Res |Hist ], Exc2 )
669694 end .
670695
671696% % @private
0 commit comments