obi458 commented on issue #1182: fixed race is_idle URL: https://github.com/apache/couchdb/pull/1182#issuecomment-369345885 I don't give up :-) ``` incref(#db{fd = Fd} = Db) -> incref(Db,couch_file:lock(Fd)). incref(#db{fd = Fd} = Db, true = _Locked) -> % first monitor Ref = erlang:monitor(process, Fd), % than release the lock couch_file:unlock(Fd), {ok, Db#db{fd_monitor = Ref}}; % we are not able to write the lock, % either the file will be closed or another process want to monitor % we will try it again incref(#db{fd = _Fd} = _Db, false = _Locked) -> retry. ``` couch_file: ``` % System dbs aren't monitored by couch_stats_process_tracker is_idle(#file{is_sys=true}) -> case process_info(self(), monitored_by) of {monitored_by, []} -> lock(self()); _ -> false end; is_idle(#file{is_sys=false}) -> Tracker = whereis(couch_stats_process_tracker), case process_info(self(), monitored_by) of {monitored_by, []} -> lock(self()); {monitored_by, [Tracker]} -> lock(self()); {monitored_by, [_]} -> exit(tracker_monitoring_failed); _ -> false end. lock(Fd) -> try ets:new(list_to_atom(pid_to_list(Fd)), [named_table]), true catch _:_ -> false end. unlock(Fd) -> ets:delete(list_to_atom(pid_to_list(Fd))). ``` couchd_db_updater: ``` handle_info(timeout, #db{fd=Fd, name=DbName} = Db) -> IdleLimitMSec = update_idle_limit_from_config(), case couch_db:is_idle(Db) of true -> % we have to unlock Fd, cause close_db_if_idle will check is_idle again couch_file:unlock(Fd), MSecSinceLastRead = couch_file:msec_since_last_read(Fd), case MSecSinceLastRead > IdleLimitMSec of true -> ok = couch_server:close_db_if_idle(DbName); false -> ok end; false -> ok end, % Send a message to wake up and then hibernate. Hibernation here is done to % force a thorough garbage collection. gen_server:cast(self(), wakeup), {noreply, Db, hibernate}. ``` couchd_db: ``` is_idle(#db{compactor_pid=nil, waiting_delayed_commit=nil} = Db) -> monitored_by(Db) == [] andalso couch_file:lock(Db#db.fd); is_idle(_Db) -> false. ``` Process died -> ets died and lock will released! `timer:tc(fun() -> [begin couch_file:lock(self()), couch_file:unlock() end || _ <- lists:seq(1,1000000)] end).` {2191728,ok} on iMac Pro
---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services
