summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiri Hansen <siri@erlang.org>2018-09-14 14:12:13 +0200
committerSiri Hansen <siri@erlang.org>2018-09-14 14:12:13 +0200
commit6073d37a5a0691704d0fa1a5ff9289ba9e35c8ed (patch)
tree4c6b91691981f5713904638974635dfe181eb7a1
parent48a1c458a46dcd1f031fd3b9689af80b32b4a6a2 (diff)
downloaderlang-6073d37a5a0691704d0fa1a5ff9289ba9e35c8ed.tar.gz
[logger] Read config before terminating handler process
When a handler process is terminated due to overload, it reads its configuration from the configuration database, so it can be restarted with the same configuration after a small delay. This was earlier done in a different process, which was spawned off from the terminate function. This caused a race condition, where in some cases, the configuration was already removed before it could be read. The reason for spawning off a process, is to avoid a deadlock due to the call to logger:remove_handler/1. This commit moves the call to logger:get_handler_config/1 back to the handler process - to ensure that the data is still there, but keeps the call to logger:remove_handler/1 in the spawned off process - to avoid deadlock.
-rw-r--r--lib/kernel/src/logger_disk_log_h.erl3
-rw-r--r--lib/kernel/src/logger_h_common.erl3
-rw-r--r--lib/kernel/src/logger_std_h.erl3
3 files changed, 6 insertions, 3 deletions
diff --git a/lib/kernel/src/logger_disk_log_h.erl b/lib/kernel/src/logger_disk_log_h.erl
index 26375373aa..a8f141f135 100644
--- a/lib/kernel/src/logger_disk_log_h.erl
+++ b/lib/kernel/src/logger_disk_log_h.erl
@@ -426,8 +426,9 @@ terminate(Reason, State = #{id := Name}) ->
_ = logger_h_common:cancel_timer(maps:get(rep_sync_tref, State,
undefined)),
_ = close_disk_log(Name, normal),
+ ok = logger_h_common:stop_or_restart(Name, Reason, State),
unregister(?name_to_reg_name(?MODULE, Name)),
- logger_h_common:stop_or_restart(Name, Reason, State).
+ ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
diff --git a/lib/kernel/src/logger_h_common.erl b/lib/kernel/src/logger_h_common.erl
index 2818a460f1..38ac7d8ffc 100644
--- a/lib/kernel/src/logger_h_common.erl
+++ b/lib/kernel/src/logger_h_common.erl
@@ -294,6 +294,7 @@ stop_or_restart(Name, {shutdown,Reason={overloaded,_Name,_QLen,_Mem}},
%% and set a restart timer. A separate process must perform this
%% in order to avoid deadlock.
HandlerPid = self(),
+ ConfigResult = logger:get_handler_config(Name),
RemoveAndRestart =
fun() ->
MRef = erlang:monitor(process, HandlerPid),
@@ -304,7 +305,7 @@ stop_or_restart(Name, {shutdown,Reason={overloaded,_Name,_QLen,_Mem}},
error_notify(Reason),
exit(HandlerPid, kill)
end,
- case logger:get_handler_config(Name) of
+ case ConfigResult of
{ok,#{module:=HMod}=HConfig} when is_integer(RestartAfter) ->
_ = logger:remove_handler(Name),
_ = timer:apply_after(RestartAfter, logger, add_handler,
diff --git a/lib/kernel/src/logger_std_h.erl b/lib/kernel/src/logger_std_h.erl
index 5dc4bc91ad..66fa6b6ab6 100644
--- a/lib/kernel/src/logger_std_h.erl
+++ b/lib/kernel/src/logger_std_h.erl
@@ -415,8 +415,9 @@ terminate(Reason, State = #{id:=Name, file_ctrl_pid:=FWPid,
false ->
ok
end,
+ ok = logger_h_common:stop_or_restart(Name, Reason, State),
unregister(?name_to_reg_name(?MODULE, Name)),
- logger_h_common:stop_or_restart(Name, Reason, State).
+ ok.
code_change(_OldVsn, State, _Extra) ->
{ok, State}.