summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFilipe David Borba Manana <fdmanana@apache.org>2011-08-18 05:50:42 +0000
committerFilipe David Borba Manana <fdmanana@apache.org>2011-08-18 05:50:42 +0000
commit82a10d77d0c206c89e640ca7097d8e12e95eb8be (patch)
tree834674bf643f2088c92331b44494f6721b3bc148 /src
parent0dc0f8b41f627876f65183ea1d99c68b16abeae0 (diff)
Merge revision 1159045 from trunk
Fix dead lock case in the os process pool Part of this patch was done by Paul Davis. The patch also introduces a test case to validate that the os process pool (couch_query_servers) operates as it should. Closes COUCHDB-1246. git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1159049 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/couchdb/couch_os_process.erl6
-rw-r--r--src/couchdb/couch_query_servers.erl22
2 files changed, 16 insertions, 12 deletions
diff --git a/src/couchdb/couch_os_process.erl b/src/couchdb/couch_os_process.erl
index 5776776b..3ee52865 100644
--- a/src/couchdb/couch_os_process.erl
+++ b/src/couchdb/couch_os_process.erl
@@ -104,7 +104,6 @@ readjson(OsProc) when is_record(OsProc, os_proc) ->
% 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{
@@ -175,10 +174,7 @@ handle_info({Port, {exit_status, 0}}, #os_proc{port=Port}=OsProc) ->
{stop, normal, OsProc};
handle_info({Port, {exit_status, Status}}, #os_proc{port=Port}=OsProc) ->
?LOG_ERROR("OS Process died with status: ~p", [Status]),
- {stop, {exit_status, Status}, OsProc};
-handle_info(Msg, OsProc) ->
- ?LOG_DEBUG("OS Proc: Unknown info: ~p", [Msg]),
- {noreply, OsProc}.
+ {stop, {exit_status, Status}, OsProc}.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
diff --git a/src/couchdb/couch_query_servers.erl b/src/couchdb/couch_query_servers.erl
index b0e46937..f8bbcaed 100644
--- a/src/couchdb/couch_query_servers.erl
+++ b/src/couchdb/couch_query_servers.erl
@@ -22,7 +22,8 @@
-export([with_ddoc_proc/2, proc_prompt/2, ddoc_prompt/3, ddoc_proc_prompt/3, json_doc/1]).
-% -export([test/0]).
+% For 210-os-proc-pool.t
+-export([get_os_process/1, ret_os_process/1]).
-include("couch_db.hrl").
@@ -343,8 +344,7 @@ handle_call({get_proc, Lang}, From, Server) ->
Error ->
{reply, Error, Server}
end;
-handle_call({unlink_proc, Pid}, _From, #qserver{pid_procs=PidProcs}=Server) ->
- rem_value(PidProcs, Pid),
+handle_call({unlink_proc, Pid}, _From, Server) ->
unlink(Pid),
{reply, ok, Server};
handle_call({ret_proc, Proc}, _From, #qserver{
@@ -352,15 +352,22 @@ handle_call({ret_proc, Proc}, _From, #qserver{
lang_procs=LangProcs}=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),
+ case is_process_alive(Proc#proc.pid) of
+ true ->
+ add_value(PidProcs, Proc#proc.pid, Proc),
+ add_to_list(LangProcs, Proc#proc.lang, Proc),
+ link(Proc#proc.pid);
+ false ->
+ ok
+ end,
{reply, true, service_waitlist(Server)}.
handle_cast(_Whatever, Server) ->
{noreply, Server}.
-handle_info({'EXIT', Pid, Status}, #qserver{
+handle_info({'EXIT', _, _}, Server) ->
+ {noreply, Server};
+handle_info({'DOWN', _, process, Pid, Status}, #qserver{
pid_procs=PidProcs,
lang_procs=LangProcs,
lang_limits=LangLimits}=Server) ->
@@ -461,6 +468,7 @@ new_process(Langs, LangLimits, Lang) ->
case ets:lookup(Langs, Lang) of
[{Lang, Mod, Func, Arg}] ->
{ok, Pid} = apply(Mod, Func, Arg),
+ erlang:monitor(process, Pid),
true = ets:insert(LangLimits, {Lang, Lim, Current+1}),
{ok, #proc{lang=Lang,
pid=Pid,