Current section

Files

Jump to
radius src radius_sup.erl
Raw

src/radius_sup.erl

-module(radius_sup).
-behaviour(supervisor).
%% API
-export([start_link/0, start_child/1]).
%% supervisor callbacks
-export([init/1]).
-define(TABLES, [
{radius_clients, [{read_concurrency, true}]},
{radius_dict_attrs, [{keypos, 2}, {read_concurrency, true}]},
{radius_dict_values, [{read_concurrency, true}]}
]).
-define(SPEC(Id, Name, IP, Port, Callback, SocketOpts),
{Id, {radius_service, start_link, [Name, IP, Port, Callback, SocketOpts]},
transient, brutal_kill, worker, [radius_service]}
).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
start_child([Name, IP, Port, Callback, SocketOpts]) ->
case proplists:get_value(reuseport, SocketOpts) of
N when is_integer(N) andalso N > 1 ->
NewSocketOpts = reuseport(SocketOpts),
F = fun(Idx) ->
Id = list_to_atom(atom_to_list(Name) ++ integer_to_list(Idx)),
supervisor:start_child(?MODULE, ?SPEC(Id, Name, IP, Port, Callback, NewSocketOpts))
end,
lists:foreach(F, lists:seq(1, N));
_ ->
supervisor:start_child(?MODULE, ?SPEC(Name, Name, IP, Port, Callback, SocketOpts))
end.
init([]) ->
ok = create_table(?TABLES),
{ok, {{one_for_one, 5, 10}, []}}.
%% Internal functions
create_table(Tables) when is_list(Tables) ->
lists:foreach(fun create_table/1, Tables);
create_table({Table, Options}) ->
ets:new(Table, [named_table, public | Options]).
reuseport(Options) ->
NewOptions = case os:type() of
{unix, linux} ->
Options ++ [{raw, 1, 15, <<1:32/native>>}];
{unix, OsName} ->
case lists:member(OsName, [darwin, freebsd, openbsd, netbsd]) of
true ->
Options ++ [{raw, 16#FFFF, 16#0200, <<1:32/native>>}];
false ->
Options
end;
_ -> Options
end,
lists:keydelete(reuseport, 1, NewOptions).