From 8e6a1ad62e3db7be3b1fa75c8268997aa6bf0992 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sat, 19 Mar 2016 12:41:40 -0400 Subject: 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. --- src/rebar_prv_shell.erl | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src') 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) -- cgit v1.1