aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2017-02-22 15:41:26 +0100
committerRaimo Niskanen <[email protected]>2017-02-23 08:39:01 +0100
commit913d0b52df1e029fb1728b44ba7da318f3dc49dd (patch)
tree35037c24dcf6c412d9c3c602dfe3e7057534de3e /lib
parentf1365135f1dd0b57849317b77e8bc9a1e0fd6307 (diff)
downloadotp-913d0b52df1e029fb1728b44ba7da318f3dc49dd.tar.gz
otp-913d0b52df1e029fb1728b44ba7da318f3dc49dd.tar.bz2
otp-913d0b52df1e029fb1728b44ba7da318f3dc49dd.zip
Implement fallback for terminate/3
Diffstat (limited to 'lib')
-rw-r--r--lib/stdlib/doc/src/gen_statem.xml5
-rw-r--r--lib/stdlib/src/gen_statem.erl28
2 files changed, 22 insertions, 11 deletions
diff --git a/lib/stdlib/doc/src/gen_statem.xml b/lib/stdlib/doc/src/gen_statem.xml
index d19602b67c..5eb13db1aa 100644
--- a/lib/stdlib/doc/src/gen_statem.xml
+++ b/lib/stdlib/doc/src/gen_statem.xml
@@ -1973,6 +1973,11 @@ handle_event(_, _, State, Data) ->
<v>Ignored = term()</v>
</type>
<desc>
+ <note>
+ <p>This callback is optional, so callback modules need not
+ export it. The <c>gen_statem</c> module provides a default
+ implementation without cleanup.</p>
+ </note>
<p>
This function is called by a <c>gen_statem</c>
when it is about to terminate. It is to be the opposite of
diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl
index d7e8504564..ae50651c06 100644
--- a/lib/stdlib/src/gen_statem.erl
+++ b/lib/stdlib/src/gen_statem.erl
@@ -289,6 +289,7 @@
-optional_callbacks(
[init/1, % One may use enter_loop/5,6,7 instead
format_status/2, % Has got a default implementation
+ terminate/3, % Has got a default implementation
%%
state_name/3, % Example for callback_mode() =:= state_functions:
%% there has to be a StateName/3 callback function
@@ -1560,17 +1561,22 @@ terminate(
Class, Reason, Stacktrace, Debug,
#{module := Module, state := State, data := Data, postponed := P} = S,
Q) ->
- try Module:terminate(Reason, State, Data) of
- _ -> ok
- catch
- _ -> ok;
- C:R ->
- ST = erlang:get_stacktrace(),
- error_info(
- C, R, ST, S, Q, P,
- format_status(terminate, get(), S)),
- sys:print_log(Debug),
- erlang:raise(C, R, ST)
+ case erlang:function_exported(Module, terminate, 3) of
+ true ->
+ try Module:terminate(Reason, State, Data) of
+ _ -> ok
+ catch
+ _ -> ok;
+ C:R ->
+ ST = erlang:get_stacktrace(),
+ error_info(
+ C, R, ST, S, Q, P,
+ format_status(terminate, get(), S)),
+ sys:print_log(Debug),
+ erlang:raise(C, R, ST)
+ end;
+ false ->
+ ok
end,
_ =
case Reason of