diff options
author | Simon MacMullen <simon@rabbitmq.com> | 2011-07-18 14:50:44 +0100 |
---|---|---|
committer | Simon MacMullen <simon@rabbitmq.com> | 2011-07-18 14:50:44 +0100 |
commit | a140aab76627a794270dbae6cca0bfe66bd1b97f (patch) | |
tree | 0f4e8738c71fd1f71a77b887e44cf8b457d9651a | |
parent | fb1f332d7135388d4abcb88adba9dac1b322e671 (diff) | |
download | rabbitmq-server-a140aab76627a794270dbae6cca0bfe66bd1b97f.tar.gz |
If start_child is called twice in a row we used to hang. Um, that's not good. Fix.
-rw-r--r-- | src/mirrored_supervisor.erl | 17 | ||||
-rw-r--r-- | src/mirrored_supervisor_tests.erl | 6 |
2 files changed, 16 insertions, 7 deletions
diff --git a/src/mirrored_supervisor.erl b/src/mirrored_supervisor.erl index 09d38630..78399b84 100644 --- a/src/mirrored_supervisor.erl +++ b/src/mirrored_supervisor.erl @@ -391,22 +391,25 @@ demonitor_all_peers(#state{peer_monitors = Peers}) -> [erlang:demonitor(Ref) || Ref <- sets:to_list(Peers)]. maybe_start(Delegate, ChildSpec) -> - case mnesia:transaction(fun() -> check_start(ChildSpec) end) of + case mnesia:transaction(fun() -> check_start(Delegate, ChildSpec) end) of {atomic, start} -> start(Delegate, ChildSpec); {atomic, Pid} -> {ok, Pid} end. -check_start(ChildSpec) -> +check_start(Delegate, ChildSpec) -> case mnesia:wread({?TABLE, id(ChildSpec)}) of [] -> write(ChildSpec), start; [S] -> #mirrored_sup_childspec{id = Id, mirroring_pid = Pid} = S, - case supervisor(Pid) of - dead -> delete(ChildSpec), - write(ChildSpec), - start; - Delegate -> child(Delegate, Id) + case self() of + Pid -> child(Delegate, Id); + _ -> case supervisor(Pid) of + dead -> delete(ChildSpec), + write(ChildSpec), + start; + Delegate0 -> child(Delegate0, Id) + end end end. diff --git a/src/mirrored_supervisor_tests.erl b/src/mirrored_supervisor_tests.erl index 51d3ea0d..b052e255 100644 --- a/src/mirrored_supervisor_tests.erl +++ b/src/mirrored_supervisor_tests.erl @@ -37,6 +37,7 @@ all_tests() -> passed = test_childspecs_at_init(), passed = test_anonymous_supervisors(), passed = test_no_migration_on_shutdown(), + passed = test_start_idempotence(), passed. %% Simplest test @@ -131,6 +132,11 @@ test_no_migration_on_shutdown() -> timer:sleep(1000) end, [evil, good]). +test_start_idempotence() -> + with_sups(fun([A]) -> + mirrored_supervisor:start_child(a, childspec(worker)), + mirrored_supervisor:start_child(a, childspec(worker)) + end, [a]). %% --------------------------------------------------------------------------- |