summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Kocoloski <adam@cloudant.com>2011-10-13 11:10:24 -0700
committerAdam Kocoloski <adam@cloudant.com>2011-10-13 14:14:17 -0400
commit41e7cb7666a8645b9eb5898ac4027ca6df0d1107 (patch)
tree8fe9d70b60b45afadf3f8c9690fc5dd5ce769b41
parent82de8a49bf39386979d86007c470b82974e8d3f0 (diff)
parent7c04f93ef1337405ac4440e254f3dae5d6e1189b (diff)
Merge pull request #74 from cloudant/7c04f93
Fix badarg error in couch_server:try_close_lru/1 BugzID: 12363
-rw-r--r--apps/couch/src/couch_server.erl30
1 files changed, 21 insertions, 9 deletions
diff --git a/apps/couch/src/couch_server.erl b/apps/couch/src/couch_server.erl
index f9c960c5..c7850990 100644
--- a/apps/couch/src/couch_server.erl
+++ b/apps/couch/src/couch_server.erl
@@ -199,16 +199,28 @@ try_close_lru(StartTime) ->
% There may exist an extremely small possibility of a race
% condition here, if a process could lookup the DB before the lock,
% but fail to monitor the fd before the is_idle check.
- true = ets:update_element(couch_dbs, DbName, {#db.fd_monitor, locked}),
- [#db{main_pid = Pid} = Db] = ets:lookup(couch_dbs, DbName),
- case couch_db:is_idle(Db) of true ->
- true = ets:delete(couch_dbs, DbName),
- true = ets:delete(couch_lru, DbName),
- exit(Pid, kill),
- ok;
+ %
+ % If we do hit this race condition the behavior is that the process
+ % grabbing the database will end up inserting a value into the
+ % couch_lru table. Its possible that we end up picking that up
+ % as the DbName above to close. So we here we'll just remove the
+ % couch_lru entry and ignore it.
+ case ets:update_element(couch_dbs, DbName, {#db.fd_monitor, locked}) of
+ true ->
+ [#db{main_pid = Pid} = Db] = ets:lookup(couch_dbs, DbName),
+ case couch_db:is_idle(Db) of true ->
+ true = ets:delete(couch_dbs, DbName),
+ true = ets:delete(couch_lru, DbName),
+ exit(Pid, kill),
+ ok;
+ false ->
+ Update = {#db.fd_monitor, nil},
+ true = ets:update_element(couch_dbs, DbName, Update),
+ true = ets:insert(couch_lru, {DbName, now()}),
+ try_close_lru(StartTime)
+ end;
false ->
- true = ets:update_element(couch_dbs, DbName, {#db.fd_monitor, nil}),
- true = ets:insert(couch_lru, {DbName, now()}),
+ true = ets:delete(couch_lru, DbName),
try_close_lru(StartTime)
end
end.