gen_event.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 659 行 · 第 1/2 页

ERL
659
字号
server_add_handler({Mod,Id}, Args, MSL) ->    Handler = #handler{module = Mod,		       id = Id},    server_add_handler(Mod, Handler, Args, MSL);server_add_handler(Mod, Args, MSL) ->     Handler = #handler{module = Mod},    server_add_handler(Mod, Handler, Args, MSL).server_add_handler(Mod, Handler, Args, MSL) ->    case catch Mod:init(Args) of        {ok, State} ->	    {ok, [Handler#handler{state = State}|MSL]};        Other ->            {Other, MSL}    end.%% Set up a link to the supervising process.%% (Ought to be unidirected links here, Erl5.0 !!)%% NOTE: This link will not be removed then the%% handler is removed in case another handler has%% own link to this process.server_add_sup_handler({Mod,Id}, Args, MSL, Parent) ->    link(Parent),    Handler = #handler{module = Mod,		       id = Id,		       supervised = Parent},    server_add_handler(Mod, Handler, Args, MSL);server_add_sup_handler(Mod, Args, MSL, Parent) ->     link(Parent),    Handler = #handler{module = Mod,		       supervised = Parent},    server_add_handler(Mod, Handler, Args, MSL).%% server_delete_handler(HandlerId, Args, MSL) -> {Ret, MSL'}server_delete_handler(HandlerId, Args, MSL, SName) ->     case split(HandlerId, MSL) of	{Mod, Handler, MSL1} ->	    {do_terminate(Mod, Handler, Args,			  Handler#handler.state, delete, SName, normal),	     MSL1};	error ->	    {{error, module_not_found}, MSL}    end.%% server_swap_handler(Handler1, Args1, Handler2, Args2, MSL, SN)= -> MSL'%% server_swap_handler(Handler1, Args1, Handler2, Args2, MSL, Sup, SN)= -> MSL'server_swap_handler(Handler1, Args1, Handler2, Args2, MSL, SName) ->    {State2, Sup, MSL1} = split_and_terminate(Handler1, Args1, MSL,					      SName, Handler2, false),    case s_s_h(Sup, Handler2, {Args2, State2}, MSL1) of	{ok, MSL2} ->	    {ok, MSL2};	{What, MSL2} ->	    {{error, What}, MSL2}    end.server_swap_handler(Handler1, Args1, Handler2, Args2, MSL, Sup, SName) ->    {State2, _, MSL1} = split_and_terminate(Handler1, Args1, MSL,					    SName, Handler2, Sup),    case s_s_h(Sup, Handler2, {Args2, State2}, MSL1) of	{ok, MSL2} ->	    {ok, MSL2};	{What, MSL2} ->	    {{error, What}, MSL2}    end.s_s_h(false, Handler, Args, MSL) ->    server_add_handler(Handler, Args, MSL);s_s_h(Pid, Handler, Args, MSL) ->    server_add_sup_handler(Handler, Args, MSL, Pid).split_and_terminate(HandlerId, Args, MSL, SName, Handler2, Sup) ->    case split(HandlerId, MSL) of	{Mod, Handler, MSL1} ->	    OldSup = Handler#handler.supervised,	    NewSup = if			 not Sup -> OldSup;			 true    -> Sup		     end,	    {do_terminate(Mod, Handler, Args,			  Handler#handler.state, swapped, SName,			  {swapped, Handler2, NewSup}),	     OldSup,	     MSL1};	error ->            {error, false, MSL}    end.%% server_notify(Event, Func, MSL, SName) -> MSL'server_notify(Event, Func, [Handler|T], SName) ->     case server_update(Handler, Func, Event, SName) of	{ok, Handler1} ->	    [Handler1|server_notify(Event, Func, T, SName)];	no ->	    server_notify(Event, Func, T, SName)    end;server_notify(_, _, [], _) ->    [].%% server_update(Handler, Func, Event, ServerName) -> Handler1 | noserver_update(Handler1, Func, Event, SName) ->    Mod1 = Handler1#handler.module,    State = Handler1#handler.state,    case catch Mod1:Func(Event, State) of	{ok, State1} -> 	    {ok, Handler1#handler{state = State1}};	{swap_handler, Args1, State1, Handler2, Args2} ->	    do_swap(Mod1,Handler1,Args1,State1,Handler2,Args2,SName);	remove_handler ->	    do_terminate(Mod1, Handler1, remove_handler, State,			 remove, SName, normal),	    no;	Other ->	    do_terminate(Mod1, Handler1, {error, Other}, State,			 Event, SName, crash),	    no    end.do_swap(Mod1,Handler1,Args1,State1,Handler2,Args2,SName) ->    %% finalise the existing handler    State2 = do_terminate(Mod1, Handler1, Args1, State1,			  swapped, SName,			  {swapped, Handler2, Handler1#handler.supervised}),    {Mod2,Handler} = new_handler(Handler2, Handler1),    case catch Mod2:init({Args2, State2}) of	{ok, State2a} ->	    {ok, Handler#handler{state = State2a}};	Other ->	    report_terminate(Handler2, crash, {error, Other}, SName, false),	    no    end.new_handler({Mod,Id}, Handler1) ->    {Mod,#handler{module = Mod,		  id = Id,		  supervised = Handler1#handler.supervised}};new_handler(Mod, Handler1) ->    {Mod,#handler{module = Mod,		  supervised = Handler1#handler.supervised}}.%% split(Handler, [#handler]) ->%%   {Mod, #handler, [#handler]} | errorsplit(Ha, MSL) -> split(Ha, MSL, []).split({Mod,Id}, [Ha|T], L) when Ha#handler.module =:= Mod,                                Ha#handler.id =:= Id ->    {Mod, Ha, lists:reverse(L, T)};split(Mod, [Ha|T], L) when Ha#handler.module =:= Mod,                           not Ha#handler.id ->    {Mod, Ha, lists:reverse(L, T)};split(Ha, [H|T], L) ->    split(Ha, T, [H|L]);split(_, [], _) ->    error.%% server_call(Handler, Query, MSL, ServerName) ->%%    {Reply, MSL1}server_call(Handler, Query, MSL, SName) ->    case search(Handler, MSL) of	{ok, Ha} ->	    case server_call_update(Ha, Query, SName) of		{no, Reply} ->		    {Reply, delete(Handler, MSL)};		{{ok, Ha1}, Reply} ->		    {Reply, replace(Handler, MSL, Ha1)}	    end;	false ->	    {{error, bad_module}, MSL}    end.search({Mod, Id}, [Ha|_MSL]) when Ha#handler.module =:= Mod,				  Ha#handler.id =:= Id ->    {ok, Ha};search(Mod, [Ha|_MSL]) when Ha#handler.module =:= Mod,			    not Ha#handler.id ->    {ok, Ha};search(Handler, [_|MSL]) ->    search(Handler, MSL);search(_, []) ->    false.delete({Mod, Id}, [Ha|MSL]) when Ha#handler.module =:= Mod,                                 Ha#handler.id =:= Id ->    MSL;delete(Mod, [Ha|MSL]) when Ha#handler.module =:= Mod,                           not Ha#handler.id ->    MSL;delete(Handler, [Ha|MSL]) ->    [Ha|delete(Handler, MSL)];delete(_, []) ->    [].replace({Mod, Id}, [Ha|MSL], NewHa) when Ha#handler.module =:= Mod,                                         Ha#handler.id =:= Id ->    [NewHa|MSL];replace(Mod, [Ha|MSL], NewHa) when Ha#handler.module =:= Mod,                                   not Ha#handler.id ->    [NewHa|MSL];replace(Handler, [Ha|MSL], NewHa) ->    [Ha|replace(Handler, MSL, NewHa)];replace(_, [], NewHa) ->    [NewHa].%% server_call_update(Handler, Query, ServerName) ->%%    {{Handler1, State1} | no, Reply}server_call_update(Handler1, Query, SName) ->    Mod1 = Handler1#handler.module,    State = Handler1#handler.state,    case catch Mod1:handle_call(Query, State) of	{ok, Reply, State1} -> 	    {{ok, Handler1#handler{state = State1}}, Reply};	{swap_handler, Reply, Args1, State1, Handler2, Args2} ->	    {do_swap(Mod1,Handler1,Args1,State1,Handler2,Args2,SName), Reply};	{remove_handler, Reply} -> 	    do_terminate(Mod1, Handler1, remove_handler, State,			 remove, SName, normal),	    {no, Reply};	Other ->	    do_terminate(Mod1, Handler1, {error, Other}, State,			 Query, SName, crash),	    {no, {error, Other}}end.do_terminate(Mod, Handler, Args, State, LastIn, SName, Reason) ->    Res = (catch Mod:terminate(Args, State)),    report_terminate(Handler, Reason, Args, State, LastIn, SName, Res),    Res.report_terminate(Handler, crash, {error, Why}, State, LastIn, SName, _) ->    report_terminate(Handler, Why, State, LastIn, SName);report_terminate(Handler, How, _, State, LastIn, SName, _) ->    %% How == normal | shutdown | {swapped, NewHandler, NewSupervisor}    report_terminate(Handler, How, State, LastIn, SName).report_terminate(Handler, Reason, State, LastIn, SName) ->    report_error(Handler, Reason, State, LastIn, SName),    case Handler#handler.supervised of	false ->	    ok;	Pid ->	    Pid ! {gen_event_EXIT,handler(Handler),Reason},	    ok    end.report_error(_Handler, normal, _, _, _)               -> ok;report_error(_Handler, shutdown, _, _, _)             -> ok;report_error(_Handler, {swapped,_,_}, _, _, _)        -> ok;report_error(Handler, Reason, State, LastIn, SName)   ->    Reason1 = 	case Reason of	    {'EXIT',{undef,[{M,F,A}|MFAs]}} ->		case code:is_loaded(M) of		    false ->			{'module could not be loaded',[{M,F,A}|MFAs]};		    _ ->			case erlang:function_exported(M, F, length(A)) of			    true ->				{undef,[{M,F,A}|MFAs]};			    false ->				{'function not exported',[{M,F,A}|MFAs]}			end		end;	    {'EXIT',Why} -> 		Why;	    _ ->            		Reason	end,    error_msg("** gen_event handler ~p crashed.~n"	      "** Was installed in ~p~n"	      "** Last event was: ~p~n"	      "** When handler state == ~p~n"	      "** Reason == ~p~n",	      [handler(Handler),SName,LastIn,State,Reason1]).handler(Handler) when not Handler#handler.id ->    Handler#handler.module;handler(Handler) ->    {Handler#handler.module, Handler#handler.id}.%% stop_handlers(MSL, ServerName) -> []stop_handlers([Handler|T], SName) ->    Mod = Handler#handler.module,    do_terminate(Mod, Handler, stop, Handler#handler.state,		 stop, SName, shutdown),    stop_handlers(T, SName);stop_handlers([], _) ->    [].the_handlers(MSL) ->    lists:map(fun(Handler) when not Handler#handler.id ->		      Handler#handler.module;		 (Handler) ->		      {Handler#handler.module, Handler#handler.id}	      end,	      MSL).%% Message from the release_handler.%% The list of modules got to be a set !get_modules(MSL) ->    Mods = lists:map(fun(Handler) -> Handler#handler.module end,		     MSL),    ordsets:to_list(ordsets:from_list(Mods)).%%-----------------------------------------------------------------%% Status information%%-----------------------------------------------------------------format_status(_Opt, StatusData) ->    [_PDict, SysState, Parent, _Debug, [ServerName, MSL]] = StatusData,    Header = lists:concat(["Status for event handler ", ServerName]),    [{header, Header},     {data, [{"Status", SysState},	     {"Parent", Parent}]},     {items, {"Installed handlers", MSL}}].

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?