@@ -80,6 +80,7 @@ the process itself to format these events.
8080
8181% % External exports
8282-export ([suspend /1 , suspend /2 , resume /1 , resume /2 ,
83+ multi_suspend /1 , multi_suspend /2 ,
8384 get_status /1 , get_status /2 ,
8485 get_state /1 , get_state /2 ,
8586 replace_state /2 , replace_state /3 ,
@@ -284,6 +285,29 @@ system messages, but not other messages.
284285 Timeout :: timeout ().
285286suspend (Name , Timeout ) -> send_system_msg (Name , suspend , Timeout ).
286287
288+ -doc (#{equiv => multi_suspend (Names , 5000 )}).
289+ -spec multi_suspend (Names ) -> [{Name , Result }] when
290+ Names :: [name ()],
291+ Name :: name (),
292+ Result :: 'ok' | {'error' , term ()}.
293+ multi_suspend (Names ) -> multi_suspend (Names , 5000 ).
294+
295+ -doc """
296+ Suspends multiple processes concurrently.
297+
298+ Sends suspend requests to all processes in ` Names ` simultaneously and
299+ collects the results. Returns a list of ` {Name, Result} ` tuples in
300+ the same order as ` Names ` , where ` Result ` is ` ok ` on success or
301+ ` {error, Reason} ` on failure.
302+ """ .
303+ -spec multi_suspend (Names , Timeout ) -> [{Name , Result }] when
304+ Names :: [name ()],
305+ Name :: name (),
306+ Timeout :: timeout (),
307+ Result :: 'ok' | {'error' , term ()}.
308+ multi_suspend (Names , Timeout ) ->
309+ send_multi_system_msg (Names , suspend , Timeout ).
310+
287311-doc (#{equiv => resume (Name , 5000 )}).
288312-spec resume (Name ) -> 'ok' when
289313 Name :: name ().
@@ -763,6 +787,31 @@ send_system_msg(Name, Request, Timeout) ->
763787 exit ({Reason , mfa (Name , Request , Timeout )})
764788 end .
765789
790+ send_multi_system_msg (Names , Request , Timeout ) ->
791+ ReqIdCol = lists :foldl (
792+ fun (Name , Acc ) ->
793+ gen :send_request (Name , system , Request , Name , Acc )
794+ end , gen :reqids_new (), Names ),
795+ ResultMap = collect_multi_responses (ReqIdCol , Timeout , #{}),
796+ [{Name , maps :get (Name , ResultMap )} || Name <- Names ].
797+
798+ collect_multi_responses (ReqIdCol , Timeout , Acc ) ->
799+ case gen :wait_response (ReqIdCol , Timeout , true ) of
800+ {{reply , Reply }, Name , NewReqIdCol } ->
801+ collect_multi_responses (NewReqIdCol , Timeout ,
802+ Acc #{Name => Reply });
803+ {{error , {Reason , _Ref }}, Name , NewReqIdCol } ->
804+ collect_multi_responses (NewReqIdCol , Timeout ,
805+ Acc #{Name => {error , Reason }});
806+ timeout ->
807+ Remaining = gen :reqids_to_list (ReqIdCol ),
808+ lists :foldl (
809+ fun ({_ReqId , Name }, A ) -> A #{Name => {error , timeout }} end ,
810+ Acc , Remaining );
811+ no_request ->
812+ Acc
813+ end .
814+
766815mfa (Name , {debug , {Func , Arg2 }}) ->
767816 {sys , Func , [Name , Arg2 ]};
768817mfa (Name , {change_code , Mod , Vsn , Extra }) ->
0 commit comments