diff options
Diffstat (limited to 'src/couch_inets/httpd_instance_sup.erl')
-rw-r--r-- | src/couch_inets/httpd_instance_sup.erl | 193 |
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}. |