1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20-module(gen_server).
21
22%%% ---------------------------------------------------
23%%%
24%%% The idea behind THIS server is that the user module
25%%% provides (different) functions to handle different
26%%% kind of inputs.
27%%% If the Parent process terminates the Module:terminate/2
28%%% function is called.
29%%%
30%%% The user module should export:
31%%%
32%%%   init(Args)
33%%%     ==> {ok, State}
34%%%         {ok, State, Timeout}
35%%%         ignore
36%%%         {stop, Reason}
37%%%
38%%%   handle_call(Msg, {From, Tag}, State)
39%%%
40%%%    ==> {reply, Reply, State}
41%%%        {reply, Reply, State, Timeout}
42%%%        {noreply, State}
43%%%        {noreply, State, Timeout}
44%%%        {stop, Reason, Reply, State}
45%%%              Reason = normal | shutdown | Term terminate(State) is called
46%%%
47%%%   handle_cast(Msg, State)
48%%%
49%%%    ==> {noreply, State}
50%%%        {noreply, State, Timeout}
51%%%        {stop, Reason, State}
52%%%              Reason = normal | shutdown | Term terminate(State) is called
53%%%
54%%%   handle_info(Info, State) Info is e.g. {'EXIT', P, R}, {nodedown, N}, ...
55%%%
56%%%    ==> {noreply, State}
57%%%        {noreply, State, Timeout}
58%%%        {stop, Reason, State}
59%%%              Reason = normal | shutdown | Term, terminate(State) is called
60%%%
61%%%   terminate(Reason, State) Let the user module clean up
62%%%        always called when server terminates
63%%%
64%%%    ==> ok
65%%%
66%%%
67%%% The work flow (of the server) can be described as follows:
68%%%
69%%%   User module                          Generic
70%%%   -----------                          -------
71%%%     start            ----->             start
72%%%     init             <-----              .
73%%%
74%%%                                         loop
75%%%     handle_call      <-----              .
76%%%                      ----->             reply
77%%%
78%%%     handle_cast      <-----              .
79%%%
80%%%     handle_info      <-----              .
81%%%
82%%%     terminate        <-----              .
83%%%
84%%%                      ----->             reply
85%%%
86%%%
87%%% ---------------------------------------------------
88
89%% API
90-export([start/3, start/4,
91	 start_link/3, start_link/4,
92	 stop/1, stop/3,
93	 call/2, call/3,
94	 cast/2, reply/2,
95	 abcast/2, abcast/3,
96	 multi_call/2, multi_call/3, multi_call/4,
97	 enter_loop/3, enter_loop/4, enter_loop/5, wake_hib/6]).
98
99%% System exports
100-export([system_continue/3,
101	 system_terminate/4,
102	 system_code_change/4,
103	 system_get_state/1,
104	 system_replace_state/2,
105	 format_status/2]).
106
107%% logger callback
108-export([format_log/1]).
109
110%% Internal exports
111-export([init_it/6]).
112
113-include("logger.hrl").
114
115-define(
116   STACKTRACE(),
117   element(2, erlang:process_info(self(), current_stacktrace))).
118
119%%%=========================================================================
120%%%  API
121%%%=========================================================================
122
123-callback init(Args :: term()) ->
124    {ok, State :: term()} | {ok, State :: term(), timeout() | hibernate | {continue, term()}} |
125    {stop, Reason :: term()} | ignore.
126-callback handle_call(Request :: term(), From :: {pid(), Tag :: term()},
127                      State :: term()) ->
128    {reply, Reply :: term(), NewState :: term()} |
129    {reply, Reply :: term(), NewState :: term(), timeout() | hibernate | {continue, term()}} |
130    {noreply, NewState :: term()} |
131    {noreply, NewState :: term(), timeout() | hibernate | {continue, term()}} |
132    {stop, Reason :: term(), Reply :: term(), NewState :: term()} |
133    {stop, Reason :: term(), NewState :: term()}.
134-callback handle_cast(Request :: term(), State :: term()) ->
135    {noreply, NewState :: term()} |
136    {noreply, NewState :: term(), timeout() | hibernate | {continue, term()}} |
137    {stop, Reason :: term(), NewState :: term()}.
138-callback handle_info(Info :: timeout | term(), State :: term()) ->
139    {noreply, NewState :: term()} |
140    {noreply, NewState :: term(), timeout() | hibernate | {continue, term()}} |
141    {stop, Reason :: term(), NewState :: term()}.
142-callback handle_continue(Info :: term(), State :: term()) ->
143    {noreply, NewState :: term()} |
144    {noreply, NewState :: term(), timeout() | hibernate | {continue, term()}} |
145    {stop, Reason :: term(), NewState :: term()}.
146-callback terminate(Reason :: (normal | shutdown | {shutdown, term()} |
147                               term()),
148                    State :: term()) ->
149    term().
150-callback code_change(OldVsn :: (term() | {down, term()}), State :: term(),
151                      Extra :: term()) ->
152    {ok, NewState :: term()} | {error, Reason :: term()}.
153-callback format_status(Opt, StatusData) -> Status when
154      Opt :: 'normal' | 'terminate',
155      StatusData :: [PDict | State],
156      PDict :: [{Key :: term(), Value :: term()}],
157      State :: term(),
158      Status :: term().
159
160-optional_callbacks(
161    [handle_info/2, handle_continue/2, terminate/2, code_change/3, format_status/2]).
162
163%%%  -----------------------------------------------------------------
164%%% Starts a generic server.
165%%% start(Mod, Args, Options)
166%%% start(Name, Mod, Args, Options)
167%%% start_link(Mod, Args, Options)
168%%% start_link(Name, Mod, Args, Options) where:
169%%%    Name ::= {local, atom()} | {global, term()} | {via, atom(), term()}
170%%%    Mod  ::= atom(), callback module implementing the 'real' server
171%%%    Args ::= term(), init arguments (to Mod:init/1)
172%%%    Options ::= [{timeout, Timeout} | {debug, [Flag]}]
173%%%      Flag ::= trace | log | {logfile, File} | statistics | debug
174%%%          (debug == log && statistics)
175%%% Returns: {ok, Pid} |
176%%%          {error, {already_started, Pid}} |
177%%%          {error, Reason}
178%%% -----------------------------------------------------------------
179start(Mod, Args, Options) ->
180    gen:start(?MODULE, nolink, Mod, Args, Options).
181
182start(Name, Mod, Args, Options) ->
183    gen:start(?MODULE, nolink, Name, Mod, Args, Options).
184
185start_link(Mod, Args, Options) ->
186    gen:start(?MODULE, link, Mod, Args, Options).
187
188start_link(Name, Mod, Args, Options) ->
189    gen:start(?MODULE, link, Name, Mod, Args, Options).
190
191
192%% -----------------------------------------------------------------
193%% Stop a generic server and wait for it to terminate.
194%% If the server is located at another node, that node will
195%% be monitored.
196%% -----------------------------------------------------------------
197stop(Name) ->
198    gen:stop(Name).
199
200stop(Name, Reason, Timeout) ->
201    gen:stop(Name, Reason, Timeout).
202
203%% -----------------------------------------------------------------
204%% Make a call to a generic server.
205%% If the server is located at another node, that node will
206%% be monitored.
207%% If the client is trapping exits and is linked server termination
208%% is handled here (? Shall we do that here (or rely on timeouts) ?).
209%% -----------------------------------------------------------------
210call(Name, Request) ->
211    case catch gen:call(Name, '$gen_call', Request) of
212	{ok,Res} ->
213	    Res;
214	{'EXIT',Reason} ->
215	    exit({Reason, {?MODULE, call, [Name, Request]}})
216    end.
217
218call(Name, Request, Timeout) ->
219    case catch gen:call(Name, '$gen_call', Request, Timeout) of
220	{ok,Res} ->
221	    Res;
222	{'EXIT',Reason} ->
223	    exit({Reason, {?MODULE, call, [Name, Request, Timeout]}})
224    end.
225
226%% -----------------------------------------------------------------
227%% Make a cast to a generic server.
228%% -----------------------------------------------------------------
229cast({global,Name}, Request) ->
230    catch global:send(Name, cast_msg(Request)),
231    ok;
232cast({via, Mod, Name}, Request) ->
233    catch Mod:send(Name, cast_msg(Request)),
234    ok;
235cast({Name,Node}=Dest, Request) when is_atom(Name), is_atom(Node) ->
236    do_cast(Dest, Request);
237cast(Dest, Request) when is_atom(Dest) ->
238    do_cast(Dest, Request);
239cast(Dest, Request) when is_pid(Dest) ->
240    do_cast(Dest, Request).
241
242do_cast(Dest, Request) ->
243    do_send(Dest, cast_msg(Request)),
244    ok.
245
246cast_msg(Request) -> {'$gen_cast',Request}.
247
248%% -----------------------------------------------------------------
249%% Send a reply to the client.
250%% -----------------------------------------------------------------
251reply({To, Tag}, Reply) ->
252    catch To ! {Tag, Reply}.
253
254%% -----------------------------------------------------------------
255%% Asynchronous broadcast, returns nothing, it's just send 'n' pray
256%%-----------------------------------------------------------------
257abcast(Name, Request) when is_atom(Name) ->
258    do_abcast([node() | nodes()], Name, cast_msg(Request)).
259
260abcast(Nodes, Name, Request) when is_list(Nodes), is_atom(Name) ->
261    do_abcast(Nodes, Name, cast_msg(Request)).
262
263do_abcast([Node|Nodes], Name, Msg) when is_atom(Node) ->
264    do_send({Name,Node},Msg),
265    do_abcast(Nodes, Name, Msg);
266do_abcast([], _,_) -> abcast.
267
268%%% -----------------------------------------------------------------
269%%% Make a call to servers at several nodes.
270%%% Returns: {[Replies],[BadNodes]}
271%%% A Timeout can be given
272%%%
273%%% A middleman process is used in case late answers arrives after
274%%% the timeout. If they would be allowed to glog the callers message
275%%% queue, it would probably become confused. Late answers will
276%%% now arrive to the terminated middleman and so be discarded.
277%%% -----------------------------------------------------------------
278multi_call(Name, Req)
279  when is_atom(Name) ->
280    do_multi_call([node() | nodes()], Name, Req, infinity).
281
282multi_call(Nodes, Name, Req)
283  when is_list(Nodes), is_atom(Name) ->
284    do_multi_call(Nodes, Name, Req, infinity).
285
286multi_call(Nodes, Name, Req, infinity) ->
287    do_multi_call(Nodes, Name, Req, infinity);
288multi_call(Nodes, Name, Req, Timeout)
289  when is_list(Nodes), is_atom(Name), is_integer(Timeout), Timeout >= 0 ->
290    do_multi_call(Nodes, Name, Req, Timeout).
291
292
293%%-----------------------------------------------------------------
294%% enter_loop(Mod, Options, State, <ServerName>, <TimeOut>) ->_
295%%
296%% Description: Makes an existing process into a gen_server.
297%%              The calling process will enter the gen_server receive
298%%              loop and become a gen_server process.
299%%              The process *must* have been started using one of the
300%%              start functions in proc_lib, see proc_lib(3).
301%%              The user is responsible for any initialization of the
302%%              process, including registering a name for it.
303%%-----------------------------------------------------------------
304enter_loop(Mod, Options, State) ->
305    enter_loop(Mod, Options, State, self(), infinity).
306
307enter_loop(Mod, Options, State, ServerName = {Scope, _})
308  when Scope == local; Scope == global ->
309    enter_loop(Mod, Options, State, ServerName, infinity);
310
311enter_loop(Mod, Options, State, ServerName = {via, _, _}) ->
312    enter_loop(Mod, Options, State, ServerName, infinity);
313
314enter_loop(Mod, Options, State, Timeout) ->
315    enter_loop(Mod, Options, State, self(), Timeout).
316
317enter_loop(Mod, Options, State, ServerName, Timeout) ->
318    Name = gen:get_proc_name(ServerName),
319    Parent = gen:get_parent(),
320    Debug = gen:debug_options(Name, Options),
321    HibernateAfterTimeout = gen:hibernate_after(Options),
322    loop(Parent, Name, State, Mod, Timeout, HibernateAfterTimeout, Debug).
323
324%%%========================================================================
325%%% Gen-callback functions
326%%%========================================================================
327
328%%% ---------------------------------------------------
329%%% Initiate the new process.
330%%% Register the name using the Rfunc function
331%%% Calls the Mod:init/Args function.
332%%% Finally an acknowledge is sent to Parent and the main
333%%% loop is entered.
334%%% ---------------------------------------------------
335init_it(Starter, self, Name, Mod, Args, Options) ->
336    init_it(Starter, self(), Name, Mod, Args, Options);
337init_it(Starter, Parent, Name0, Mod, Args, Options) ->
338    Name = gen:name(Name0),
339    Debug = gen:debug_options(Name, Options),
340    HibernateAfterTimeout = gen:hibernate_after(Options),
341
342    case init_it(Mod, Args) of
343	{ok, {ok, State}} ->
344	    proc_lib:init_ack(Starter, {ok, self()}),
345	    loop(Parent, Name, State, Mod, infinity, HibernateAfterTimeout, Debug);
346	{ok, {ok, State, Timeout}} ->
347	    proc_lib:init_ack(Starter, {ok, self()}),
348	    loop(Parent, Name, State, Mod, Timeout, HibernateAfterTimeout, Debug);
349	{ok, {stop, Reason}} ->
350	    %% For consistency, we must make sure that the
351	    %% registered name (if any) is unregistered before
352	    %% the parent process is notified about the failure.
353	    %% (Otherwise, the parent process could get
354	    %% an 'already_started' error if it immediately
355	    %% tried starting the process again.)
356	    gen:unregister_name(Name0),
357	    proc_lib:init_ack(Starter, {error, Reason}),
358	    exit(Reason);
359	{ok, ignore} ->
360	    gen:unregister_name(Name0),
361	    proc_lib:init_ack(Starter, ignore),
362	    exit(normal);
363	{ok, Else} ->
364	    Error = {bad_return_value, Else},
365	    proc_lib:init_ack(Starter, {error, Error}),
366	    exit(Error);
367	{'EXIT', Class, Reason, Stacktrace} ->
368	    gen:unregister_name(Name0),
369	    proc_lib:init_ack(Starter, {error, terminate_reason(Class, Reason, Stacktrace)}),
370	    erlang:raise(Class, Reason, Stacktrace)
371    end.
372init_it(Mod, Args) ->
373    try
374	{ok, Mod:init(Args)}
375    catch
376	throw:R -> {ok, R};
377	Class:R:S -> {'EXIT', Class, R, S}
378    end.
379
380%%%========================================================================
381%%% Internal functions
382%%%========================================================================
383%%% ---------------------------------------------------
384%%% The MAIN loop.
385%%% ---------------------------------------------------
386
387loop(Parent, Name, State, Mod, {continue, Continue} = Msg, HibernateAfterTimeout, Debug) ->
388    Reply = try_dispatch(Mod, handle_continue, Continue, State),
389    case Debug of
390	[] ->
391	    handle_common_reply(Reply, Parent, Name, undefined, Msg, Mod,
392				HibernateAfterTimeout, State);
393	_ ->
394	    Debug1 = sys:handle_debug(Debug, fun print_event/3, Name, Msg),
395	    handle_common_reply(Reply, Parent, Name, undefined, Msg, Mod,
396				HibernateAfterTimeout, State, Debug1)
397    end;
398
399loop(Parent, Name, State, Mod, hibernate, HibernateAfterTimeout, Debug) ->
400    proc_lib:hibernate(?MODULE,wake_hib,[Parent, Name, State, Mod, HibernateAfterTimeout, Debug]);
401
402loop(Parent, Name, State, Mod, infinity, HibernateAfterTimeout, Debug) ->
403	receive
404		Msg ->
405			decode_msg(Msg, Parent, Name, State, Mod, infinity, HibernateAfterTimeout, Debug, false)
406	after HibernateAfterTimeout ->
407		loop(Parent, Name, State, Mod, hibernate, HibernateAfterTimeout, Debug)
408	end;
409
410loop(Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug) ->
411    Msg = receive
412	      Input ->
413		    Input
414	  after Time ->
415		  timeout
416	  end,
417    decode_msg(Msg, Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug, false).
418
419wake_hib(Parent, Name, State, Mod, HibernateAfterTimeout, Debug) ->
420    Msg = receive
421	      Input ->
422		  Input
423	  end,
424    decode_msg(Msg, Parent, Name, State, Mod, hibernate, HibernateAfterTimeout, Debug, true).
425
426decode_msg(Msg, Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug, Hib) ->
427    case Msg of
428	{system, From, Req} ->
429	    sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
430				  [Name, State, Mod, Time, HibernateAfterTimeout], Hib);
431	{'EXIT', Parent, Reason} ->
432	    terminate(Reason, ?STACKTRACE(), Name, undefined, Msg, Mod, State, Debug);
433	_Msg when Debug =:= [] ->
434	    handle_msg(Msg, Parent, Name, State, Mod, HibernateAfterTimeout);
435	_Msg ->
436	    Debug1 = sys:handle_debug(Debug, fun print_event/3,
437				      Name, {in, Msg}),
438	    handle_msg(Msg, Parent, Name, State, Mod, HibernateAfterTimeout, Debug1)
439    end.
440
441%%% ---------------------------------------------------
442%%% Send/receive functions
443%%% ---------------------------------------------------
444do_send(Dest, Msg) ->
445    try erlang:send(Dest, Msg)
446    catch
447        error:_ -> ok
448    end,
449    ok.
450
451do_multi_call(Nodes, Name, Req, infinity) ->
452    Tag = make_ref(),
453    Monitors = send_nodes(Nodes, Name, Tag, Req),
454    rec_nodes(Tag, Monitors, Name, undefined);
455do_multi_call(Nodes, Name, Req, Timeout) ->
456    Tag = make_ref(),
457    Caller = self(),
458    Receiver =
459	spawn(
460	  fun() ->
461		  %% Middleman process. Should be unsensitive to regular
462		  %% exit signals. The sychronization is needed in case
463		  %% the receiver would exit before the caller started
464		  %% the monitor.
465		  process_flag(trap_exit, true),
466		  Mref = erlang:monitor(process, Caller),
467		  receive
468		      {Caller,Tag} ->
469			  Monitors = send_nodes(Nodes, Name, Tag, Req),
470			  TimerId = erlang:start_timer(Timeout, self(), ok),
471			  Result = rec_nodes(Tag, Monitors, Name, TimerId),
472			  exit({self(),Tag,Result});
473		      {'DOWN',Mref,_,_,_} ->
474			  %% Caller died before sending us the go-ahead.
475			  %% Give up silently.
476			  exit(normal)
477		  end
478	  end),
479    Mref = erlang:monitor(process, Receiver),
480    Receiver ! {self(),Tag},
481    receive
482	{'DOWN',Mref,_,_,{Receiver,Tag,Result}} ->
483	    Result;
484	{'DOWN',Mref,_,_,Reason} ->
485	    %% The middleman code failed. Or someone did
486	    %% exit(_, kill) on the middleman process => Reason==killed
487	    exit(Reason)
488    end.
489
490send_nodes(Nodes, Name, Tag, Req) ->
491    send_nodes(Nodes, Name, Tag, Req, []).
492
493send_nodes([Node|Tail], Name, Tag, Req, Monitors)
494  when is_atom(Node) ->
495    Monitor = start_monitor(Node, Name),
496    %% Handle non-existing names in rec_nodes.
497    catch {Name, Node} ! {'$gen_call', {self(), {Tag, Node}}, Req},
498    send_nodes(Tail, Name, Tag, Req, [Monitor | Monitors]);
499send_nodes([_Node|Tail], Name, Tag, Req, Monitors) ->
500    %% Skip non-atom Node
501    send_nodes(Tail, Name, Tag, Req, Monitors);
502send_nodes([], _Name, _Tag, _Req, Monitors) ->
503    Monitors.
504
505%% Against old nodes:
506%% If no reply has been delivered within 2 secs. (per node) check that
507%% the server really exists and wait for ever for the answer.
508%%
509%% Against contemporary nodes:
510%% Wait for reply, server 'DOWN', or timeout from TimerId.
511
512rec_nodes(Tag, Nodes, Name, TimerId) ->
513    rec_nodes(Tag, Nodes, Name, [], [], 2000, TimerId).
514
515rec_nodes(Tag, [{N,R}|Tail], Name, Badnodes, Replies, Time, TimerId ) ->
516    receive
517	{'DOWN', R, _, _, _} ->
518	    rec_nodes(Tag, Tail, Name, [N|Badnodes], Replies, Time, TimerId);
519	{{Tag, N}, Reply} ->  %% Tag is bound !!!
520	    erlang:demonitor(R, [flush]),
521	    rec_nodes(Tag, Tail, Name, Badnodes,
522		      [{N,Reply}|Replies], Time, TimerId);
523	{timeout, TimerId, _} ->
524	    erlang:demonitor(R, [flush]),
525	    %% Collect all replies that already have arrived
526	    rec_nodes_rest(Tag, Tail, Name, [N|Badnodes], Replies)
527    end;
528rec_nodes(Tag, [N|Tail], Name, Badnodes, Replies, Time, TimerId) ->
529    %% R6 node
530    receive
531	{nodedown, N} ->
532	    monitor_node(N, false),
533	    rec_nodes(Tag, Tail, Name, [N|Badnodes], Replies, 2000, TimerId);
534	{{Tag, N}, Reply} ->  %% Tag is bound !!!
535	    receive {nodedown, N} -> ok after 0 -> ok end,
536	    monitor_node(N, false),
537	    rec_nodes(Tag, Tail, Name, Badnodes,
538		      [{N,Reply}|Replies], 2000, TimerId);
539	{timeout, TimerId, _} ->
540	    receive {nodedown, N} -> ok after 0 -> ok end,
541	    monitor_node(N, false),
542	    %% Collect all replies that already have arrived
543	    rec_nodes_rest(Tag, Tail, Name, [N | Badnodes], Replies)
544    after Time ->
545	    case rpc:call(N, erlang, whereis, [Name]) of
546		Pid when is_pid(Pid) -> % It exists try again.
547		    rec_nodes(Tag, [N|Tail], Name, Badnodes,
548			      Replies, infinity, TimerId);
549		_ -> % badnode
550		    receive {nodedown, N} -> ok after 0 -> ok end,
551		    monitor_node(N, false),
552		    rec_nodes(Tag, Tail, Name, [N|Badnodes],
553			      Replies, 2000, TimerId)
554	    end
555    end;
556rec_nodes(_, [], _, Badnodes, Replies, _, TimerId) ->
557    case catch erlang:cancel_timer(TimerId) of
558	false ->  % It has already sent it's message
559	    receive
560		{timeout, TimerId, _} -> ok
561	    after 0 ->
562		    ok
563	    end;
564	_ -> % Timer was cancelled, or TimerId was 'undefined'
565	    ok
566    end,
567    {Replies, Badnodes}.
568
569%% Collect all replies that already have arrived
570rec_nodes_rest(Tag, [{N,R}|Tail], Name, Badnodes, Replies) ->
571    receive
572	{'DOWN', R, _, _, _} ->
573	    rec_nodes_rest(Tag, Tail, Name, [N|Badnodes], Replies);
574	{{Tag, N}, Reply} -> %% Tag is bound !!!
575	    erlang:demonitor(R, [flush]),
576	    rec_nodes_rest(Tag, Tail, Name, Badnodes, [{N,Reply}|Replies])
577    after 0 ->
578	    erlang:demonitor(R, [flush]),
579	    rec_nodes_rest(Tag, Tail, Name, [N|Badnodes], Replies)
580    end;
581rec_nodes_rest(Tag, [N|Tail], Name, Badnodes, Replies) ->
582    %% R6 node
583    receive
584	{nodedown, N} ->
585	    monitor_node(N, false),
586	    rec_nodes_rest(Tag, Tail, Name, [N|Badnodes], Replies);
587	{{Tag, N}, Reply} ->  %% Tag is bound !!!
588	    receive {nodedown, N} -> ok after 0 -> ok end,
589	    monitor_node(N, false),
590	    rec_nodes_rest(Tag, Tail, Name, Badnodes, [{N,Reply}|Replies])
591    after 0 ->
592	    receive {nodedown, N} -> ok after 0 -> ok end,
593	    monitor_node(N, false),
594	    rec_nodes_rest(Tag, Tail, Name, [N|Badnodes], Replies)
595    end;
596rec_nodes_rest(_Tag, [], _Name, Badnodes, Replies) ->
597    {Replies, Badnodes}.
598
599
600%%% ---------------------------------------------------
601%%% Monitor functions
602%%% ---------------------------------------------------
603
604start_monitor(Node, Name) when is_atom(Node), is_atom(Name) ->
605    if node() =:= nonode@nohost, Node =/= nonode@nohost ->
606	    Ref = make_ref(),
607	    self() ! {'DOWN', Ref, process, {Name, Node}, noconnection},
608	    {Node, Ref};
609       true ->
610	    case catch erlang:monitor(process, {Name, Node}) of
611		{'EXIT', _} ->
612		    %% Remote node is R6
613		    monitor_node(Node, true),
614		    Node;
615		Ref when is_reference(Ref) ->
616		    {Node, Ref}
617	    end
618    end.
619
620%% ---------------------------------------------------
621%% Helper functions for try-catch of callbacks.
622%% Returns the return value of the callback, or
623%% {'EXIT', Class, Reason, Stack} (if an exception occurs)
624%%
625%% The Class, Reason and Stack are given to erlang:raise/3
626%% to make sure proc_lib receives the proper reasons and
627%% stacktraces.
628%% ---------------------------------------------------
629
630try_dispatch({'$gen_cast', Msg}, Mod, State) ->
631    try_dispatch(Mod, handle_cast, Msg, State);
632try_dispatch(Info, Mod, State) ->
633    try_dispatch(Mod, handle_info, Info, State).
634
635try_dispatch(Mod, Func, Msg, State) ->
636    try
637	{ok, Mod:Func(Msg, State)}
638    catch
639	throw:R ->
640	    {ok, R};
641        error:undef = R:Stacktrace when Func == handle_info ->
642            case erlang:function_exported(Mod, handle_info, 2) of
643                false ->
644                    ?LOG_WARNING(
645                       #{label=>{gen_server,no_handle_info},
646                         module=>Mod,
647                         message=>Msg},
648                       #{domain=>[otp],
649                         report_cb=>fun gen_server:format_log/1,
650                         error_logger=>#{tag=>warning_msg}}),
651                    {ok, {noreply, State}};
652                true ->
653                    {'EXIT', error, R, Stacktrace}
654            end;
655	Class:R:Stacktrace ->
656	    {'EXIT', Class, R, Stacktrace}
657    end.
658
659try_handle_call(Mod, Msg, From, State) ->
660    try
661	{ok, Mod:handle_call(Msg, From, State)}
662    catch
663	throw:R ->
664	    {ok, R};
665	Class:R:Stacktrace ->
666	    {'EXIT', Class, R, Stacktrace}
667    end.
668
669try_terminate(Mod, Reason, State) ->
670    case erlang:function_exported(Mod, terminate, 2) of
671	true ->
672	    try
673		{ok, Mod:terminate(Reason, State)}
674	    catch
675		throw:R ->
676		    {ok, R};
677		Class:R:Stacktrace ->
678		    {'EXIT', Class, R, Stacktrace}
679	   end;
680	false ->
681	    {ok, ok}
682    end.
683
684
685%%% ---------------------------------------------------
686%%% Message handling functions
687%%% ---------------------------------------------------
688
689handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, HibernateAfterTimeout) ->
690    Result = try_handle_call(Mod, Msg, From, State),
691    case Result of
692	{ok, {reply, Reply, NState}} ->
693	    reply(From, Reply),
694	    loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, []);
695	{ok, {reply, Reply, NState, Time1}} ->
696	    reply(From, Reply),
697	    loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, []);
698	{ok, {noreply, NState}} ->
699	    loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, []);
700	{ok, {noreply, NState, Time1}} ->
701	    loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, []);
702	{ok, {stop, Reason, Reply, NState}} ->
703	    try
704		terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, [])
705	    after
706		reply(From, Reply)
707	    end;
708	Other -> handle_common_reply(Other, Parent, Name, From, Msg, Mod, HibernateAfterTimeout, State)
709    end;
710handle_msg(Msg, Parent, Name, State, Mod, HibernateAfterTimeout) ->
711    Reply = try_dispatch(Msg, Mod, State),
712    handle_common_reply(Reply, Parent, Name, undefined, Msg, Mod, HibernateAfterTimeout, State).
713
714handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, HibernateAfterTimeout, Debug) ->
715    Result = try_handle_call(Mod, Msg, From, State),
716    case Result of
717	{ok, {reply, Reply, NState}} ->
718	    Debug1 = reply(Name, From, Reply, NState, Debug),
719	    loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, Debug1);
720	{ok, {reply, Reply, NState, Time1}} ->
721	    Debug1 = reply(Name, From, Reply, NState, Debug),
722	    loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, Debug1);
723	{ok, {noreply, NState}} ->
724	    Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
725				      {noreply, NState}),
726	    loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, Debug1);
727	{ok, {noreply, NState, Time1}} ->
728	    Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
729				      {noreply, NState}),
730	    loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, Debug1);
731	{ok, {stop, Reason, Reply, NState}} ->
732	    try
733		terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, Debug)
734	    after
735		_ = reply(Name, From, Reply, NState, Debug)
736	    end;
737	Other ->
738	    handle_common_reply(Other, Parent, Name, From, Msg, Mod, HibernateAfterTimeout, State, Debug)
739    end;
740handle_msg(Msg, Parent, Name, State, Mod, HibernateAfterTimeout, Debug) ->
741    Reply = try_dispatch(Msg, Mod, State),
742    handle_common_reply(Reply, Parent, Name, undefined, Msg, Mod, HibernateAfterTimeout, State, Debug).
743
744handle_common_reply(Reply, Parent, Name, From, Msg, Mod, HibernateAfterTimeout, State) ->
745    case Reply of
746	{ok, {noreply, NState}} ->
747	    loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, []);
748	{ok, {noreply, NState, Time1}} ->
749	    loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, []);
750	{ok, {stop, Reason, NState}} ->
751	    terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, []);
752	{'EXIT', Class, Reason, Stacktrace} ->
753	    terminate(Class, Reason, Stacktrace, Name, From, Msg, Mod, State, []);
754	{ok, BadReply} ->
755	    terminate({bad_return_value, BadReply}, ?STACKTRACE(), Name, From, Msg, Mod, State, [])
756    end.
757
758handle_common_reply(Reply, Parent, Name, From, Msg, Mod, HibernateAfterTimeout, State, Debug) ->
759    case Reply of
760	{ok, {noreply, NState}} ->
761	    Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
762				      {noreply, NState}),
763	    loop(Parent, Name, NState, Mod, infinity, HibernateAfterTimeout, Debug1);
764	{ok, {noreply, NState, Time1}} ->
765	    Debug1 = sys:handle_debug(Debug, fun print_event/3, Name,
766				      {noreply, NState}),
767	    loop(Parent, Name, NState, Mod, Time1, HibernateAfterTimeout, Debug1);
768	{ok, {stop, Reason, NState}} ->
769	    terminate(Reason, ?STACKTRACE(), Name, From, Msg, Mod, NState, Debug);
770	{'EXIT', Class, Reason, Stacktrace} ->
771	    terminate(Class, Reason, Stacktrace, Name, From, Msg, Mod, State, Debug);
772	{ok, BadReply} ->
773	    terminate({bad_return_value, BadReply}, ?STACKTRACE(), Name, From, Msg, Mod, State, Debug)
774    end.
775
776reply(Name, From, Reply, State, Debug) ->
777    reply(From, Reply),
778    sys:handle_debug(Debug, fun print_event/3, Name,
779		     {out, Reply, From, State} ).
780
781
782%%-----------------------------------------------------------------
783%% Callback functions for system messages handling.
784%%-----------------------------------------------------------------
785system_continue(Parent, Debug, [Name, State, Mod, Time, HibernateAfterTimeout]) ->
786    loop(Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug).
787
788-spec system_terminate(_, _, _, [_]) -> no_return().
789
790system_terminate(Reason, _Parent, Debug, [Name, State, Mod, _Time, _HibernateAfterTimeout]) ->
791    terminate(Reason, ?STACKTRACE(), Name, undefined, [], Mod, State, Debug).
792
793system_code_change([Name, State, Mod, Time, HibernateAfterTimeout], _Module, OldVsn, Extra) ->
794    case catch Mod:code_change(OldVsn, State, Extra) of
795	{ok, NewState} -> {ok, [Name, NewState, Mod, Time, HibernateAfterTimeout]};
796	Else -> Else
797    end.
798
799system_get_state([_Name, State, _Mod, _Time, _HibernateAfterTimeout]) ->
800    {ok, State}.
801
802system_replace_state(StateFun, [Name, State, Mod, Time, HibernateAfterTimeout]) ->
803    NState = StateFun(State),
804    {ok, NState, [Name, NState, Mod, Time, HibernateAfterTimeout]}.
805
806%%-----------------------------------------------------------------
807%% Format debug messages.  Print them as the call-back module sees
808%% them, not as the real erlang messages.  Use trace for that.
809%%-----------------------------------------------------------------
810print_event(Dev, {in, Msg}, Name) ->
811    case Msg of
812	{'$gen_call', {From, _Tag}, Call} ->
813	    io:format(Dev, "*DBG* ~tp got call ~tp from ~tw~n",
814		      [Name, Call, From]);
815	{'$gen_cast', Cast} ->
816	    io:format(Dev, "*DBG* ~tp got cast ~tp~n",
817		      [Name, Cast]);
818	_ ->
819	    io:format(Dev, "*DBG* ~tp got ~tp~n", [Name, Msg])
820    end;
821print_event(Dev, {out, Msg, {To,_Tag}, State}, Name) ->
822    io:format(Dev, "*DBG* ~tp sent ~tp to ~tw, new state ~tp~n",
823	      [Name, Msg, To, State]);
824print_event(Dev, {noreply, State}, Name) ->
825    io:format(Dev, "*DBG* ~tp new state ~tp~n", [Name, State]);
826print_event(Dev, Event, Name) ->
827    io:format(Dev, "*DBG* ~tp dbg  ~tp~n", [Name, Event]).
828
829
830%%% ---------------------------------------------------
831%%% Terminate the server.
832%%%
833%%% terminate/8 is triggered by {stop, Reason} or bad
834%%% return values. The stacktrace is generated via the
835%%% ?STACKTRACE() macro and the ReportReason must not
836%%% be wrapped in tuples.
837%%%
838%%% terminate/9 is triggered in case of error/exit in
839%%% the user callback. In this case the report reason
840%%% always includes the user stacktrace.
841%%%
842%%% The reason received in the terminate/2 callbacks
843%%% always includes the stacktrace for errors and never
844%%% for exits.
845%%% ---------------------------------------------------
846
847-spec terminate(_, _, _, _, _, _, _, _) -> no_return().
848terminate(Reason, Stacktrace, Name, From, Msg, Mod, State, Debug) ->
849  terminate(exit, Reason, Stacktrace, Reason, Name, From, Msg, Mod, State, Debug).
850
851-spec terminate(_, _, _, _, _, _, _, _, _) -> no_return().
852terminate(Class, Reason, Stacktrace, Name, From, Msg, Mod, State, Debug) ->
853  ReportReason = {Reason, Stacktrace},
854  terminate(Class, Reason, Stacktrace, ReportReason, Name, From, Msg, Mod, State, Debug).
855
856-spec terminate(_, _, _, _, _, _, _, _, _, _) -> no_return().
857terminate(Class, Reason, Stacktrace, ReportReason, Name, From, Msg, Mod, State, Debug) ->
858    Reply = try_terminate(Mod, terminate_reason(Class, Reason, Stacktrace), State),
859    case Reply of
860	{'EXIT', C, R, S} ->
861	    error_info({R, S}, Name, From, Msg, Mod, State, Debug),
862	    erlang:raise(C, R, S);
863	_ ->
864	    case {Class, Reason} of
865		{exit, normal} -> ok;
866		{exit, shutdown} -> ok;
867		{exit, {shutdown,_}} -> ok;
868		_ ->
869		    error_info(ReportReason, Name, From, Msg, Mod, State, Debug)
870	    end
871    end,
872    case Stacktrace of
873	[] ->
874	    erlang:Class(Reason);
875	_ ->
876	    erlang:raise(Class, Reason, Stacktrace)
877    end.
878
879terminate_reason(error, Reason, Stacktrace) -> {Reason, Stacktrace};
880terminate_reason(exit, Reason, _Stacktrace) -> Reason.
881
882error_info(_Reason, application_controller, _From, _Msg, _Mod, _State, _Debug) ->
883    %% OTP-5811 Don't send an error report if it's the system process
884    %% application_controller which is terminating - let init take care
885    %% of it instead
886    ok;
887error_info(Reason, Name, From, Msg, Mod, State, Debug) ->
888    Log = sys:get_log(Debug),
889    ?LOG_ERROR(#{label=>{gen_server,terminate},
890                 name=>Name,
891                 last_message=>Msg,
892                 state=>format_status(terminate, Mod, get(), State),
893                 log=>format_log_state(Mod, Log),
894                 reason=>Reason,
895                 client_info=>client_stacktrace(From)},
896               #{domain=>[otp],
897                 report_cb=>fun gen_server:format_log/1,
898                 error_logger=>#{tag=>error}}),
899    ok.
900
901client_stacktrace(undefined) ->
902    undefined;
903client_stacktrace({From,_Tag}) ->
904    client_stacktrace(From);
905client_stacktrace(From) when is_pid(From), node(From) =:= node() ->
906    case process_info(From, [current_stacktrace, registered_name]) of
907        undefined ->
908            {From,dead};
909        [{current_stacktrace, Stacktrace}, {registered_name, []}]  ->
910            {From,{From,Stacktrace}};
911        [{current_stacktrace, Stacktrace}, {registered_name, Name}]  ->
912            {From,{Name,Stacktrace}}
913    end;
914client_stacktrace(From) when is_pid(From) ->
915    {From,remote}.
916
917format_log(#{label:={gen_server,terminate},
918             name:=Name,
919             last_message:=Msg,
920             state:=State,
921             log:=Log,
922             reason:=Reason,
923             client_info:=Client}) ->
924    Reason1 =
925	case Reason of
926	    {undef,[{M,F,A,L}|MFAs]} ->
927		case code:is_loaded(M) of
928		    false ->
929			{'module could not be loaded',[{M,F,A,L}|MFAs]};
930		    _ ->
931			case erlang:function_exported(M, F, length(A)) of
932			    true ->
933				Reason;
934			    false ->
935				{'function not exported',[{M,F,A,L}|MFAs]}
936			end
937		end;
938	    _ ->
939		Reason
940	end,
941    {ClientFmt,ClientArgs} = format_client_log(Client),
942    [LimitedMsg,LimitedState,LimitedReason|LimitedLog] =
943        [error_logger:limit_term(D) || D <- [Msg,State,Reason1|Log]],
944    {"** Generic server ~tp terminating \n"
945     "** Last message in was ~tp~n"
946     "** When Server state == ~tp~n"
947     "** Reason for termination ==~n** ~tp~n" ++
948         case LimitedLog of
949             [] -> [];
950             _ -> "** Log ==~n** ~tp~n"
951         end ++ ClientFmt,
952     [Name, LimitedMsg, LimitedState, LimitedReason] ++
953         case LimitedLog of
954             [] -> [];
955             _ -> [LimitedLog]
956         end ++ ClientArgs};
957format_log(#{label:={gen_server,no_handle_info},
958             module:=Mod,
959             message:=Msg}) ->
960    {"** Undefined handle_info in ~p~n"
961     "** Unhandled message: ~tp~n",
962     [Mod, error_logger:limit_term(Msg)]}.
963
964format_client_log(undefined) ->
965    {"", []};
966format_client_log({From,dead}) ->
967    {"** Client ~p is dead~n", [From]};
968format_client_log({From,remote}) ->
969    {"** Client ~p is remote on node ~p~n", [From, node(From)]};
970format_client_log({_From,{Name,Stacktrace}}) ->
971    {"** Client ~tp stacktrace~n"
972     "** ~tp~n",
973     [Name, error_logger:limit_term(Stacktrace)]}.
974
975%%-----------------------------------------------------------------
976%% Status information
977%%-----------------------------------------------------------------
978format_status(Opt, StatusData) ->
979    [PDict, SysState, Parent, Debug, [Name, State, Mod, _Time, _HibernateAfterTimeout]] = StatusData,
980    Header = gen:format_status_header("Status for generic server", Name),
981    Log = sys:get_log(Debug),
982    Specific = case format_status(Opt, Mod, PDict, State) of
983		  S when is_list(S) -> S;
984		  S -> [S]
985	      end,
986    [{header, Header},
987     {data, [{"Status", SysState},
988	     {"Parent", Parent},
989	     {"Logged events", format_log_state(Mod, Log)}]} |
990     Specific].
991
992format_log_state(Mod, Log) ->
993    [case Event of
994         {out,Msg,From,State} ->
995             {out,Msg,From,format_status(terminate, Mod, get(), State)};
996         {noreply,State} ->
997             {noreply,format_status(terminate, Mod, get(), State)};
998         _ -> Event
999     end || Event <- Log].
1000
1001format_status(Opt, Mod, PDict, State) ->
1002    DefStatus = case Opt of
1003		    terminate -> State;
1004		    _ -> [{data, [{"State", State}]}]
1005		end,
1006    case erlang:function_exported(Mod, format_status, 2) of
1007	true ->
1008	    case catch Mod:format_status(Opt, [PDict, State]) of
1009		{'EXIT', _} -> DefStatus;
1010		Else -> Else
1011	    end;
1012	_ ->
1013	    DefStatus
1014    end.
1015