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}}).