You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2008/08/24 19:52:56 UTC

svn commit: r688540 - /incubator/couchdb/trunk/src/couchdb/couch_file.erl

Author: damien
Date: Sun Aug 24 10:52:56 2008
New Revision: 688540

URL: http://svn.apache.org/viewvc?rev=688540&view=rev
Log:
fix for occasional crash when attempting to open a database on a heavily loaded server

Modified:
    incubator/couchdb/trunk/src/couchdb/couch_file.erl

Modified: incubator/couchdb/trunk/src/couchdb/couch_file.erl
URL: http://svn.apache.org/viewvc/incubator/couchdb/trunk/src/couchdb/couch_file.erl?rev=688540&r1=688539&r2=688540&view=diff
==============================================================================
--- incubator/couchdb/trunk/src/couchdb/couch_file.erl (original)
+++ incubator/couchdb/trunk/src/couchdb/couch_file.erl Sun Aug 24 10:52:56 2008
@@ -363,12 +363,16 @@
     {ok, Pos} = file:position(Fd, eof),
     {reply, {file:pwrite(Fd, Pos, Bin2), Pos}, Fd};
 handle_call({pread_bin, Pos}, _From, Fd) ->
-    {ok, <<TermLen:32>>}
-        = file:pread(Fd, Pos, 4),
+    {ok, <<TermLen:32>>} = file:pread(Fd, Pos, 4),
     {ok, Bin} = file:pread(Fd, Pos + 4, TermLen),
     {reply, {ok, Bin}, Fd};
 handle_call({add_ref, Pid},_From, Fd) ->
-    undefined = put(Pid, erlang:monitor(process, Pid)),
+    case get(Pid) of
+    undefined ->
+        put(Pid, {erlang:monitor(process, Pid), 1});
+    {MonRef, RefCnt} ->
+        put(Pid, {MonRef, RefCnt + 1})
+    end,
     {reply, ok, Fd};
 handle_call(num_refs, _From, Fd) ->
     {monitors, Monitors} =  process_info(self(), monitors),
@@ -382,9 +386,15 @@
     catch unlink(Pid),
     maybe_close_async(Fd);
 handle_cast({drop_ref, Pid}, Fd) ->
-    % don't check return of demonitor. The process could haved crashed causing
-    % the {'DOWN', ...} message to be sent and the process unmonitored.
-    erlang:demonitor(erase(Pid), [flush]),
+    case get(Pid) of
+    {MonRef, 1} ->
+        erase(Pid),
+        % don't check return of demonitor. The process could haved crashed causing
+        % the {'DOWN', ...} message to be sent and the process unmonitored.
+        erlang:demonitor(MonRef, [flush]);
+    {MonRef, Num} ->
+        put(Pid, {MonRef, Num-1})
+    end,
     maybe_close_async(Fd).
 
 
@@ -392,7 +402,7 @@
     {ok, State}.
 
 handle_info({'DOWN', MonitorRef, _Type, Pid, _Info}, Fd) ->
-    MonitorRef = erase(Pid),
+    {MonitorRef, _RefCount} = erase(Pid),
     maybe_close_async(Fd);
 handle_info(Info, Fd) ->
     exit({error, {Info, Fd}}).