summaryrefslogtreecommitdiff
path: root/src/couch_inets/httpd_instance_sup.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/couch_inets/httpd_instance_sup.erl')
-rw-r--r--src/couch_inets/httpd_instance_sup.erl193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/couch_inets/httpd_instance_sup.erl b/src/couch_inets/httpd_instance_sup.erl
new file mode 100644
index 00000000..ddf81a49
--- /dev/null
+++ b/src/couch_inets/httpd_instance_sup.erl
@@ -0,0 +1,193 @@
+%% ``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 via the world wide web 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.
+%%
+%% The Initial Developer of the Original Code is Ericsson Utvecklings AB.
+%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
+%% AB. All Rights Reserved.''
+%%
+%% $Id$
+%%
+%%----------------------------------------------------------------------
+%% Purpose: The top supervisor for an instance of the http server. (You may
+%% have several instances running on the same machine.) Hangs under
+%% httpd_sup.
+%%----------------------------------------------------------------------
+
+-module(httpd_instance_sup).
+
+-behaviour(supervisor).
+
+-export([init/1]).
+
+%% Internal API
+-export([start/1, start_link/1, start_link/3, start2/1, start_link2/1,
+ stop/1, stop/2, stop2/1]).
+
+%%%=========================================================================
+%%% Supervisor callback
+%%%=========================================================================
+init([ConfigFile, ConfigList, AcceptTimeout, Debug, Addr, Port]) ->
+ httpd_util:enable_debug(Debug),
+ Flags = {one_for_one, 0, 1},
+ Children = [sup_spec(httpd_acceptor_sup, Addr, Port),
+ sup_spec(httpd_misc_sup, Addr, Port),
+ worker_spec(httpd_manager, Addr, Port,
+ ConfigFile, ConfigList,AcceptTimeout)],
+ {ok, {Flags, Children}}.
+
+
+%%%=========================================================================
+%%% ??? functions
+%%%=========================================================================
+
+start(ConfigFile) ->
+ case start_link(ConfigFile) of
+ {ok, Pid} ->
+ unlink(Pid),
+ {ok, Pid};
+
+ Else ->
+ Else
+ end.
+
+start_link(Config) ->
+ case catch httpd_options(Config) of
+ {error,Reason} ->
+ error_logger:error_report(Reason),
+ {stop, Reason};
+ {ConfigFile,AcceptTimeout,Debug} ->
+ start_link(ConfigFile, AcceptTimeout, Debug)
+ end.
+start_link(ConfigFile, AcceptTimeout, Debug) ->
+ case get_addr_and_port(ConfigFile) of
+ {ok, ConfigList, Addr, Port} ->
+ Name = make_name(Addr, Port),
+ SupName = {local, Name},
+ supervisor:start_link(SupName, ?MODULE,
+ [ConfigFile, ConfigList ,AcceptTimeout ,
+ Debug, Addr, Port]);
+ {error, Reason} ->
+ error_logger:error_report(Reason),
+ {stop, Reason}
+ end.
+
+
+start2(ConfigList) ->
+ case start_link2(ConfigList) of
+ {ok, Pid} ->
+ unlink(Pid),
+ {ok, Pid};
+
+ Else ->
+ Else
+ end.
+
+
+start_link2(ConfigList) ->
+ {ok, Addr, Port} = get_addr_and_port2(ConfigList),
+ Name = make_name(Addr, Port),
+ SupName = {local, Name},
+ Debug = [],
+ AcceptTimeout = 15000,
+ supervisor:start_link(SupName, ?MODULE,
+ [undefined, ConfigList, AcceptTimeout,
+ Debug, Addr, Port]).
+
+
+stop(Pid) when pid(Pid) ->
+ do_stop(Pid);
+stop(ConfigFile) when list(ConfigFile) ->
+ case get_addr_and_port(ConfigFile) of
+ {ok, _, Addr, Port} ->
+ stop(Addr, Port);
+
+ Error ->
+ Error
+ end;
+stop(_StartArgs) ->
+ ok.
+
+
+stop(Addr, Port) when integer(Port) ->
+ Name = make_name(Addr, Port),
+ case whereis(Name) of
+ Pid when pid(Pid) ->
+ do_stop(Pid),
+ ok;
+ _ ->
+ not_started
+ end.
+
+
+stop2(ConfigList) when list(ConfigList) ->
+ {ok, Addr, Port} = get_addr_and_port2(ConfigList),
+ stop(Addr, Port).
+
+%%%=========================================================================
+%%% Internal functions
+%%%=========================================================================
+do_stop(Pid) ->
+ exit(Pid, shutdown).
+
+sup_spec(SupModule, Addr, Port) ->
+ Name = {SupModule, Addr, Port},
+ StartFunc = {SupModule, start_link, [Addr, Port]},
+ Restart = permanent,
+ Shutdown = infinity,
+ Modules = [SupModule],
+ Type = supervisor,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+
+worker_spec(WorkerModule, Addr, Port, ConfigFile, ConfigList, AcceptTimeout) ->
+ Name = {WorkerModule, Addr, Port},
+ StartFunc = {WorkerModule, start_link,
+ [ConfigFile, ConfigList, AcceptTimeout]},
+ Restart = permanent,
+ Shutdown = 4000,
+ Modules = [WorkerModule],
+ Type = worker,
+ {Name, StartFunc, Restart, Shutdown, Type, Modules}.
+
+httpd_options(Config) ->
+ OptionList = mk_tuple_list(Config),
+ Debug = http_util:key1search(OptionList,debug,[]),
+ AcceptTimeout = http_util:key1search(OptionList,accept_timeout,15000),
+ ConfigFile =
+ case http_util:key1search(OptionList,file) of
+ undefined -> throw({error,{mandatory_conf_file_missed}});
+ File -> File
+ end,
+ httpd_util:valid_options(Debug,AcceptTimeout,ConfigFile),
+ {ConfigFile, AcceptTimeout, Debug}.
+
+mk_tuple_list([]) ->
+ [];
+mk_tuple_list([H={_,_}|T]) ->
+ [H|mk_tuple_list(T)];
+mk_tuple_list(F) when list(F) ->
+ [{file,F}].
+
+make_name(Addr,Port) ->
+ httpd_util:make_name("httpd_instance_sup",Addr,Port).
+
+get_addr_and_port(ConfigFile) ->
+ case httpd_conf:load(ConfigFile) of
+ {ok, ConfigList} ->
+ {ok, Addr, Port} = get_addr_and_port2(ConfigList),
+ {ok, ConfigList, Addr, Port};
+ Error ->
+ Error
+ end.
+
+get_addr_and_port2(ConfigList) ->
+ Port = httpd_util:key1search(ConfigList, port, 80),
+ Addr = httpd_util:key1search(ConfigList, bind_address),
+ {ok, Addr, Port}.