view server/awetv/src/awelistener.erl @ 0:db5c7047ef0e default tip

Initial commit
author Mike Pavone <pavone@retrodev.com>
date Fri, 21 Jun 2013 22:09:34 -0700
parents
children
line wrap: on
line source

-module(awelistener).
-behavior(gen_server).

-export([start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2]).

start_link() ->
	gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).


init(_Args) ->
	Port = 5432,
	Listeners = 2,
	{ok, Socket} = gen_tcp:listen(Port, [{active, false}, binary]),
	Children = [spawn_link(fun () -> accept_loop(Socket) end) || _ <- lists:seq(1, Listeners)],
	{ok, {Socket, Children}}.

handle_call(_Msg, _From, State) ->
	{noreply, State}.

handle_cast(_Msg, State) ->
	{noreply, State}.

handle_info({'EXIT', Pid, Reason}, {Socket, Children}) ->
	io:format("Accept worker exited due to reason ~p~n", [Reason]),
	case Reason of
		shutdown -> {noreply, {Socket, []}};
		_ ->  {noreply, {Socket, replace_worker(Pid, Socket, Children)}}
	end.

terminate(shutdown, {Socket, Children}) ->
	lists:foreach(
		fun(Child) ->
			exit(Child, shutdown)
		end, Children),
	socket:close(Socket),
	ok.

accept_loop(Socket) ->
	{ok, ClientSock} = gen_tcp:accept(Socket),
	io:format("Got new connection~n"),
	aweconn:start(ClientSock),
	accept_loop(Socket).

replace_worker(_, _, []) ->
	[];
replace_worker(Pid, Socket, [Pid | Rest]) ->
	[spawn_link(fun() -> accept_loop(Socket) end) | Rest];
replace_worker(Pid, Socket, [OtherPid | Rest]) ->
	[OtherPid | replace_worker(Pid, Socket, Rest)].