diff options
Diffstat (limited to 'lib/megaco/src/tcp/megaco_tcp_accept.erl')
-rw-r--r-- | lib/megaco/src/tcp/megaco_tcp_accept.erl | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/lib/megaco/src/tcp/megaco_tcp_accept.erl b/lib/megaco/src/tcp/megaco_tcp_accept.erl new file mode 100644 index 0000000000..68bda8a340 --- /dev/null +++ b/lib/megaco/src/tcp/megaco_tcp_accept.erl @@ -0,0 +1,123 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1999-2009. All Rights Reserved. +%% +%% 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 online 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. +%% +%% %CopyrightEnd% +%% + +%% +%%----------------------------------------------------------------- +%% Purpose: Waiting in accept for new connections. +%%----------------------------------------------------------------- +-module(megaco_tcp_accept). + +%%----------------------------------------------------------------- +%% Include files +%%----------------------------------------------------------------- +-include_lib("megaco/src/tcp/megaco_tcp.hrl"). +-include_lib("megaco/src/app/megaco_internal.hrl"). + + +-define(d1(F, A), ?d("~p " ++ F, [self()|A])). +-define(d2(F), ?d1(F, [])). + + +%%----------------------------------------------------------------- +%% External exports +%%----------------------------------------------------------------- +-export([ + start_link/1 + ]). + + +%%----------------------------------------------------------------- +%% Internal exports +%%----------------------------------------------------------------- +-export([ + net_accept/4 + ]). + + +%%----------------------------------------------------------------- +%% External interface functions +%%----------------------------------------------------------------- +%%----------------------------------------------------------------- +%% Func: start +%% Description: Starts the proces that makes the accept call. +%%----------------------------------------------------------------- +start_link({TcpRec, SupPid, Listen}) -> + Args = [TcpRec, SupPid, Listen, self()], + Pid = proc_lib:spawn_link(?MODULE, net_accept, Args), + {ok, Pid}. + +%%----------------------------------------------------------------- +%% Internal Interface Functions +%%----------------------------------------------------------------- +%%----------------------------------------------------------------- +%% Func: net_accept +%% Description: Loop function which calls accept and +%% spawns a connection process when there is an initial +%% contact. +%%----------------------------------------------------------------- +net_accept(TcpRec, SupPid, ListenFd, Parent) -> + do_accept(TcpRec, SupPid, ListenFd), + net_accept(TcpRec, SupPid, ListenFd, Parent). + +do_accept(Tcp, Sup, Fd) -> + case gen_tcp:accept(Fd) of + {ok, S} -> + ?d1("do_accept -> accepted: " + "~n S: ~p", [S]), + case megaco_tcp:start_connection(Sup, + Tcp#megaco_tcp{socket = S}) of + {ok, Pid} -> + ?d1("do_accept -> connection started" + "~n Pid: ~p", [Pid]), + case gen_tcp:controlling_process(S, Pid) of + ok -> + ?d2("do_accept -> control transferred"), + ok; + {error, _Reason} -> + ?d1("do_accept -> " + "failed changing controlling process: " + "n _Reason: ~p", [_Reason]), + tcp_clear(S), + gen_tcp:close(S) + end; + + {error, _Reason} -> + ?d1("do_accept -> failed starting connection: " + "~n _Reason: ~p", [_Reason]), + tcp_clear(S), + gen_tcp:close(S) + end; + {error, _Reason} -> + ?d1("do_accept -> accept failed: " + "~n _Reason: ~p", [_Reason]), + ok + end. + + +tcp_clear(Socket) -> + receive + {tcp, Socket, _Data} -> + tcp_clear(Socket); + {tcp_closed, Socket} -> + tcp_clear(Socket); + {tcp_error, Socket} -> + tcp_clear(Socket) + after 0 -> + ok + end. |