summaryrefslogtreecommitdiff
path: root/src/couch_index
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 /src/couch_index
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
Diffstat (limited to 'src/couch_index')
-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) ->