aboutsummaryrefslogtreecommitdiffstats
path: root/lib/mnesia/src
diff options
context:
space:
mode:
authorDan Gudmundsson <[email protected]>2016-10-11 15:19:10 +0200
committerDan Gudmundsson <[email protected]>2016-10-11 15:19:10 +0200
commit82d1b7b4c79cef54f04e062f04b696544609a25b (patch)
tree85ceb23d7df2e82e40cd69d04be6314dea14b0b4 /lib/mnesia/src
parenta59807ef9a6a8af6eb6f13976eb405ddb9baad6c (diff)
downloadotp-82d1b7b4c79cef54f04e062f04b696544609a25b.tar.gz
otp-82d1b7b4c79cef54f04e062f04b696544609a25b.tar.bz2
otp-82d1b7b4c79cef54f04e062f04b696544609a25b.zip
mnesia: Fix double blocked tables which could cause a crash
Fast restarts could cause table to be blocked twice.
Diffstat (limited to 'lib/mnesia/src')
-rw-r--r--lib/mnesia/src/mnesia_controller.erl7
-rw-r--r--lib/mnesia/src/mnesia_loader.erl8
2 files changed, 11 insertions, 4 deletions
diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index 4791e2e290..17b47c059e 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.erl
@@ -1703,9 +1703,10 @@ add_active_replica(Tab, Node, Cs = #cstruct{}) ->
block_table(Tab) ->
Var = {Tab, where_to_commit},
- Old = val(Var),
- New = {blocked, Old},
- set(Var, New). % where_to_commit
+ case is_tab_blocked(val(Var)) of
+ {true, _} -> ok;
+ {false, W2C} -> set(Var, mark_blocked_tab(true, W2C))
+ end.
unblock_table(Tab) ->
call({unblock_table, Tab}).
diff --git a/lib/mnesia/src/mnesia_loader.erl b/lib/mnesia/src/mnesia_loader.erl
index 71e5829c87..d2e42ef0d1 100644
--- a/lib/mnesia/src/mnesia_loader.erl
+++ b/lib/mnesia/src/mnesia_loader.erl
@@ -916,9 +916,15 @@ send_packet(_N, _Pid, _Chunk, DataState) ->
finish_copy(Pid, Tab, Storage, RemoteS, NeedLock) ->
RecNode = node(Pid),
DatBin = dat2bin(Tab, Storage, RemoteS),
+ Node = node(Pid),
Trans =
fun() ->
NeedLock andalso mnesia:read_lock_table(Tab),
+ %% Check that receiver is still alive
+ receive {copier_done, Node} ->
+ throw(receiver_died)
+ after 0 -> ok
+ end,
A = val({Tab, access_mode}),
mnesia_controller:sync_and_block_table_whereabouts(Tab, RecNode, RemoteS, A),
cleanup_tab_copier(Pid, Storage, Tab),
@@ -927,7 +933,7 @@ finish_copy(Pid, Tab, Storage, RemoteS, NeedLock) ->
receive
{Pid, no_more} -> % Dont bother about the spurious 'more' message
no_more;
- {copier_done, Node} when Node == node(Pid)->
+ {copier_done, Node} ->
verbose("Tab receiver ~p crashed (more): ~p~n", [Tab, Node]),
receiver_died
end