%%% Copyright (c) 2019, Sunet. %%% See LICENSE for licensing information. -module(p11p_server_sup). -behaviour(supervisor). -export([start_link/0, start_server/1]). -export([init/1, cleanup/0]). start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> ok = start_servers(p11p_config:nameof(p11p_config:tokens())), {ok, {{simple_one_for_one, 1, 5}, [{sock_server, {p11p_server, start_link, []}, temporary, 1000, worker, [p11p_server]} ]}}. start_server(Args) -> {ok, Pid} = supervisor:start_child(?MODULE, [Args]), Pid. cleanup() -> cleanup(p11p_config:nameof(p11p_config:tokens())). %% Private functions. start_servers([]) -> ok; start_servers([Name|T]) -> Path = socket_path(mkdir_socket_basepath(), Name), file:delete(Path), %% TODO: Consider flow control using {active, once}. %% And if so, don't forget activating after read. {ok, Socket} = gen_tcp:listen(0, [{ifaddr, {local, Path}}, binary]), spawn_link(?MODULE, start_server, [[Name, Socket]]), start_servers(T). cleanup([]) -> ok; cleanup([Token|Tail]) -> file:delete(socket_path(mkdir_socket_basepath(), Token)), cleanup(Tail). mkdir_socket_basepath() -> Dir = p11p_config:socket_dir(), ok = case file:make_dir(Dir) of ok -> ok; {error, eexist} -> ok; Err -> lager:error("~s: unable to create directory: ~p", [Dir, Err]), err end, Dir. -spec socket_path(string(), string()) -> string(). socket_path(BasePath, Name) -> case p11p_config:socket_path_has_pid() of true -> BasePath ++ "/" ++ Name ++ "-" ++ os:getpid(); false -> BasePath ++ "/" ++ Name end.