You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2010/06/14 15:35:11 UTC
svn commit: r954453 - in /couchdb/branches/0.11.x: src/couchdb/ test/etap/
Author: jan
Date: Mon Jun 14 13:35:11 2010
New Revision: 954453
URL: http://svn.apache.org/viewvc?rev=954453&view=rev
Log:
Revert "Merge r918805 from trunk:"
This reverts commit 2736068598d608f13a6e1e1a88b2888ff8905f85.
Modified:
couchdb/branches/0.11.x/src/couchdb/couch_config.erl
couchdb/branches/0.11.x/src/couchdb/couch_db.erl
couchdb/branches/0.11.x/src/couchdb/couch_db_updater.erl
couchdb/branches/0.11.x/src/couchdb/couch_external_server.erl
couchdb/branches/0.11.x/src/couchdb/couch_file.erl
couchdb/branches/0.11.x/src/couchdb/couch_native_process.erl
couchdb/branches/0.11.x/src/couchdb/couch_os_process.erl
couchdb/branches/0.11.x/src/couchdb/couch_query_servers.erl
couchdb/branches/0.11.x/src/couchdb/couch_ref_counter.erl
couchdb/branches/0.11.x/src/couchdb/couch_server.erl
couchdb/branches/0.11.x/src/couchdb/couch_server_sup.erl
couchdb/branches/0.11.x/src/couchdb/couch_stats_collector.erl
couchdb/branches/0.11.x/src/couchdb/couch_util.erl
couchdb/branches/0.11.x/src/couchdb/couch_view.erl
couchdb/branches/0.11.x/src/couchdb/couch_view_group.erl
couchdb/branches/0.11.x/test/etap/010-file-basics.t
couchdb/branches/0.11.x/test/etap/040-util.t
Modified: couchdb/branches/0.11.x/src/couchdb/couch_config.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_config.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_config.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_config.erl Mon Jun 14 13:35:11 2010
@@ -111,7 +111,7 @@ terminate(_Reason, _State) ->
handle_call(all, _From, Config) ->
Resp = lists:sort((ets:tab2list(?MODULE))),
{reply, Resp, Config};
-handle_call({set, Sec, Key, Val, Persist}, From, Config) ->
+handle_call({set, Sec, Key, Val, Persist}, _From, Config) ->
true = ets:insert(?MODULE, {{Sec, Key}, Val}),
case {Persist, Config#config.write_filename} of
{true, undefined} ->
@@ -121,12 +121,9 @@ handle_call({set, Sec, Key, Val, Persist
_ ->
ok
end,
- spawn_link(fun() ->
- [catch F(Sec, Key, Val, Persist) || {_Pid, F} <- Config#config.notify_funs],
- gen_server:reply(From, ok)
- end),
- {noreply, Config};
-handle_call({delete, Sec, Key, Persist}, From, Config) ->
+ [catch F(Sec, Key, Val, Persist) || {_Pid, F} <- Config#config.notify_funs],
+ {reply, ok, Config};
+handle_call({delete, Sec, Key, Persist}, _From, Config) ->
true = ets:delete(?MODULE, {Sec,Key}),
case {Persist, Config#config.write_filename} of
{true, undefined} ->
@@ -136,11 +133,8 @@ handle_call({delete, Sec, Key, Persist},
_ ->
ok
end,
- spawn_link(fun() ->
- [catch F(Sec, Key, deleted, Persist) || {_Pid, F} <- Config#config.notify_funs],
- gen_server:reply(From, ok)
- end),
- {noreply, Config};
+ [catch F(Sec, Key, deleted, Persist) || {_Pid, F} <- Config#config.notify_funs],
+ {reply, ok, Config};
handle_call({register, Fun, Pid}, _From, #config{notify_funs=PidFuns}=Config) ->
erlang:monitor(process, Pid),
% convert 1 and 2 arity to 3 arity
Modified: couchdb/branches/0.11.x/src/couchdb/couch_db.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_db.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_db.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_db.erl Mon Jun 14 13:35:11 2010
@@ -906,11 +906,10 @@ init({DbName, Filepath, Fd, Options}) ->
{ok, #db{fd_ref_counter=RefCntr}=Db} = gen_server:call(UpdaterPid, get_db),
couch_ref_counter:add(RefCntr),
couch_stats_collector:track_process_count({couchdb, open_databases}),
- process_flag(trap_exit, true),
{ok, Db}.
-terminate(_Reason, Db) ->
- couch_util:shutdown_sync(Db#db.update_pid),
+terminate(Reason, _Db) ->
+ couch_util:terminate_linked(Reason),
ok.
handle_call({open_ref_count, OpenerPid}, _, #db{fd_ref_counter=RefCntr}=Db) ->
@@ -938,11 +937,7 @@ handle_cast(Msg, Db) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
-
-handle_info({'EXIT', _Pid, normal}, Db) ->
- {noreply, Db};
-handle_info({'EXIT', _Pid, Reason}, Server) ->
- {stop, Reason, Server};
+
handle_info(Msg, Db) ->
?LOG_ERROR("Bad message received for db ~s: ~p", [Db#db.name, Msg]),
exit({error, Msg}).
Modified: couchdb/branches/0.11.x/src/couchdb/couch_db_updater.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_db_updater.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_db_updater.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_db_updater.erl Mon Jun 14 13:35:11 2010
@@ -20,7 +20,6 @@
init({MainPid, DbName, Filepath, Fd, Options}) ->
- process_flag(trap_exit, true),
case lists:member(create, Options) of
true ->
% create a new header and writes it to the file
@@ -38,10 +37,8 @@ init({MainPid, DbName, Filepath, Fd, Opt
{ok, Db2#db{main_pid=MainPid}}.
-terminate(_Reason, Db) ->
- couch_file:close(Db#db.fd),
- couch_util:shutdown_sync(Db#db.compactor_pid),
- couch_util:shutdown_sync(Db#db.fd_ref_counter),
+terminate(Reason, _Srv) ->
+ couch_util:terminate_linked(Reason),
ok.
handle_call(get_db, _From, Db) ->
@@ -221,11 +218,7 @@ handle_info(delayed_commit, Db) ->
Db2 ->
ok = gen_server:call(Db2#db.main_pid, {db_updated, Db2}),
{noreply, Db2}
- end;
-handle_info({'EXIT', _Pid, normal}, Db) ->
- {noreply, Db};
-handle_info({'EXIT', _Pid, Reason}, Db) ->
- {stop, Reason, Db}.
+ end.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
Modified: couchdb/branches/0.11.x/src/couchdb/couch_external_server.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_external_server.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_external_server.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_external_server.erl Mon Jun 14 13:35:11 2010
@@ -50,11 +50,9 @@ terminate(_Reason, {_Name, _Command, Pid
handle_call({execute, JsonReq}, _From, {Name, Command, Pid}) ->
{reply, couch_os_process:prompt(Pid, JsonReq), {Name, Command, Pid}}.
-handle_info({'EXIT', _Pid, normal}, State) ->
- {noreply, State};
handle_info({'EXIT', Pid, Reason}, {Name, Command, Pid}) ->
?LOG_INFO("EXTERNAL: Process for ~s exiting. (reason: ~w)", [Name, Reason]),
- {stop, Reason, {Name, Command, Pid}}.
+ {stop, normal, {Name, Command, Pid}}.
handle_cast(stop, {Name, Command, Pid}) ->
?LOG_INFO("EXTERNAL: Shutting down ~s", [Name]),
Modified: couchdb/branches/0.11.x/src/couchdb/couch_file.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_file.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_file.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_file.erl Mon Jun 14 13:35:11 2010
@@ -176,21 +176,13 @@ sync(Fd) ->
gen_server:call(Fd, sync, infinity).
%%----------------------------------------------------------------------
-%% Purpose: Close the file.
+%% Purpose: Close the file. Is performed asynchronously.
%% Returns: ok
%%----------------------------------------------------------------------
close(Fd) ->
- MRef = erlang:monitor(process, Fd),
- try
- catch unlink(Fd),
- catch exit(Fd, shutdown),
- receive
- {'DOWN', MRef, _, _, _} ->
- ok
- end
- after
- erlang:demonitor(MRef, [flush])
- end.
+ Result = gen_server:cast(Fd, close),
+ catch unlink(Fd),
+ Result.
% 09 UPGRADE CODE
old_pread(Fd, Pos, Len) ->
@@ -227,7 +219,6 @@ init_status_error(ReturnPid, Ref, Error)
% server functions
init({Filepath, Options, ReturnPid, Ref}) ->
- process_flag(trap_exit, true),
case lists:member(create, Options) of
true ->
filelib:ensure_dir(Filepath),
@@ -441,8 +432,6 @@ handle_cast(close, Fd) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
-handle_info({'EXIT', _, normal}, Fd) ->
- {noreply, Fd};
handle_info({'EXIT', _, Reason}, Fd) ->
{stop, Reason, Fd}.
Modified: couchdb/branches/0.11.x/src/couchdb/couch_native_process.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_native_process.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_native_process.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_native_process.erl Mon Jun 14 13:35:11 2010
@@ -94,10 +94,8 @@ handle_call({prompt, Data}, _From, State
{reply, Resp, NewState}
end.
-handle_cast(foo, State) -> {noreply, State}.
-handle_info({'EXIT',_,normal}, State) -> {noreply, State};
-handle_info({'EXIT',_,Reason}, State) ->
- {stop, Reason, State}.
+handle_cast(_Msg, State) -> {noreply, State}.
+handle_info(_Msg, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVersion, State, _Extra) -> {ok, State}.
Modified: couchdb/branches/0.11.x/src/couchdb/couch_os_process.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_os_process.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_os_process.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_os_process.erl Mon Jun 14 13:35:11 2010
@@ -104,7 +104,6 @@ readjson(OsProc) when is_record(OsProc,
% gen_server API
init([Command, Options, PortOptions]) ->
- process_flag(trap_exit, true),
PrivDir = couch_util:priv_dir(),
Spawnkiller = filename:join(PrivDir, "couchspawnkillable"),
BaseProc = #os_proc{
Modified: couchdb/branches/0.11.x/src/couchdb/couch_query_servers.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_query_servers.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_query_servers.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_query_servers.erl Mon Jun 14 13:35:11 2010
@@ -15,7 +15,7 @@
-export([start_link/0]).
--export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2,code_change/3]).
+-export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2,code_change/3,stop/0]).
-export([start_doc_map/2, map_docs/2, stop_doc_map/1]).
-export([reduce/3, rereduce/3,validate_doc_update/5]).
-export([filter_docs/5]).
@@ -38,6 +38,9 @@
start_link() ->
gen_server:start_link({local, couch_query_servers}, couch_query_servers, [], []).
+stop() ->
+ exit(whereis(couch_query_servers), normal).
+
start_doc_map(Lang, Functions) ->
Proc = get_os_process(Lang),
lists:foreach(fun(FunctionSource) ->
@@ -215,18 +218,17 @@ init([]) ->
ok = couch_config:register(
fun("query_servers" ++ _, _) ->
- supervisor:terminate_child(couch_secondary_services, query_servers),
- supervisor:restart_child(couch_secondary_services, query_servers)
+ ?MODULE:stop()
end),
ok = couch_config:register(
fun("native_query_servers" ++ _, _) ->
- supervisor:terminate_child(couch_secondary_services, query_servers),
- [supervisor:restart_child(couch_secondary_services, query_servers)]
+ ?MODULE:stop()
end),
Langs = ets:new(couch_query_server_langs, [set, private]),
PidProcs = ets:new(couch_query_server_pid_langs, [set, private]),
LangProcs = ets:new(couch_query_server_procs, [set, private]),
+ InUse = ets:new(couch_query_server_used, [set, private]),
% 'query_servers' specifies an OS command-line to execute.
lists:foreach(fun({Lang, Command}) ->
true = ets:insert(Langs, {?l2b(Lang),
@@ -241,71 +243,75 @@ init([]) ->
process_flag(trap_exit, true),
{ok, {Langs, % Keyed by language name, value is {Mod,Func,Arg}
PidProcs, % Keyed by PID, valus is a #proc record.
- LangProcs % Keyed by language name, value is a #proc record
+ LangProcs, % Keyed by language name, value is a #proc record
+ InUse % Keyed by PID, value is #proc record.
}}.
-terminate(_Reason, {_Langs, PidProcs, _LangProcs}) ->
- [couch_util:shutdown_sync(P) || {P,_} <- ets:tab2list(PidProcs)],
+terminate(_Reason, _Server) ->
ok.
-handle_call({get_proc, #doc{body={Props}}=DDoc, DDocKey}, _From, {Langs, PidProcs, LangProcs}=Server) ->
+handle_call({get_proc, #doc{body={Props}}=DDoc, DDocKey}, _From, {Langs, PidProcs, LangProcs, InUse}=Server) ->
% Note to future self. Add max process limit.
Lang = proplists:get_value(<<"language">>, Props, <<"javascript">>),
case ets:lookup(LangProcs, Lang) of
[{Lang, [P|Rest]}] ->
% find a proc in the set that has the DDoc
case proc_with_ddoc(DDoc, DDocKey, [P|Rest]) of
- {ok, Proc} ->
- rem_from_list(LangProcs, Lang, Proc),
- {reply, {ok, Proc, get_query_server_config()}, Server};
- Error ->
- {reply, Error, Server}
- end;
+ {ok, Proc} ->
+ % looks like the proc isn't getting dropped from the list.
+ % we need to change this to take a fun for equality checking
+ % so we can do a comparison on portnum
+ rem_from_list(LangProcs, Lang, Proc),
+ add_to_list(InUse, Lang, Proc),
+ {reply, {ok, Proc, get_query_server_config()}, Server};
+ Error ->
+ {reply, Error, Server}
+ end;
_ ->
case (catch new_process(Langs, Lang)) of
{ok, Proc} ->
add_value(PidProcs, Proc#proc.pid, Proc),
case proc_with_ddoc(DDoc, DDocKey, [Proc]) of
- {ok, Proc2} ->
- {reply, {ok, Proc2, get_query_server_config()}, Server};
- Error ->
- {reply, Error, Server}
- end;
+ {ok, Proc2} ->
+ rem_from_list(LangProcs, Lang, Proc),
+ add_to_list(InUse, Lang, Proc2),
+ {reply, {ok, Proc2, get_query_server_config()}, Server};
+ Error ->
+ {reply, Error, Server}
+ end;
Error ->
{reply, Error, Server}
end
end;
-handle_call({get_proc, Lang}, _From, {Langs, PidProcs, LangProcs}=Server) ->
+handle_call({get_proc, Lang}, _From, {Langs, PidProcs, LangProcs, InUse}=Server) ->
% Note to future self. Add max process limit.
case ets:lookup(LangProcs, Lang) of
[{Lang, [Proc|_]}] ->
+ add_value(PidProcs, Proc#proc.pid, Proc),
rem_from_list(LangProcs, Lang, Proc),
+ add_to_list(InUse, Lang, Proc),
{reply, {ok, Proc, get_query_server_config()}, Server};
_ ->
case (catch new_process(Langs, Lang)) of
{ok, Proc} ->
add_value(PidProcs, Proc#proc.pid, Proc),
+ add_to_list(InUse, Lang, Proc),
{reply, {ok, Proc, get_query_server_config()}, Server};
Error ->
{reply, Error, Server}
end
end;
-handle_call({unlink_proc, Pid}, _From, {_, PidProcs, _}=Server) ->
- rem_value(PidProcs, Pid),
- unlink(Pid),
- {reply, ok, Server};
-handle_call({ret_proc, Proc}, _From, {_, PidProcs, LangProcs}=Server) ->
+handle_call({ret_proc, Proc}, _From, {_, _, LangProcs, InUse}=Server) ->
% Along with max process limit, here we should check
% if we're over the limit and discard when we are.
- add_value(PidProcs, Proc#proc.pid, Proc),
add_to_list(LangProcs, Proc#proc.lang, Proc),
- link(Proc#proc.pid),
+ rem_from_list(InUse, Proc#proc.lang, Proc),
{reply, true, Server}.
handle_cast(_Whatever, Server) ->
{noreply, Server}.
-handle_info({'EXIT', Pid, Status}, {_, PidProcs, LangProcs}=Server) ->
+handle_info({'EXIT', Pid, Status}, {_, PidProcs, LangProcs, InUse}=Server) ->
case ets:lookup(PidProcs, Pid) of
[{Pid, Proc}] ->
case Status of
@@ -314,14 +320,11 @@ handle_info({'EXIT', Pid, Status}, {_, P
end,
rem_value(PidProcs, Pid),
catch rem_from_list(LangProcs, Proc#proc.lang, Proc),
+ catch rem_from_list(InUse, Proc#proc.lang, Proc),
{noreply, Server};
[] ->
- case Status of
- normal ->
- {noreply, Server};
- _ ->
- {stop, Status, Server}
- end
+ ?LOG_DEBUG("Unknown linked process died: ~p (reason: ~p)", [Pid, Status]),
+ {stop, Status, Server}
end.
code_change(_OldVsn, State, _Extra) ->
@@ -398,7 +401,6 @@ get_ddoc_process(#doc{} = DDoc, DDocKey)
proc_set_timeout(Proc, list_to_integer(couch_config:get(
"couchdb", "os_process_timeout", "5000"))),
link(Proc#proc.pid),
- gen_server:call(couch_query_servers, {unlink_proc, Proc#proc.pid}),
Proc;
_ ->
catch proc_stop(Proc),
@@ -416,7 +418,6 @@ get_os_process(Lang) ->
proc_set_timeout(Proc, list_to_integer(couch_config:get(
"couchdb", "os_process_timeout", "5000"))),
link(Proc#proc.pid),
- gen_server:call(couch_query_servers, {unlink_proc, Proc#proc.pid}),
Proc;
_ ->
catch proc_stop(Proc),
Modified: couchdb/branches/0.11.x/src/couchdb/couch_ref_counter.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_ref_counter.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_ref_counter.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_ref_counter.erl Mon Jun 14 13:35:11 2010
@@ -40,18 +40,17 @@ count(RefCounterPid) ->
-record(srv,
{
- referrers=dict:new(), % a dict of each ref counting proc.
- child_procs=[]
+ referrers=dict:new() % a dict of each ref counting proc.
}).
init({Pid, ChildProcs}) ->
[link(ChildProc) || ChildProc <- ChildProcs],
Referrers = dict:from_list([{Pid, {erlang:monitor(process, Pid), 1}}]),
- {ok, #srv{referrers=Referrers, child_procs=ChildProcs}}.
+ {ok, #srv{referrers=Referrers}}.
-terminate(_Reason, #srv{child_procs=ChildProcs}) ->
- [couch_util:shutdown_sync(Pid) || Pid <- ChildProcs],
+terminate(Reason, _Srv) ->
+ couch_util:terminate_linked(Reason),
ok.
Modified: couchdb/branches/0.11.x/src/couchdb/couch_server.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_server.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_server.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_server.erl Mon Jun 14 13:35:11 2010
@@ -147,9 +147,8 @@ init([]) ->
max_dbs_open=MaxDbsOpen,
start_time=httpd_util:rfc1123_date()}}.
-terminate(_Reason, _Srv) ->
- [couch_util:shutdown_sync(Pid) || {_, {Pid, _LruTime}} <-
- ets:tab2list(couch_dbs_by_name)],
+terminate(Reason, _Srv) ->
+ couch_util:terminate_linked(Reason),
ok.
all_databases() ->
@@ -190,7 +189,8 @@ try_close_lru(StartTime) ->
[{_, {MainPid, LruTime}}] = ets:lookup(couch_dbs_by_name, DbName),
case couch_db:is_idle(MainPid) of
true ->
- couch_util:shutdown_sync(MainPid),
+ exit(MainPid, kill),
+ receive {'EXIT', MainPid, _Reason} -> ok end,
true = ets:delete(couch_dbs_by_lru, LruTime),
true = ets:delete(couch_dbs_by_name, DbName),
true = ets:delete(couch_dbs_by_pid, MainPid),
@@ -286,7 +286,8 @@ handle_call({delete, DbName, _Options},
case ets:lookup(couch_dbs_by_name, DbName) of
[] -> Server;
[{_, {Pid, LruTime}}] ->
- couch_util:shutdown_sync(Pid),
+ exit(Pid, kill),
+ receive {'EXIT', Pid, _Reason} -> ok end,
true = ets:delete(couch_dbs_by_name, DbName),
true = ets:delete(couch_dbs_by_pid, Pid),
true = ets:delete(couch_dbs_by_lru, LruTime),
@@ -316,18 +317,14 @@ handle_cast(Msg, _Server) ->
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
-handle_info({'EXIT', _Pid, config_change}, Server) ->
- {stop, shutdown, Server};
-handle_info({'EXIT', Pid, Reason}, #server{dbs_open=DbsOpen}=Server) ->
- case ets:lookup(couch_dbs_by_pid, Pid) of
- [{Pid, DbName}] ->
- [{DbName, {Pid, LruTime}}] = ets:lookup(couch_dbs_by_name, DbName),
- true = ets:delete(couch_dbs_by_pid, Pid),
- true = ets:delete(couch_dbs_by_name, DbName),
- true = ets:delete(couch_dbs_by_lru, LruTime),
- {noreply, Server#server{dbs_open=DbsOpen - 1}};
- _ ->
- {stop,Reason,Server}
- end;
+handle_info({'EXIT', _Pid, config_change}, _Server) ->
+ exit(kill);
+handle_info({'EXIT', Pid, _Reason}, #server{dbs_open=DbsOpen}=Server) ->
+ [{Pid, DbName}] = ets:lookup(couch_dbs_by_pid, Pid),
+ [{DbName, {Pid, LruTime}}] = ets:lookup(couch_dbs_by_name, DbName),
+ true = ets:delete(couch_dbs_by_pid, Pid),
+ true = ets:delete(couch_dbs_by_name, DbName),
+ true = ets:delete(couch_dbs_by_lru, LruTime),
+ {noreply, Server#server{dbs_open=DbsOpen - 1}};
handle_info(Info, _Server) ->
exit({unknown_message, Info}).
Modified: couchdb/branches/0.11.x/src/couchdb/couch_server_sup.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_server_sup.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_server_sup.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_server_sup.erl Mon Jun 14 13:35:11 2010
@@ -174,7 +174,7 @@ start_secondary_services() ->
{list_to_atom(Name),
{Module, Fun, Args},
permanent,
- 1000,
+ brutal_kill,
worker,
[Module]}
end
Modified: couchdb/branches/0.11.x/src/couchdb/couch_stats_collector.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_stats_collector.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_stats_collector.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_stats_collector.erl Mon Jun 14 13:35:11 2010
@@ -60,7 +60,7 @@ increment(Key) ->
Key2 = make_key(Key),
case catch ets:update_counter(?HIT_TABLE, Key2, 1) of
{'EXIT', {badarg, _}} ->
- catch ets:insert(?HIT_TABLE, {Key2, 1}),
+ true = ets:insert(?HIT_TABLE, {Key2, 1}),
ok;
_ ->
ok
@@ -70,16 +70,16 @@ decrement(Key) ->
Key2 = make_key(Key),
case catch ets:update_counter(?HIT_TABLE, Key2, -1) of
{'EXIT', {badarg, _}} ->
- catch ets:insert(?HIT_TABLE, {Key2, -1}),
+ true = ets:insert(?HIT_TABLE, {Key2, -1}),
ok;
_ -> ok
end.
record(Key, Value) ->
- catch ets:insert(?ABS_TABLE, {make_key(Key), Value}).
+ true = ets:insert(?ABS_TABLE, {make_key(Key), Value}).
clear(Key) ->
- catch ets:delete(?ABS_TABLE, make_key(Key)).
+ true = ets:delete(?ABS_TABLE, make_key(Key)).
track_process_count(Stat) ->
track_process_count(self(), Stat).
Modified: couchdb/branches/0.11.x/src/couchdb/couch_util.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_util.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_util.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_util.erl Mon Jun 14 13:35:11 2010
@@ -12,7 +12,7 @@
-module(couch_util).
--export([priv_dir/0, start_driver/1, normpath/1]).
+-export([priv_dir/0, start_driver/1, normpath/1, terminate_linked/1]).
-export([should_flush/0, should_flush/1, to_existing_atom/1]).
-export([rand32/0, implode/2, collate/2, collate/3]).
-export([abs_pathname/1,abs_pathname/2, trim/1, ascii_lower/1]).
@@ -21,7 +21,7 @@
-export([file_read_size/1, get_nested_json_value/2, json_user_ctx/1]).
-export([to_binary/1, to_integer/1, to_list/1, url_encode/1]).
-export([json_encode/1, json_decode/1]).
--export([verify/2,simple_call/2,shutdown_sync/1]).
+-export([verify/2]).
-export([compressible_att_type/1]).
-include("couch_db.hrl").
@@ -72,35 +72,14 @@ to_existing_atom(V) when is_binary(V) ->
to_existing_atom(V) when is_atom(V) ->
V.
-shutdown_sync(Pid) when not is_pid(Pid)->
- ok;
-shutdown_sync(Pid) ->
- MRef = erlang:monitor(process, Pid),
- try
- catch unlink(Pid),
- catch exit(Pid, shutdown),
- receive
- {'DOWN', MRef, _, _, _} ->
- ok
- end
- after
- erlang:demonitor(MRef, [flush])
- end.
-
-simple_call(Pid, Message) ->
- MRef = erlang:monitor(process, Pid),
- try
- Pid ! {self(), Message},
- receive
- {Pid, Result} ->
- Result;
- {'DOWN', MRef, _, _, Reason} ->
- exit(Reason)
- end
- after
- erlang:demonitor(MRef, [flush])
- end.
+terminate_linked(normal) ->
+ terminate_linked(shutdown);
+terminate_linked(Reason) ->
+ {links, Links} = process_info(self(), links),
+ [catch exit(Pid, Reason) || Pid <- Links],
+ ok.
+
to_hex([]) ->
[];
Modified: couchdb/branches/0.11.x/src/couchdb/couch_view.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_view.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_view.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_view.erl Mon Jun 14 13:35:11 2010
@@ -269,9 +269,8 @@ init([]) ->
{ok, #server{root_dir=RootDir}}.
-terminate(_Reason, _Srv) ->
- [couch_util:shutdown_sync(Pid) || {Pid, _} <-
- ets:tab2list(couch_groups_by_updater)],
+terminate(Reason, _Srv) ->
+ couch_util:terminate_linked(Reason),
ok.
@@ -312,7 +311,10 @@ do_reset_indexes(DbName, Root) ->
fun({_DbName, Sig}) ->
?LOG_DEBUG("Killing update process for view group ~s. in database ~s.", [Sig, DbName]),
[{_, Pid}] = ets:lookup(group_servers_by_sig, {DbName, Sig}),
- couch_util:shutdown_sync(Pid)
+ exit(Pid, kill),
+ receive {'EXIT', Pid, _} ->
+ delete_from_ets(Pid, DbName, Sig)
+ end
end, Names),
delete_index_dir(Root, DbName),
file:delete(Root ++ "/." ++ ?b2l(DbName) ++ "_temp").
Modified: couchdb/branches/0.11.x/src/couchdb/couch_view_group.erl
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_view_group.erl?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_view_group.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_view_group.erl Mon Jun 14 13:35:11 2010
@@ -341,8 +341,8 @@ handle_info({'DOWN',_,_,_,_}, State) ->
terminate(Reason, #group_state{updater_pid=Update, compactor_pid=Compact}=S) ->
reply_all(S, Reason),
- couch_util:shutdown_sync(Update),
- couch_util:shutdown_sync(Compact),
+ catch exit(Update, Reason),
+ catch exit(Compact, Reason),
ok.
code_change(_OldVsn, State, _Extra) ->
Modified: couchdb/branches/0.11.x/test/etap/010-file-basics.t
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/test/etap/010-file-basics.t?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/test/etap/010-file-basics.t (original)
+++ couchdb/branches/0.11.x/test/etap/010-file-basics.t Mon Jun 14 13:35:11 2010
@@ -67,19 +67,6 @@ test() ->
{ok, BinPos} = couch_file:append_binary(Fd, <<131,100,0,3,102,111,111>>),
etap:is({ok, foo}, couch_file:pread_term(Fd, BinPos),
"Reading a term from a written binary term representation succeeds."),
-
- BigBin = list_to_binary(lists:duplicate(100000, 0)),
- {ok, BigBinPos} = couch_file:append_binary(Fd, BigBin),
- etap:is({ok, BigBin}, couch_file:pread_binary(Fd, BigBinPos),
- "Reading a large term from a written representation succeeds."),
-
- ok = couch_file:write_header(Fd, hello),
- etap:is({ok, hello}, couch_file:read_header(Fd),
- "Reading a header succeeds."),
-
- {ok, BigBinPos2} = couch_file:append_binary(Fd, BigBin),
- etap:is({ok, BigBin}, couch_file:pread_binary(Fd, BigBinPos2),
- "Reading a large term from a written representation succeeds 2."),
% append_binary == append_iolist?
% Possible bug in pread_iolist or iolist() -> append_binary
Modified: couchdb/branches/0.11.x/test/etap/040-util.t
URL: http://svn.apache.org/viewvc/couchdb/branches/0.11.x/test/etap/040-util.t?rev=954453&r1=954452&r2=954453&view=diff
==============================================================================
--- couchdb/branches/0.11.x/test/etap/040-util.t (original)
+++ couchdb/branches/0.11.x/test/etap/040-util.t Mon Jun 14 13:35:11 2010
@@ -35,6 +35,29 @@ test() ->
etap:is(foobarbaz, couch_util:to_existing_atom("foobarbaz"),
"A list of atoms is one munged atom."),
+ % terminate_linked
+ Self = self(),
+
+ spawn(fun() ->
+ SecondSelf = self(),
+ ChildPid = spawn_link(fun() ->
+ SecondSelf ! {child, started},
+ receive shutdown -> ok end
+ end),
+ PidUp = receive
+ {child, started} -> ok
+ after 1000 ->
+ {error, timeout}
+ end,
+ etap:is(ok, PidUp, "Started a linked process."),
+ couch_util:terminate_linked(normal),
+ Self ! {pid, ChildPid}
+ end),
+ receive
+ {pid, Pid} ->
+ etap:ok(not is_process_alive(Pid), "Linked process was killed.")
+ end,
+
% implode
etap:is([1, 38, 2, 38, 3], couch_util:implode([1,2,3],"&"),
"use & as separator in list."),