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."),