diff options
author | Steve Vinoski <[email protected]> | 2014-03-19 11:45:11 -0400 |
---|---|---|
committer | Steve Vinoski <[email protected]> | 2014-03-21 10:19:51 -0400 |
commit | 6c298a7bfa332e5b7d153648d741740abc3bcdf8 (patch) | |
tree | 3f8a5604555b8a3b959c5184bba59d9c65b0da3a /system | |
parent | 73af231f1a22083031df49ba19fdfd4f6b434a10 (diff) | |
download | otp-6c298a7bfa332e5b7d153648d741740abc3bcdf8.tar.gz otp-6c298a7bfa332e5b7d153648d741740abc3bcdf8.tar.bz2 otp-6c298a7bfa332e5b7d153648d741740abc3bcdf8.zip |
fix sys:get_state/1,2 and sys:replace_state/2,3 when sys suspended
Add two new system callbacks Module:system_get_state/1 and
Module:system_replace_state/2 to allow sys:get_state/1,2 and
sys:replace_state/2,3 to operate correctly even if a process is sys
suspended. Modify gen_server, gen_fsm, and gen_event to support the new
callbacks.
If a callback module does not export these functions, then by default the
Misc value (the same as that passed as the final argument to
sys:handle_system_msg/6, and returned as part of the return value of
sys:get_status/1,2) is treated as the callback module's state.
The previous behaviour of intercepting the system message and passing a
tuple of size 2 as the last argument to sys:handle_system_msg/6 is no
longer supported.
Add tests to verify the correctness of sys:get_state/1,2 and
sys:replace_state/2,3 when processes are sys suspended. Add two tests for
modules that implement special processes, one that exports
system_get_state/1 and system_replace_state/2 and one that doesn't.
Much of the credit for this patch goes to James Fish, who reported the
initial problem and implemented much of the fix.
Diffstat (limited to 'system')
-rw-r--r-- | system/doc/design_principles/spec_proc.xml | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/system/doc/design_principles/spec_proc.xml b/system/doc/design_principles/spec_proc.xml index 8de7a5fe03..d55427aa10 100644 --- a/system/doc/design_principles/spec_proc.xml +++ b/system/doc/design_principles/spec_proc.xml @@ -130,7 +130,8 @@ ok -export([alloc/0, free/1]). -export([init/1]). -export([system_continue/3, system_terminate/4, - write_debug/3]). + write_debug/3, + system_get_state/1, system_replace_state/2]). start_link() -> proc_lib:start_link(ch4, init, [self()]). @@ -177,9 +178,21 @@ loop(Chs, Parent, Deb) -> system_continue(Parent, Deb, Chs) -> loop(Chs, Parent, Deb). -system_terminate(Reason, Parent, Deb, Chs) -> +system_terminate(Reason, _Parent, _Deb, _Chs) -> exit(Reason). +system_get_state(Chs) -> + {ok, Chs}. + +system_replace_state(StateFun, Chs) -> + try + NChs = StateFun(Chs), + {ok, NChs, NChs} + catch + _:_ -> + {ok, Chs, Chs} + end. + write_debug(Dev, Event, Name) -> io:format(Dev, "~p event = ~p~n", [Name, Event]).</pre> <p>Example on how the simple debugging functions in <c>sys</c> can @@ -366,8 +379,15 @@ Module:system_terminate(Reason, Parent, Deb, State)</code> <item><c>Module</c> is the name of the module.</item> <item><c>Deb</c> is the debug structure.</item> <item><c>State</c> is a term describing the internal state and - is passed to <c>system_continue</c>/<c>system_terminate</c>.</item> + is passed to <c>system_continue</c>/<c>system_terminate</c>/ + <c>system_get_state</c>/<c>system_replace_state</c>.</item> </list> + <p>If the process should return its state <c>handle_system_msg</c> will call:</p> + <code type="none"> +Module:system_get_state(State)</code> + <p>or if the process should replace its state using the fun <c>StateFun</c>:</p> + <code type="none"> +Module:system_replace_state(StateFun, State)</code> <p>In the example:</p> <code type="none"> loop(Chs, Parent, Deb) -> @@ -383,7 +403,19 @@ system_continue(Parent, Deb, Chs) -> loop(Chs, Parent, Deb). system_terminate(Reason, Parent, Deb, Chs) -> - exit(Reason).</code> + exit(Reason). + +system_get_state(Chs) -> + {ok, Chs, Chs}. + +system_replace_state(StateFun, Chs) -> + try + NChs = StateFun(Chs), + {ok, NChs, NChs} + catch + _:_ -> + {ok, Chs, Chs} + end.</code> <p>If the special process is set to trap exits, note that if the parent process terminates, the expected behavior is to terminate with the same reason:</p> |