From 9a472f2899519234198f677269c5e70362bec351 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Fri, 23 Feb 2018 18:19:36 +0100 Subject: kernel: Remove redundant code No need to clear them as they cannot be set. --- lib/kernel/src/dist_util.erl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl index 5ea0ca991f..88718ee531 100644 --- a/lib/kernel/src/dist_util.erl +++ b/lib/kernel/src/dist_util.erl @@ -184,9 +184,7 @@ make_this_flags(RequestType, AddFlags, RemoveFlags, OtherNode) -> Flgs0 = ?DFLAGS_THIS_DEFAULT, Flgs1 = Flgs0 bor publish_flag(RequestType, OtherNode), Flgs2 = Flgs1 bor AddFlags, - Flgs3 = Flgs2 band (bnot (?DFLAG_HIDDEN_ATOM_CACHE - bor ?DFLAG_ATOM_CACHE)), - Flgs3 band (bnot RemoveFlags). + Flgs2 band (bnot RemoveFlags). handshake_other_started(#hs_data{request_type=ReqType, add_flags=AddFlgs0, -- cgit v1.2.3 From 337919abe6ed9a97e15d5f471ef8f79d44cb8363 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 26 Feb 2018 15:36:34 +0100 Subject: erts,kernel: Add erts_internal:get_dflags/0 for kernel to ask erts about distribution flags and keep this info in one place. --- lib/kernel/src/dist_util.erl | 69 ++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 44 deletions(-) (limited to 'lib') diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl index 88718ee531..638b91e153 100644 --- a/lib/kernel/src/dist_util.erl +++ b/lib/kernel/src/dist_util.erl @@ -143,48 +143,29 @@ publish_flag(_, OtherNode) -> 0 end. --define(DFLAGS_REMOVABLE, - (?DFLAG_DIST_HDR_ATOM_CACHE - bor ?DFLAG_HIDDEN_ATOM_CACHE - bor ?DFLAG_ATOM_CACHE)). - --define(DFLAGS_ADDABLE, - (?DFLAGS_ALL - band (bnot (?DFLAG_PUBLISHED - bor ?DFLAG_HIDDEN_ATOM_CACHE - bor ?DFLAG_ATOM_CACHE)))). - --define(DFLAGS_THIS_DEFAULT, - (?DFLAG_EXPORT_PTR_TAG - bor ?DFLAG_EXTENDED_PIDS_PORTS - bor ?DFLAG_EXTENDED_REFERENCES - bor ?DFLAG_DIST_MONITOR - bor ?DFLAG_FUN_TAGS - bor ?DFLAG_DIST_MONITOR_NAME - bor ?DFLAG_NEW_FUN_TAGS - bor ?DFLAG_BIT_BINARIES - bor ?DFLAG_NEW_FLOATS - bor ?DFLAG_UNICODE_IO - bor ?DFLAG_DIST_HDR_ATOM_CACHE - bor ?DFLAG_SMALL_ATOM_TAGS - bor ?DFLAG_UTF8_ATOMS - bor ?DFLAG_MAP_TAG - bor ?DFLAG_BIG_CREATION - bor ?DFLAG_SEND_SENDER)). - -make_this_flags(RequestType, AddFlags, RemoveFlags, OtherNode) -> - case RemoveFlags band (bnot ?DFLAGS_REMOVABLE) of + +%% Sync with dist.c +-record(erts_dflags, { + default, % flags erts prefers + mandatory, % flags erts needs + addable, % flags local dist implementation is allowed to add + rejectable % flags local dist implementation is allowed to reject +}). + +make_this_flags(RequestType, AddFlags, RejectFlags, OtherNode, + #erts_dflags{}=EDF) -> + case RejectFlags band (bnot EDF#erts_dflags.rejectable) of 0 -> ok; Rerror -> exit({"Rejecting non rejectable flags", Rerror}) end, - case AddFlags band (bnot ?DFLAGS_ADDABLE) of + case AddFlags band (bnot EDF#erts_dflags.addable) of 0 -> ok; Aerror -> exit({"Adding non addable flags", Aerror}) end, - Flgs0 = ?DFLAGS_THIS_DEFAULT, + Flgs0 = EDF#erts_dflags.default, Flgs1 = Flgs0 bor publish_flag(RequestType, OtherNode), Flgs2 = Flgs1 bor AddFlags, - Flgs2 band (bnot RemoveFlags). + Flgs2 band (bnot RejectFlags). handshake_other_started(#hs_data{request_type=ReqType, add_flags=AddFlgs0, @@ -194,7 +175,8 @@ handshake_other_started(#hs_data{request_type=ReqType, RejFlgs = convert_flags(RejFlgs0), ReqFlgs = convert_flags(ReqFlgs0), {PreOtherFlags,Node,Version} = recv_name(HSData0), - PreThisFlags = make_this_flags(ReqType, AddFlgs, RejFlgs, Node), + EDF = erts_internal:get_dflags(), + PreThisFlags = make_this_flags(ReqType, AddFlgs, RejFlgs, Node, EDF), {ThisFlags, OtherFlags} = adjust_flags(PreThisFlags, PreOtherFlags, RejFlgs), @@ -206,7 +188,7 @@ handshake_other_started(#hs_data{request_type=ReqType, add_flags=AddFlgs, reject_flags=RejFlgs, require_flags=ReqFlgs}, - check_dflags(HSData), + check_dflags(HSData, EDF), is_allowed(HSData), ?debug({"MD5 connection from ~p (V~p)~n", [Node, HSData#hs_data.other_version]}), @@ -245,12 +227,10 @@ is_allowed(#hs_data{other_node = Node, check_dflags(#hs_data{other_node = Node, other_flags = OtherFlags, other_started = OtherStarted, - require_flags = RequiredFlags} = HSData) -> - Mandatory = ((?DFLAG_EXTENDED_REFERENCES - bor ?DFLAG_EXTENDED_PIDS_PORTS - bor ?DFLAG_UTF8_ATOMS - bor ?DFLAG_NEW_FUN_TAGS) - bor RequiredFlags), + require_flags = RequiredFlags} = HSData, + #erts_dflags{}=EDF) -> + + Mandatory = (EDF#erts_dflags.mandatory bor RequiredFlags), Missing = check_mandatory(0, ?DFLAGS_ALL, Mandatory, OtherFlags, []), case Missing of @@ -408,7 +388,8 @@ handshake_we_started(#hs_data{request_type=ReqType, AddFlgs = convert_flags(AddFlgs0), RejFlgs = convert_flags(RejFlgs0), ReqFlgs = convert_flags(ReqFlgs0), - PreThisFlags = make_this_flags(ReqType, AddFlgs, RejFlgs, Node), + EDF = erts_internal:get_dflags(), + PreThisFlags = make_this_flags(ReqType, AddFlgs, RejFlgs, Node, EDF), HSData = PreHSData#hs_data{this_flags = PreThisFlags, add_flags = AddFlgs, reject_flags = RejFlgs, @@ -422,7 +403,7 @@ handshake_we_started(#hs_data{request_type=ReqType, NewHSData = HSData#hs_data{this_flags = ThisFlags, other_flags = OtherFlags, other_started = false}, - check_dflags(NewHSData), + check_dflags(NewHSData, EDF), MyChallenge = gen_challenge(), {MyCookie,HisCookie} = get_cookies(Node), send_challenge_reply(NewHSData,MyChallenge, -- cgit v1.2.3 From 7917c31757994f4f2fd344d0529de8bb193adc85 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 26 Feb 2018 15:54:44 +0100 Subject: kernel: Simplify dist flags handshake merging to a simple 'band' operation into ChosenFlags and no need to remember old 'this_flags' and 'other_flags'. --- lib/kernel/src/dist_util.erl | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) (limited to 'lib') diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl index 638b91e153..5871e7e8ee 100644 --- a/lib/kernel/src/dist_util.erl +++ b/lib/kernel/src/dist_util.erl @@ -116,22 +116,8 @@ dflag2str(_) -> "UNKNOWN". -remove_flag(Flag, Flags) -> - case Flags band Flag of - 0 -> - Flags; - _ -> - Flags - Flag - end. - -adjust_flags(ThisFlags, OtherFlags, RejectFlags) -> - case (?DFLAG_PUBLISHED band ThisFlags) band OtherFlags of - 0 -> - {remove_flag(?DFLAG_PUBLISHED, ThisFlags), - remove_flag(?DFLAG_PUBLISHED, OtherFlags)}; - _ -> - {ThisFlags, OtherFlags band (bnot RejectFlags)} - end. +adjust_flags(ThisFlags, OtherFlags) -> + ThisFlags band OtherFlags. publish_flag(hidden, _) -> 0; @@ -177,11 +163,9 @@ handshake_other_started(#hs_data{request_type=ReqType, {PreOtherFlags,Node,Version} = recv_name(HSData0), EDF = erts_internal:get_dflags(), PreThisFlags = make_this_flags(ReqType, AddFlgs, RejFlgs, Node, EDF), - {ThisFlags, OtherFlags} = adjust_flags(PreThisFlags, - PreOtherFlags, - RejFlgs), - HSData = HSData0#hs_data{this_flags=ThisFlags, - other_flags=OtherFlags, + ChosenFlags = adjust_flags(PreThisFlags, PreOtherFlags), + HSData = HSData0#hs_data{this_flags=ChosenFlags, + other_flags=ChosenFlags, other_version=Version, other_node=Node, other_started=true, @@ -397,11 +381,9 @@ handshake_we_started(#hs_data{request_type=ReqType, send_name(HSData), recv_status(HSData), {PreOtherFlags,ChallengeA} = recv_challenge(HSData), - {ThisFlags,OtherFlags} = adjust_flags(PreThisFlags, - PreOtherFlags, - RejFlgs), - NewHSData = HSData#hs_data{this_flags = ThisFlags, - other_flags = OtherFlags, + ChosenFlags = adjust_flags(PreThisFlags, PreOtherFlags), + NewHSData = HSData#hs_data{this_flags = ChosenFlags, + other_flags = ChosenFlags, other_started = false}, check_dflags(NewHSData, EDF), MyChallenge = gen_challenge(), -- cgit v1.2.3 From 2709c93ede0be977ac13543d0fabe8ff3c27f4cc Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 26 Feb 2018 16:59:39 +0100 Subject: kernel: Remove DFLAGS_ALL from dist.hrl and remove use in dist_util:check_mandatory --- lib/kernel/include/dist.hrl | 21 --------------------- lib/kernel/src/dist_util.erl | 20 +++++++++----------- 2 files changed, 9 insertions(+), 32 deletions(-) (limited to 'lib') diff --git a/lib/kernel/include/dist.hrl b/lib/kernel/include/dist.hrl index db4a5eaebc..986aca6c26 100644 --- a/lib/kernel/include/dist.hrl +++ b/lib/kernel/include/dist.hrl @@ -49,24 +49,3 @@ %% Also update dflag2str() in ../src/dist_util.erl %% when adding flags... - --define(DFLAGS_ALL, - (?DFLAG_PUBLISHED - bor ?DFLAG_ATOM_CACHE - bor ?DFLAG_EXTENDED_REFERENCES - bor ?DFLAG_DIST_MONITOR - bor ?DFLAG_FUN_TAGS - bor ?DFLAG_DIST_MONITOR_NAME - bor ?DFLAG_HIDDEN_ATOM_CACHE - bor ?DFLAG_NEW_FUN_TAGS - bor ?DFLAG_EXTENDED_PIDS_PORTS - bor ?DFLAG_EXPORT_PTR_TAG - bor ?DFLAG_BIT_BINARIES - bor ?DFLAG_NEW_FLOATS - bor ?DFLAG_UNICODE_IO - bor ?DFLAG_DIST_HDR_ATOM_CACHE - bor ?DFLAG_SMALL_ATOM_TAGS - bor ?DFLAG_UTF8_ATOMS - bor ?DFLAG_MAP_TAG - bor ?DFLAG_BIG_CREATION - bor ?DFLAG_SEND_SENDER)). diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl index 5871e7e8ee..5614b80802 100644 --- a/lib/kernel/src/dist_util.erl +++ b/lib/kernel/src/dist_util.erl @@ -215,8 +215,7 @@ check_dflags(#hs_data{other_node = Node, #erts_dflags{}=EDF) -> Mandatory = (EDF#erts_dflags.mandatory bor RequiredFlags), - Missing = check_mandatory(0, ?DFLAGS_ALL, Mandatory, - OtherFlags, []), + Missing = check_mandatory(Mandatory, OtherFlags, []), case Missing of [] -> ok; @@ -236,21 +235,20 @@ check_dflags(#hs_data{other_node = Node, ?shutdown2(Node, {check_dflags_failed, Missing}) end. -check_mandatory(_Bit, 0, _Mandatory, _OtherFlags, Missing) -> +check_mandatory(0, _OtherFlags, Missing) -> Missing; -check_mandatory(Bit, Left, Mandatory, OtherFlags, Missing) -> - DFlag = (1 bsl Bit), - NewLeft = Left band (bnot DFlag), - NewMissing = case {DFlag band Mandatory, - DFlag band OtherFlags} of - {DFlag, 0} -> +check_mandatory(Mandatory, OtherFlags, Missing) -> + Left = Mandatory band (Mandatory - 1), % clear lowest set bit + DFlag = Mandatory bxor Left, % only lowest set bit + NewMissing = case DFlag band OtherFlags of + 0 -> %% Mandatory and missing... [dflag2str(DFlag) | Missing]; _ -> - %% Not mandatory or present... + %% Mandatory and present... Missing end, - check_mandatory(Bit+1, NewLeft, Mandatory, OtherFlags, NewMissing). + check_mandatory(Left, OtherFlags, NewMissing). %% No nodedown will be sent if we fail before this process has -- cgit v1.2.3 From 7fb3ed7d2731050186eb5224fe8e6050e4909341 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 26 Feb 2018 20:40:51 +0100 Subject: erts,kernel: Add dist_util:strict_order_flags/0 to replace DFLAGS_STRICT_ORDER_DELIVERY and remove that compile time dependency. --- lib/kernel/include/dist.hrl | 5 ----- lib/kernel/src/dist_util.erl | 9 ++++++++- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/kernel/include/dist.hrl b/lib/kernel/include/dist.hrl index 986aca6c26..b7c35712a6 100644 --- a/lib/kernel/include/dist.hrl +++ b/lib/kernel/include/dist.hrl @@ -42,10 +42,5 @@ -define(DFLAG_BIG_CREATION, 16#40000). -define(DFLAG_SEND_SENDER, 16#80000). -%% DFLAGs that require strict ordering or:ed together... --define(DFLAGS_STRICT_ORDER_DELIVERY, - ?DFLAG_DIST_HDR_ATOM_CACHE). - - %% Also update dflag2str() in ../src/dist_util.erl %% when adding flags... diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl index 5614b80802..3927b64b06 100644 --- a/lib/kernel/src/dist_util.erl +++ b/lib/kernel/src/dist_util.erl @@ -27,6 +27,7 @@ %%-compile(export_all). -export([handshake_we_started/1, handshake_other_started/1, + strict_order_flags/0, start_timer/1, setup_timer/2, reset_timer/1, cancel_timer/1, shutdown/3, shutdown/4]). @@ -135,9 +136,15 @@ publish_flag(_, OtherNode) -> default, % flags erts prefers mandatory, % flags erts needs addable, % flags local dist implementation is allowed to add - rejectable % flags local dist implementation is allowed to reject + rejectable, % flags local dist implementation is allowed to reject + strict_order % flags for features needing strict order delivery }). +-spec strict_order_flags() -> integer(). +strict_order_flags() -> + EDF = erts_internal:get_dflags(), + EDF#erts_dflags.strict_order. + make_this_flags(RequestType, AddFlags, RejectFlags, OtherNode, #erts_dflags{}=EDF) -> case RejectFlags band (bnot EDF#erts_dflags.rejectable) of -- cgit v1.2.3 From e8d0a8654ecf85f89a0c0f7aa26da8bc467e9373 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Fri, 2 Mar 2018 16:51:11 +0100 Subject: stdlib: Remove obsolete use of monitor_node as fallback when erlang:monitor failed toward primitive nodes, which it does not do in OTP-21. --- lib/stdlib/src/gen.erl | 38 ++------------------------------------ 1 file changed, 2 insertions(+), 36 deletions(-) (limited to 'lib') diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl index 0e6f49d99f..dc957b4d4e 100644 --- a/lib/stdlib/src/gen.erl +++ b/lib/stdlib/src/gen.erl @@ -158,8 +158,7 @@ call(Process, Label, Request, Timeout) do_for_proc(Process, Fun). do_call(Process, Label, Request, Timeout) -> - try erlang:monitor(process, Process) of - Mref -> + Mref = erlang:monitor(process, Process), %% If the monitor/2 call failed to set up a connection to a %% remote node, we don't want the '!' operator to attempt %% to set up the connection again. (If the monitor/2 call @@ -183,27 +182,7 @@ do_call(Process, Label, Request, Timeout) -> after Timeout -> erlang:demonitor(Mref, [flush]), exit(timeout) - end - catch - error:_ -> - %% Node (C/Java?) is not supporting the monitor. - %% The other possible case -- this node is not distributed - %% -- should have been handled earlier. - %% Do the best possible with monitor_node/2. - %% This code may hang indefinitely if the Process - %% does not exist. It is only used for featureweak remote nodes. - Node = get_node(Process), - monitor_node(Node, true), - receive - {nodedown, Node} -> - monitor_node(Node, false), - exit({nodedown, Node}) - after 0 -> - Tag = make_ref(), - Process ! {Label, {self(), Tag}, Request}, - wait_resp(Node, Tag, Timeout) - end - end. + end. get_node(Process) -> %% We trust the arguments to be correct, i.e @@ -217,19 +196,6 @@ get_node(Process) -> node(Process) end. -wait_resp(Node, Tag, Timeout) -> - receive - {Tag, Reply} -> - monitor_node(Node, false), - {ok, Reply}; - {nodedown, Node} -> - monitor_node(Node, false), - exit({nodedown, Node}) - after Timeout -> - monitor_node(Node, false), - exit(timeout) - end. - %% %% Send a reply to the client. %% -- cgit v1.2.3 From 3e580e039a8eb2467c638503bc526116fe829fec Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Fri, 2 Mar 2018 16:56:13 +0100 Subject: kernel,stdlib: Remove obsolete use of send with 'noconnect' as workarounds to avoid blocking auto-connect, which is now asynchronous in OTP-21. Also changed old catch to more efficient try-catch. --- lib/kernel/src/net_kernel.erl | 8 ++++---- lib/kernel/src/rpc.erl | 5 +---- lib/stdlib/src/gen.erl | 45 ++++++++++++++++++++----------------------- lib/stdlib/src/gen_server.erl | 11 +++++------ lib/stdlib/src/gen_statem.erl | 13 ++++--------- 5 files changed, 35 insertions(+), 47 deletions(-) (limited to 'lib') diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl index cdb10a7b12..f38989d103 100644 --- a/lib/kernel/src/net_kernel.erl +++ b/lib/kernel/src/net_kernel.erl @@ -1777,16 +1777,16 @@ async_reply({reply, Msg, State}, From) -> async_gen_server_reply(From, Msg) -> {Pid, Tag} = From, M = {Tag, Msg}, - case catch erlang:send(Pid, M, [nosuspend, noconnect]) of + try erlang:send(Pid, M, [nosuspend, noconnect]) of ok -> ok; nosuspend -> _ = spawn(fun() -> catch erlang:send(Pid, M, [noconnect]) end), ok; noconnect -> - ok; % The gen module takes care of this case. - {'EXIT', _} -> - ok + ok % The gen module takes care of this case. + catch + _:_ -> ok end. call_owner(Owner, Msg) -> diff --git a/lib/kernel/src/rpc.erl b/lib/kernel/src/rpc.erl index 0e0b7dffa3..917e725fd6 100644 --- a/lib/kernel/src/rpc.erl +++ b/lib/kernel/src/rpc.erl @@ -418,10 +418,7 @@ abcast(Name, Mess) -> abcast([Node|Tail], Name, Mess) -> Dest = {Name,Node}, - case catch erlang:send(Dest, Mess, [noconnect]) of - noconnect -> spawn(erlang, send, [Dest,Mess]), ok; - _ -> ok - end, + try erlang:send(Dest, Mess) catch error:_ -> ok end, abcast(Tail, Name, Mess); abcast([], _,_) -> abcast. diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl index dc957b4d4e..293cb98ad2 100644 --- a/lib/stdlib/src/gen.erl +++ b/lib/stdlib/src/gen.erl @@ -159,30 +159,27 @@ call(Process, Label, Request, Timeout) do_call(Process, Label, Request, Timeout) -> Mref = erlang:monitor(process, Process), - %% If the monitor/2 call failed to set up a connection to a - %% remote node, we don't want the '!' operator to attempt - %% to set up the connection again. (If the monitor/2 call - %% failed due to an expired timeout, '!' too would probably - %% have to wait for the timeout to expire.) Therefore, - %% use erlang:send/3 with the 'noconnect' option so that it - %% will fail immediately if there is no connection to the - %% remote node. - - catch erlang:send(Process, {Label, {self(), Mref}, Request}, - [noconnect]), - receive - {Mref, Reply} -> - erlang:demonitor(Mref, [flush]), - {ok, Reply}; - {'DOWN', Mref, _, _, noconnection} -> - Node = get_node(Process), - exit({nodedown, Node}); - {'DOWN', Mref, _, _, Reason} -> - exit(Reason) - after Timeout -> - erlang:demonitor(Mref, [flush]), - exit(timeout) - end. + %% OTP-21: + %% Auto-connect is asynchronous. But we still use 'noconnect' to make sure + %% we send on the monitored connection, and not trigger a new auto-connect. + try erlang:send(Process, {Label, {self(), Mref}, Request}, [noconnect]) + catch + error:_ -> ok + end, + + receive + {Mref, Reply} -> + erlang:demonitor(Mref, [flush]), + {ok, Reply}; + {'DOWN', Mref, _, _, noconnection} -> + Node = get_node(Process), + exit({nodedown, Node}); + {'DOWN', Mref, _, _, Reason} -> + exit(Reason) + after Timeout -> + erlang:demonitor(Mref, [flush]), + exit(timeout) + end. get_node(Process) -> %% We trust the arguments to be correct, i.e diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl index 77a46419f6..f29314d0a2 100644 --- a/lib/stdlib/src/gen_server.erl +++ b/lib/stdlib/src/gen_server.erl @@ -437,12 +437,11 @@ decode_msg(Msg, Parent, Name, State, Mod, Time, HibernateAfterTimeout, Debug, Hi %%% Send/receive functions %%% --------------------------------------------------- do_send(Dest, Msg) -> - case catch erlang:send(Dest, Msg, [noconnect]) of - noconnect -> - spawn(erlang, send, [Dest,Msg]); - Other -> - Other - end. + try erlang:send(Dest, Msg) + catch + error:_ -> ok + end, + ok. do_multi_call(Nodes, Name, Req, infinity) -> Tag = make_ref(), diff --git a/lib/stdlib/src/gen_statem.erl b/lib/stdlib/src/gen_statem.erl index f95b2ea9cd..9dc360a289 100644 --- a/lib/stdlib/src/gen_statem.erl +++ b/lib/stdlib/src/gen_statem.erl @@ -641,16 +641,11 @@ replies([]) -> %% Might actually not send the message in case of caught exception send(Proc, Msg) -> - try erlang:send(Proc, Msg, [noconnect]) of - noconnect -> - _ = spawn(erlang, send, [Proc,Msg]), - ok; - ok -> - ok + try erlang:send(Proc, Msg) catch - _:_ -> - ok - end. + error:_ -> ok + end, + ok. %% Here the init_it/6 and enter_loop/5,6,7 functions converge enter(Module, Opts, State, Data, Server, Actions, Parent) -> -- cgit v1.2.3 From 5a1b9a836675b025eb1611f23ee9e2f5e4efa156 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 5 Mar 2018 15:47:59 +0100 Subject: stdlib: Fix receive-ref optimization for gen_server:call Optimization does not trigger for try-catch. But send cannot fail here anyway, as Process cannot be an atom. --- lib/stdlib/src/gen.erl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl index 293cb98ad2..2e6223d2bb 100644 --- a/lib/stdlib/src/gen.erl +++ b/lib/stdlib/src/gen.erl @@ -157,15 +157,14 @@ call(Process, Label, Request, Timeout) Fun = fun(Pid) -> do_call(Pid, Label, Request, Timeout) end, do_for_proc(Process, Fun). -do_call(Process, Label, Request, Timeout) -> +do_call(Process, Label, Request, Timeout) when is_atom(Process) =:= false -> Mref = erlang:monitor(process, Process), + %% OTP-21: %% Auto-connect is asynchronous. But we still use 'noconnect' to make sure %% we send on the monitored connection, and not trigger a new auto-connect. - try erlang:send(Process, {Label, {self(), Mref}, Request}, [noconnect]) - catch - error:_ -> ok - end, + %% + erlang:send(Process, {Label, {self(), Mref}, Request}, [noconnect]), receive {Mref, Reply} -> -- cgit v1.2.3