diff options
author | Paul J. Davis <paul.joseph.davis@gmail.com> | 2017-07-12 16:00:33 -0500 |
---|---|---|
committer | Paul J. Davis <paul.joseph.davis@gmail.com> | 2017-07-13 10:45:58 -0500 |
commit | 6586102ba496e76f27b34794ca11be2712cfa28b (patch) | |
tree | 0079a7d918c0c8d152b5ad2d62bded52add67120 | |
parent | 764168c5b03f17b7adfa5db9a3b7341b01281f44 (diff) | |
download | couchdb-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.erl | 14 |
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) -> |