|
142 | 142 | [ChildSpec :: child_spec()]}}
|
143 | 143 | | ignore.
|
144 | 144 |
|
| 145 | +-callback prep_stop() -> ok. |
| 146 | + |
145 | 147 | -define(restarting(_Pid_), {restarting,_Pid_}).
|
146 | 148 |
|
147 | 149 | %%% ---------------------------------------------------
|
@@ -629,6 +631,7 @@ handle_info({'EXIT', Pid, Reason}, State) ->
|
629 | 631 | {ok, State1} ->
|
630 | 632 | {noreply, State1};
|
631 | 633 | {shutdown, State1} ->
|
| 634 | + prep_stop(State1), |
632 | 635 | {stop, shutdown, State1}
|
633 | 636 | end;
|
634 | 637 |
|
@@ -801,7 +804,8 @@ restart_child(Pid, Reason, State) ->
|
801 | 804 | try_restart(RestartType, Reason, Child, State) ->
|
802 | 805 | case handle_restart(RestartType, Reason, Child, State) of
|
803 | 806 | {ok, NState} -> {noreply, NState};
|
804 |
| - {shutdown, State2} -> {stop, shutdown, State2} |
| 807 | + {shutdown, State2} -> prep_stop(State2), |
| 808 | + {stop, shutdown, State2} |
805 | 809 | end.
|
806 | 810 |
|
807 | 811 | do_restart(RestartType, Reason, Child, State) ->
|
@@ -1504,3 +1508,16 @@ report_progress(Child, SupName) ->
|
1504 | 1508 | Progress = [{supervisor, SupName},
|
1505 | 1509 | {started, extract_child(Child)}],
|
1506 | 1510 | error_logger:info_report(progress, Progress).
|
| 1511 | + |
| 1512 | +prep_stop(#state{module = Mod}) -> |
| 1513 | + %% Catch any exception - including non-existing prep_stop - |
| 1514 | + %% and continue stopping the supervision tree. |
| 1515 | + %% This is only executed when children are terminating, |
| 1516 | + %% because any other call from a top supervisor or application |
| 1517 | + %% will cause a deadlock stopping applications within prep_stop. |
| 1518 | + try |
| 1519 | + Mod:prep_stop() |
| 1520 | + catch |
| 1521 | + _:_ -> |
| 1522 | + ok |
| 1523 | + end. |
0 commit comments