summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFred Hebert <mononcqc@ferd.ca>2016-03-19 12:41:40 -0400
committerFred Hebert <mononcqc@ferd.ca>2016-03-19 12:41:40 -0400
commit8e6a1ad62e3db7be3b1fa75c8268997aa6bf0992 (patch)
treea661085f3126618792738a6ad63bdb0fbe31a7c8
parent7d29b74a221ef082e4bbee496019c8f1612e8f0b (diff)
Fix bugs/race conditions
Following suggestions from @psyeugenic, this code terminates and waits for the termination of the port handling IO before booting our own, which should get rid of annoying warnings. We also allow for the failure to shutdown the user worker under kernel_sup, since it is likely not there anymore in many scenarios, preventing crashes.
-rw-r--r--src/rebar_prv_shell.erl18
1 files changed, 16 insertions, 2 deletions
diff --git a/src/rebar_prv_shell.erl b/src/rebar_prv_shell.erl
index 430d1e8..d67f940 100644
--- a/src/rebar_prv_shell.erl
+++ b/src/rebar_prv_shell.erl
@@ -133,11 +133,25 @@ kill_old_user() ->
%% fully die
[P] = [P || P <- element(2,process_info(whereis(user), links)), is_port(P)],
user ! {'EXIT', P, normal}, % pretend the port died, then the port can die!
+ exit(P, kill),
+ wait_for_port_death(1000, P),
OldUser.
+wait_for_port_death(N, _) when N < 0 ->
+ %% This risks displaying a warning!
+ whatever;
+wait_for_port_death(N, P) ->
+ case erlang:port_info(P) of
+ undefined ->
+ ok;
+ _ ->
+ timer:sleep(10),
+ wait_for_port_death(N-10, P)
+ end.
+
setup_new_shell() ->
- %% terminate the current user supervision structure
- ok = supervisor:terminate_child(kernel_sup, user),
+ %% terminate the current user supervision structure, if any
+ _ = supervisor:terminate_child(kernel_sup, user),
%% start a new shell (this also starts a new user under the correct group)
_ = user_drv:start(),
%% wait until user_drv and user have been registered (max 3 seconds)