summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul J. Davis <paul.joseph.davis@gmail.com>2017-07-12 16:00:33 -0500
committerPaul J. Davis <paul.joseph.davis@gmail.com>2017-07-13 10:45:58 -0500
commit6586102ba496e76f27b34794ca11be2712cfa28b (patch)
tree0079a7d918c0c8d152b5ad2d62bded52add67120
parent764168c5b03f17b7adfa5db9a3b7341b01281f44 (diff)
downloadcouchdb-6586102ba496e76f27b34794ca11be2712cfa28b.tar.gz
Avoid a race when restarting an index updater
This was encountered during the test suite runs on Travis. It turns out that when we restart the indexer its possible to already have the 'EXIT' message in our mailbox. When we do we'll then crash with an unknown_info error since our updater pid was changed during the restart. This change simple filters any 'EXIT' message from the old updater from the mailbox before restarting thew new index updater. Fixes #649
-rw-r--r--src/couch_index/src/couch_index_updater.erl14
1 files changed, 11 insertions, 3 deletions
diff --git a/src/couch_index/src/couch_index_updater.erl b/src/couch_index/src/couch_index_updater.erl
index ad48f4065..4f63e9f10 100644
--- a/src/couch_index/src/couch_index_updater.erl
+++ b/src/couch_index/src/couch_index_updater.erl
@@ -73,12 +73,20 @@ handle_call({update, IdxState}, _From, #st{idx=Idx, mod=Mod}=State) ->
handle_call({restart, IdxState}, _From, #st{idx=Idx, mod=Mod}=State) ->
Args = [Mod:get(db_name, IdxState), Mod:get(idx_name, IdxState)],
couch_log:info("Restarting index update for db: ~s idx: ~s", Args),
- case is_pid(State#st.pid) of
+ Pid = State#st.pid,
+ case is_pid(Pid) of
true -> couch_util:shutdown_sync(State#st.pid);
_ -> ok
end,
- Pid = spawn_link(?MODULE, update, [Idx, State#st.mod, IdxState]),
- {reply, ok, State#st{pid=Pid}};
+ % Make sure and flush a possible 'EXIT' message
+ % that's already in our mailbox
+ receive
+ {'EXIT', Pid, _} -> ok
+ after 0 ->
+ ok
+ end,
+ NewPid = spawn_link(?MODULE, update, [Idx, State#st.mod, IdxState]),
+ {reply, ok, State#st{pid=NewPid}};
handle_call(is_running, _From, #st{pid=Pid}=State) when is_pid(Pid) ->
{reply, true, State};
handle_call(is_running, _From, State) ->