⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 megaco_monitor.erl

📁 OTP是开放电信平台的简称
💻 ERL
字号:
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%%%----------------------------------------------------------------------%% Purpose: Monitor connections and timers%%-----------------------------------------------------------------------module(megaco_monitor).-behaviour(gen_server).%%-----------------------------------------------------------------%% Include files%%------------------------------------------------------------------include_lib("megaco/src/app/megaco_internal.hrl"). %% Application internal exports-export([	 start_link/0,	 stop/0,	 apply_after/4,	 apply_after/5,	 cancel_apply_after/1,	 lookup_request/1,	 match_requests/1,	 which_requests/1,	 insert_request/1,	 delete_request/1, 	 lookup_reply/1,	 match_replies/1,	 which_replies/1,	 insert_reply/1,	 delete_reply/1,	 apply_at_exit/4,	 cancel_apply_at_exit/1	]).%% gen_server callbacks-export([init/1, handle_call/3, handle_cast/2, handle_info/2,	 terminate/2, code_change/3]).-define(SERVER, ?MODULE).-record(state, {parent_pid}).-record(apply_at_exit, {ref, pid, module, function, arguments}).%%%----------------------------------------------------------------------%%% API%%%----------------------------------------------------------------------start_link() ->    ?d("start -> entry", []),    gen_server:start_link({local, ?SERVER}, ?MODULE, [self()], []).stop() ->    call(stop).lookup_request(Key) ->    ets:lookup(megaco_requests, Key).match_requests(Pat) ->    ets:match_object(megaco_requests, Pat).which_requests(Pat) ->    Spec = [{Pat, [], ['$$']}],    ets:select(megaco_requests, Spec).insert_request(Rec) ->    ets:insert(megaco_requests, Rec).delete_request(Key) ->    ets:delete(megaco_requests, Key).lookup_reply(Key) ->    ets:lookup(megaco_replies, Key).match_replies(Pat) ->    ets:match_object(megaco_replies, Pat).which_replies(Pat) ->    Spec = [{Pat, [], ['$$']}],    ets:select(megaco_replies, Spec).insert_reply(Rec) ->    ets:insert(megaco_replies, Rec).delete_reply(Key) ->    ets:delete(megaco_replies, Key).apply_after(M, F, A, Time) ->    apply_after(spawn_method, M, F, A, Time).apply_after(Method, M, F, A, Time) when atom(M), atom(F), list(A) ->    if	Time == infinity ->	    apply_after_infinity;	integer(Time) ->	    Msg = {apply_after, Method, M, F, A},	    Ref = erlang:send_after(Time, whereis(?SERVER), Msg),	    {apply_after, Ref}    end.cancel_apply_after({apply_after, Ref}) ->    case erlang:cancel_timer(Ref) of	TimeLeft when integer(TimeLeft) ->	    {ok, TimeLeft};	_ ->	    {ok, 0}    end;cancel_apply_after(apply_after_infinity) ->    ok;cancel_apply_after(BadRef) ->    {error, {bad_ref, BadRef}}.%% Performs apply(M, F, [Reason | A]) when process Pid diesapply_at_exit(M, F, A, Pid)   when atom(M), atom(F), list(A), pid(Pid) ->    Ref = call({apply_at_exit, M, F, A, Pid}),    {apply_at_exit, Ref}.cancel_apply_at_exit({apply_at_exit, Ref}) ->    cast({cancel_apply_at_exit, Ref});cancel_apply_at_exit(BadRef) ->    {error, {bad_ref, BadRef}}.    call(Request) ->    gen_server:call(?SERVER, Request, infinity).cast(Msg) ->    ?SERVER ! Msg, ok.%%%----------------------------------------------------------------------%%% Callback functions from gen_server%%%----------------------------------------------------------------------%%----------------------------------------------------------------------%% Func: init/1%% Returns: {ok, State}          |%%          {ok, State, Timeout} |%%          ignore               |%%          {stop, Reason}%%----------------------------------------------------------------------init([Parent]) ->    ?d("init -> entry", []),    process_flag(trap_exit, true),    ets:new(megaco_requests, [public, named_table, {keypos, 2}]),    ets:new(megaco_replies,  [public, named_table, {keypos, 2}]),    ?d("init -> done", []),    {ok, #state{parent_pid = Parent}}.%%----------------------------------------------------------------------%% Func: handle_call/3%% Returns: {reply, Reply, State}          |%%          {reply, Reply, State, Timeout} |%%          {noreply, State}               |%%          {noreply, State, Timeout}      |%%          {stop, Reason, Reply, State}   | (terminate/2 is called)%%          {stop, Reason, State}            (terminate/2 is called)%%----------------------------------------------------------------------handle_call({apply_at_exit, M, F, A, Pid}, _From, S) ->    Ref = erlang:monitor(process, Pid),    AAE = #apply_at_exit{ref       = Ref,			 pid       = Pid,			 module    = M,			 function  = F,			 arguments = A},    put({?MODULE, Ref}, AAE),    Reply = Ref,    {reply, Reply, S};handle_call(stop, {Parent, _} = _From, #state{parent_pid = Parent} = S) ->    {stop, normal, ok, S};handle_call(Req, From, S) ->    warning_msg("received unexpected request from ~p: "		"~n~w",[From, Req]),    {reply, {error, {bad_request, Req}}, S}.%%----------------------------------------------------------------------%% Func: handle_cast/2%% Returns: {noreply, State}          |%%          {noreply, State, Timeout} |%%          {stop, Reason, State}            (terminate/2 is called)%%----------------------------------------------------------------------handle_cast(Msg, S) ->    warning_msg("received unexpected message: "		"~n~w", [Msg]),    {noreply, S}.%%----------------------------------------------------------------------%% Func: handle_info/2%% Returns: {noreply, State}          |%%          {noreply, State, Timeout} |%%          {stop, Reason, State}            (terminate/2 is called)%%----------------------------------------------------------------------handle_info({cancel_apply_at_exit, Ref}, S) ->    case erase({?MODULE, Ref}) of	undefined ->	    %% Reply = {error, {already_cancelled, {apply_at_exit, Ref}}},	    {noreply, S};	_AAE ->	    erlang:demonitor(Ref),	    {noreply, S}    end;handle_info({apply_after, Method, M, F, A}, S) ->    handle_apply(Method, M, F, A, apply_after),    {noreply, S};%% Handle the old format also...handle_info({apply_after, M, F, A}, S) ->    handle_apply(M, F, A, apply_after),    {noreply, S};handle_info({'DOWN', Ref, process, _Pid, Reason}, S) ->    case erase({?MODULE, Ref}) of	undefined ->	    {noreply, S};	AAE ->	    M = AAE#apply_at_exit.module,	    F = AAE#apply_at_exit.function,	    A = AAE#apply_at_exit.arguments,	    handle_apply(M, F, [Reason | A], apply_at_exit),	    {noreply, S}    end;handle_info({'EXIT', Pid, Reason}, S) when Pid == S#state.parent_pid ->    %% [megaco_messenger:disconnect(CH, {stopped, Reason})    %% 	|| CH <- megaco:lookup_system_info(connections)],    {stop, Reason, S};handle_info(Info, S) ->    warning_msg("received unknown info: "		"~n~w", [Info]),    {noreply, S}.%%----------------------------------------------------------------------%% Func: terminate/2%% Purpose: Shutdown the server%% Returns: any (ignored by gen_server)%%----------------------------------------------------------------------terminate(_Reason, _State) ->    ok.%%----------------------------------------------------------------------%% Func: code_change/3%% Purpose: Convert process state when code is changed%% Returns: {ok, NewState}%%----------------------------------------------------------------------code_change(_Vsn, S, _Extra) ->    {ok, S}.%%%----------------------------------------------------------------------%%% Internal functions%%%----------------------------------------------------------------------handle_apply(M, F, A, _ErrorTag) ->    spawn(M, F, A).handle_apply(spawn_method, M, F, A, _ErrorTag) ->    spawn(M, F, A);handle_apply(_Method, M, F, A, _ErrorTag) ->    (catch apply(M, F, A)).warning_msg(F, A) ->    ?megaco_warning("Monitor server: " ++ F, A).% d(F) ->%     d(F,[]).% d(F,A) ->%     %% d(true,F,A).%     d(get(dbg),F,A).% d(true,F,A) ->%     io:format("*** [~s] ~p:~p ***"% 	      "~n   " ++ F ++ "~n", % 	      [format_timestamp(now()), self(),?MODULE|A]);% d(_, _, _) ->%     ok.% format_timestamp(Now) ->%     {N1, N2, N3}   = Now,%     {Date, Time}   = calendar:now_to_datetime(Now),%     {YYYY,MM,DD}   = Date,%     {Hour,Min,Sec} = Time,%     FormatDate = %         io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",%                       [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),  %     lists:flatten(FormatDate).

⌨️ 快捷键说明

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