aboutsummaryrefslogtreecommitdiff
path: root/src/tcp_serv.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/tcp_serv.erl')
-rw-r--r--src/tcp_serv.erl156
1 files changed, 71 insertions, 85 deletions
diff --git a/src/tcp_serv.erl b/src/tcp_serv.erl
index 51e00dcc3..7607647ec 100644
--- a/src/tcp_serv.erl
+++ b/src/tcp_serv.erl
@@ -3,10 +3,10 @@
%%
%% Redistribution and use in source and binary forms, with or without
%% modification, are permitted provided that the following conditions
-%% are met:
+%% are met:
%%
%% 1. Redistributions of source code must retain the above copyright
-%% notice, this list of conditions and the following disclaimer.
+%% notice, this list of conditions and the following disclaimer.
%% 2. Redistributions in binary form must reproduce the above
%% copyright notice, this list of conditions and the following
%% disclaimer in the documentation and/or other materials provided
@@ -25,41 +25,34 @@
%% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-module(tcp_serv).
+
-vsn("1.13").
+
-author('jocke@gleipnir.com').
+
-export([start_link/1, start_link/2, stop/1, stop/2]).
+
-export([init/2, start_session/3]).
+
-export([system_continue/3, system_terminate/4]).
-include("log.hrl").
--record(state, {
- %% int()
- max_sessions,
- %% {M, F, A}
- %% M = F = atom()
- %% A = [term()]
- session_handler,
- %% [pid()]
- session_list,
- %% socket()
- listen_socket,
- %% pid()
- parent,
- %% term()
- debug_info
- }).
+-record(state,
+ {max_sessions, session_handler, session_list,
+ listen_socket, parent, debug_info}).
%% Exported: start_link/{1,2}
start_link(Args) -> start_link(Args, 60000).
-
+
start_link(Args, Timeout) ->
- Pid = proc_lib:spawn_link(?MODULE, init, [self(), Args]),
+ Pid = proc_lib:spawn_link(?MODULE, init,
+ [self(), Args]),
receive
- {Pid, started} -> {ok, Pid};
- {Pid, Reason} -> {error, Reason}
- after Timeout -> {error, timeout}
+ {Pid, started} -> {ok, Pid};
+ {Pid, Reason} -> {error, Reason}
+ after Timeout -> {error, timeout}
end.
%% Exported: stop/{1,2}
@@ -67,90 +60,83 @@ start_link(Args, Timeout) ->
stop(Pid) -> stop(Pid, 15000).
stop(Pid, Timeout) ->
- Pid ! {self(), stop},
+ Pid ! {self(), stop},
receive
- {Pid, Reply} -> Reply
- after
- Timeout -> {error, timeout}
+ {Pid, Reply} -> Reply after Timeout -> {error, timeout}
end.
%% Exported: init/2
-init(Parent, [Port, MaxSessions, OptionList, SessionHandler]) ->
+init(Parent,
+ [Port, MaxSessions, OptionList, SessionHandler]) ->
process_flag(trap_exit, true),
case gen_tcp:listen(Port, OptionList) of
- {ok, ListenSocket} ->
- self() ! start_session,
- Parent ! {self(), started},
- loop(#state{max_sessions = MaxSessions,
- session_handler = SessionHandler,
- session_list = [],
- listen_socket = ListenSocket,
- parent = Parent});
- Reason -> Parent ! {self(), {not_started, Reason}}
+ {ok, ListenSocket} ->
+ self() ! start_session,
+ Parent ! {self(), started},
+ loop(#state{max_sessions = MaxSessions,
+ session_handler = SessionHandler, session_list = [],
+ listen_socket = ListenSocket, parent = Parent});
+ Reason -> Parent ! {self(), {not_started, Reason}}
end.
-loop(#state{session_list = SessionList, listen_socket = ListenSocket,
- parent = Parent} = State) ->
+loop(#state{session_list = SessionList,
+ listen_socket = ListenSocket, parent = Parent} =
+ State) ->
receive
- {From, stop} ->
- cleanup(State),
- From ! {self(), ok};
- start_session when length(SessionList) > State#state.max_sessions ->
- timer:sleep(5000),
- self() ! start_session,
- loop(State);
- start_session ->
- A = [self(), State#state.session_handler, ListenSocket],
- Pid = proc_lib:spawn_link(?MODULE, start_session, A),
- loop(State#state{session_list = [Pid|SessionList]});
- {'EXIT', Parent, Reason} ->
- cleanup(State),
- exit(Reason);
- {'EXIT', Pid, Reason} ->
- case lists:member(Pid, SessionList) of
- true ->
- PurgedSessionList = lists:delete(Pid, SessionList),
- loop(State#state{session_list = PurgedSessionList});
- false ->
- ?ERROR_LOG({ignoring, {'EXIT', Pid, Reason}}),
- loop(State)
- end;
- {system, From, Request} ->
- sys:handle_system_msg(Request, From, Parent, ?MODULE,
- State#state.debug_info, State);
- UnknownMessage ->
- ?ERROR_LOG({unknown_message, UnknownMessage}),
- loop(State)
+ {From, stop} -> cleanup(State), From ! {self(), ok};
+ start_session
+ when length(SessionList) > State#state.max_sessions ->
+ timer:sleep(5000), self() ! start_session, loop(State);
+ start_session ->
+ A = [self(), State#state.session_handler, ListenSocket],
+ Pid = proc_lib:spawn_link(?MODULE, start_session, A),
+ loop(State#state{session_list = [Pid | SessionList]});
+ {'EXIT', Parent, Reason} ->
+ cleanup(State), exit(Reason);
+ {'EXIT', Pid, Reason} ->
+ case lists:member(Pid, SessionList) of
+ true ->
+ PurgedSessionList = lists:delete(Pid, SessionList),
+ loop(State#state{session_list = PurgedSessionList});
+ false ->
+ ?ERROR_LOG({ignoring, {'EXIT', Pid, Reason}}),
+ loop(State)
+ end;
+ {system, From, Request} ->
+ sys:handle_system_msg(Request, From, Parent, ?MODULE,
+ State#state.debug_info, State);
+ UnknownMessage ->
+ ?ERROR_LOG({unknown_message, UnknownMessage}),
+ loop(State)
end.
-cleanup(State) -> gen_tcp:close(State#state.listen_socket).
+cleanup(State) ->
+ gen_tcp:close(State#state.listen_socket).
%% Exported: start_seesion/3
start_session(Parent, {M, F, A}, ListenSocket) ->
case gen_tcp:accept(ListenSocket) of
- {ok, Socket} ->
- Parent ! start_session,
- case apply(M, F, [Socket|A]) of
- ok -> gen_tcp:close(Socket);
- {error, closed} -> ok;
- {error, Reason} ->
- ?ERROR_LOG({M, F, Reason}),
- gen_tcp:close(Socket)
- end;
- {error, Reason} ->
- timer:sleep(5000),
- Parent ! start_session
+ {ok, Socket} ->
+ Parent ! start_session,
+ case apply(M, F, [Socket | A]) of
+ ok -> gen_tcp:close(Socket);
+ {error, closed} -> ok;
+ {error, Reason} ->
+ ?ERROR_LOG({M, F, Reason}), gen_tcp:close(Socket)
+ end;
+ {error, _Reason} ->
+ timer:sleep(5000), Parent ! start_session
end.
%% Exported: system_continue/3
system_continue(Parent, DebugInfo, State) ->
- loop(State#state{parent = Parent, debug_info = DebugInfo}).
+ loop(State#state{parent = Parent,
+ debug_info = DebugInfo}).
%% Exported: system_terminate/3
-system_terminate(Reason, Parent, DebugInfo, State) ->
- cleanup(State),
- exit(Reason).
+system_terminate(Reason, _Parent, _DebugInfo, State) ->
+ cleanup(State), exit(Reason).