Don't trap exits in couch_file
It turns out to be impossible to trap the exit message from the parent
process in a gen_server, which is the only reason couch_file traps
exits in the first place (i.e, this has never worked).
This commit also changes the hot upgrade code to handle this
transition (but not the previous one).
COUCHDB-3259
diff --git a/src/couch_file.erl b/src/couch_file.erl
index 19e5998..7cf8b02 100644
--- a/src/couch_file.erl
+++ b/src/couch_file.erl
@@ -21,7 +21,7 @@
-define(MONITOR_CHECK, 10000).
-define(SIZE_BLOCK, 16#1000). % 4 KiB
-define(READ_AHEAD, 2 * ?SIZE_BLOCK).
--define(IS_OLD_STATE(S), tuple_size(S) /= tuple_size(#file{})).
+-define(IS_OLD_STATE(S), is_pid(S#file.db_monitor)).
-define(PREFIX_SIZE, 5).
-define(DEFAULT_READ_COUNT, 1024).
@@ -33,7 +33,7 @@
fd,
is_sys,
eof = 0,
- db_pid,
+ db_monitor,
pread_limit = 0
}).
@@ -342,7 +342,6 @@
% server functions
init({Filepath, Options, ReturnPid, Ref}) ->
- process_flag(trap_exit, true),
OpenOptions = file_open_options(Options),
Limit = get_pread_limit(),
IsSys = lists:member(sys_db, Options),
@@ -450,13 +449,13 @@
handle_call(bytes, _From, #file{fd = Fd} = File) ->
{reply, file:position(Fd, eof), File};
-handle_call({set_db_pid, Pid}, _From, #file{db_pid=OldPid}=File) ->
- case is_pid(OldPid) of
- true -> unlink(OldPid);
+handle_call({set_db_pid, Pid}, _From, #file{db_monitor=OldRef}=File) ->
+ case is_reference(OldRef) of
+ true -> demonitor(OldRef, [flush]);
false -> ok
end,
- link(Pid),
- {reply, ok, File#file{db_pid=Pid}};
+ Ref = monitor(process, Pid),
+ {reply, ok, File#file{db_monitor=Ref}};
handle_call(sync, _From, #file{fd=Fd}=File) ->
{reply, file:sync(Fd), File};
@@ -517,16 +516,11 @@
{noreply, File}
end;
-handle_info({'EXIT', Pid, _}, #file{db_pid=Pid}=File) ->
+handle_info({'DOWN', Ref, process, _Pid, _Info}, #file{db_monitor=Ref}=File) ->
case is_idle(File) of
true -> {stop, normal, File};
false -> {noreply, File}
- end;
-
-handle_info({'EXIT', _, normal}, Fd) ->
- {noreply, Fd};
-handle_info({'EXIT', _, Reason}, Fd) ->
- {stop, Reason, Fd}.
+ end.
find_header(Fd, Block) ->
@@ -731,9 +725,10 @@
{Fd, InitialName}
end.
-upgrade_state({file, Fd, IsSys, Eof, DbPid}) ->
- Limit = get_pread_limit(),
- #file{fd=Fd, is_sys=IsSys, eof=Eof, db_pid=DbPid, pread_limit=Limit};
+upgrade_state(#file{db_monitor=DbPid}=File) when is_pid(DbPid) ->
+ unlink(DbPid),
+ Ref = monitor(process, DbPid),
+ File#file{db_monitor=Ref};
upgrade_state(State) ->
State.