From c823bd2e8b3990b5c55dde54705d6866ad1eda4f Mon Sep 17 00:00:00 2001 From: "Damien F. Katz" Date: Mon, 22 Dec 2008 20:35:50 +0000 Subject: Fix for leaked file handles when not explicitly closed, added file stats code for checking for leaked file handles, and some refactoring of the view api. git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@728764 13f79535-47bb-0310-9956-ffa450edef68 --- src/couchdb/couch_file.erl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src/couchdb/couch_file.erl') diff --git a/src/couchdb/couch_file.erl b/src/couchdb/couch_file.erl index 06156324..9e60eb09 100644 --- a/src/couchdb/couch_file.erl +++ b/src/couchdb/couch_file.erl @@ -36,6 +36,7 @@ open(Filepath, Options) -> case gen_server:start_link(couch_file, {Filepath, Options, self(), Ref = make_ref()}, []) of {ok, Fd} -> + couch_file_stats:track_file(Fd), {ok, Fd}; ignore -> % get the error @@ -164,7 +165,9 @@ sync(Fd) -> %% Returns: ok %%---------------------------------------------------------------------- close(Fd) -> - gen_server:cast(Fd, close). + Result = gen_server:cast(Fd, close), + catch unlink(Fd), + Result. close_maybe(Fd) -> gen_server:cast(Fd, {close_maybe, self()}). @@ -185,6 +188,7 @@ add_ref(Fd, Pid) -> num_refs(Fd) -> gen_server:call(Fd, num_refs). + write_header(Fd, Prefix, Data) -> TermBin = term_to_binary(Data), % the size of all the bytes written to the header, including the md5 signature (16 bytes) @@ -286,6 +290,7 @@ 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), @@ -325,8 +330,7 @@ init({Filepath, Options, ReturnPid, Ref}) -> end. -terminate(_Reason, Fd) -> - file:close(Fd), +terminate(_Reason, _Fd) -> ok. @@ -366,7 +370,6 @@ handle_call(num_refs, _From, Fd) -> {reply, length(Monitors), Fd}. - handle_cast(close, Fd) -> {stop,normal,Fd}; handle_cast({close_maybe, Pid}, Fd) -> @@ -388,6 +391,8 @@ handle_cast({drop_ref, Pid}, Fd) -> code_change(_OldVsn, State, _Extra) -> {ok, State}. +handle_info({'EXIT', _Pid, Reason}, Fd) -> + {stop, Reason, Fd}; handle_info({'DOWN', MonitorRef, _Type, Pid, _Info}, Fd) -> {MonitorRef, _RefCount} = erase(Pid), maybe_close_async(Fd). -- cgit v1.2.3