diff options
author | Micael Karlberg <[email protected]> | 2019-05-02 12:51:52 +0200 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2019-05-29 18:41:30 +0200 |
commit | 50620e6a44a9e0dc32d51a436b0cc05c44884d1b (patch) | |
tree | 5360cdf16f98ff216a587faa4cba232f3bbbe4ea /erts | |
parent | 043cb47a1967a63b316c7bd4cb4232f2e9b0f895 (diff) | |
download | otp-50620e6a44a9e0dc32d51a436b0cc05c44884d1b.tar.gz otp-50620e6a44a9e0dc32d51a436b0cc05c44884d1b.tar.bz2 otp-50620e6a44a9e0dc32d51a436b0cc05c44884d1b.zip |
[esock] Changed return value for a selected async call
The return value for an async call (Timeout = nowait) will now
(normally) result in a {select, SelectInfo} instead (if a select
was performed).
OTP-15731
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/test/socket_SUITE.erl | 84 | ||||
-rw-r--r-- | erts/emulator/test/socket_test_ttest_tcp_server.erl | 2 | ||||
-rw-r--r-- | erts/preloaded/ebin/socket.beam | bin | 74636 -> 74796 bytes | |||
-rw-r--r-- | erts/preloaded/src/socket.erl | 66 |
4 files changed, 83 insertions, 69 deletions
diff --git a/erts/emulator/test/socket_SUITE.erl b/erts/emulator/test/socket_SUITE.erl index 52854cb7ad..66cbdda9c7 100644 --- a/erts/emulator/test/socket_SUITE.erl +++ b/erts/emulator/test/socket_SUITE.erl @@ -2708,6 +2708,8 @@ api_a_sendmsg_and_recvmsg_udp4(_Config) when is_list(_Config) -> {ok, {Source, Data}}; {ok, _} = OK -> OK; + {select, _} = SELECT -> + SELECT; {error, _} = ERROR -> ERROR end @@ -2776,7 +2778,10 @@ api_a_send_and_recv_udp(InitState) -> #{desc => "try recv request (with nowait, expect select)", cmd => fun(#{sock := Sock, recv := Recv} = State) -> case Recv(Sock) of - {ok, {select, Tag, RecvRef}} -> + {select, {select_info, Tag, RecvRef}} -> + ?SEV_IPRINT("expected select: " + "~n Tag: ~p" + "~n Ref: ~p", [Tag, RecvRef]), {ok, State#{recv_stag => Tag, recv_sref => RecvRef}}; {ok, X} -> @@ -2795,6 +2800,9 @@ api_a_send_and_recv_udp(InitState) -> receive {'$socket', Sock, select, RecvRef} -> ok + after 5000 -> + ?SEV_EPRINT("message queue: ~p", [mq()]), + {error, timeout} end end}, #{desc => "announce ready (select)", @@ -2919,7 +2927,7 @@ api_a_send_and_recv_udp(InitState) -> #{desc => "try recv reply (with nowait)", cmd => fun(#{sock := Sock, recv := Recv} = State) -> case Recv(Sock) of - {ok, {select, Tag, RecvRef}} -> + {select, {select_info, Tag, RecvRef}} -> {ok, State#{recv_stag => Tag, recv_sref => RecvRef}}; {ok, X} -> @@ -3188,8 +3196,10 @@ api_a_sendmsg_and_recvmsg_tcp4(_Config) when is_list(_Config) -> {ok, #{addr := undefined, iov := [Data]}} -> {ok, Data}; - {ok, _} = OK -> + {ok, _} = OK -> OK; + {select, _} = SELECT -> + SELECT; {error, _} = ERROR -> ERROR end @@ -3261,7 +3271,7 @@ api_a_send_and_recv_tcp(InitState) -> #{desc => "await connection (nowait)", cmd => fun(#{lsock := LSock} = State) -> case socket:accept(LSock, nowait) of - {ok, {select, Tag, Ref}} -> + {select, {select_info, Tag, Ref}} -> ?SEV_IPRINT("accept select: " "~n Tag: ~p" "~n Ref: ~p", [Tag, Ref]), @@ -3314,7 +3324,7 @@ api_a_send_and_recv_tcp(InitState) -> #{desc => "try recv request (with nowait, expect select)", cmd => fun(#{csock := Sock, recv := Recv} = State) -> case Recv(Sock) of - {ok, {select, Tag, Ref}} -> + {select, {select_info, Tag, Ref}} -> ?SEV_IPRINT("recv select: " "~n Tag: ~p" "~n Ref: ~p", [Tag, Ref]), @@ -3473,7 +3483,7 @@ api_a_send_and_recv_tcp(InitState) -> #{desc => "try recv reply (with nowait, expect select)", cmd => fun(#{sock := Sock, recv := Recv} = State) -> case Recv(Sock) of - {ok, {select, Tag, Ref}} -> + {select, {select_info, Tag, Ref}} -> ?SEV_IPRINT("recv select: " "~n Tag: ~p" "~n Ref: ~p", [Tag, Ref]), @@ -3715,6 +3725,8 @@ api_a_recvfrom_cancel_udp4(_Config) when is_list(_Config) -> case socket:recvfrom(Sock, 0, nowait) of {ok, _} = OK -> OK; + {select, _} = SELECT -> + SELECT; {error, _} = ERROR -> ERROR end @@ -3743,6 +3755,8 @@ api_a_recvmsg_cancel_udp4(_Config) when is_list(_Config) -> case socket:recvmsg(Sock, nowait) of {ok, _} = OK -> OK; + {select, _} = SELECT -> + SELECT; {error, _} = ERROR -> ERROR end @@ -3810,7 +3824,7 @@ api_a_recv_cancel_udp(InitState) -> #{desc => "try recv request (with nowait, expect select)", cmd => fun(#{sock := Sock, recv := Recv} = State) -> case Recv(Sock) of - {ok, {select, _, _} = SelectInfo} -> + {select, SelectInfo} -> {ok, State#{recv_select_info => SelectInfo}}; {ok, X} -> {error, {unexpected_select_info, X}}; @@ -3975,6 +3989,8 @@ api_a_accept_cancel_tcp4(_Config) when is_list(_Config) -> case socket:accept(Sock, nowait) of {ok, _} = OK -> OK; + {select, _} = SELECT -> + SELECT; {error, _} = ERROR -> ERROR end @@ -4047,7 +4063,7 @@ api_a_accept_cancel_tcp(InitState) -> #{desc => "await connection (nowait)", cmd => fun(#{lsock := LSock, accept := Accept} = State) -> case Accept(LSock) of - {ok, {select, T, R} = SelectInfo} -> + {select, {select_info, T, R} = SelectInfo} -> ?SEV_IPRINT("accept select: " "~n T: ~p" "~n R: ~p", [T, R]), @@ -4311,7 +4327,7 @@ api_a_recv_cancel_tcp(InitState) -> #{desc => "try recv request (with nowait, expect select)", cmd => fun(#{csock := Sock, recv := Recv} = State) -> case Recv(Sock) of - {ok, {select, T, R} = SelectInfo} -> + {select, {select_info, T, R} = SelectInfo} -> ?SEV_IPRINT("recv select: " "~n Tag: ~p" "~n Ref: ~p", [T, R]), @@ -4611,6 +4627,8 @@ api_a_mrecvfrom_cancel_udp4(_Config) when is_list(_Config) -> case socket:recvfrom(Sock, 0, nowait) of {ok, _} = OK -> OK; + {select, _} = SELECT -> + SELECT; {error, _} = ERROR -> ERROR end @@ -4640,6 +4658,8 @@ api_a_mrecvmsg_cancel_udp4(_Config) when is_list(_Config) -> case socket:recvmsg(Sock, nowait) of {ok, _} = OK -> OK; + {select, _} = SELECT -> + SELECT; {error, _} = ERROR -> ERROR end @@ -4707,7 +4727,7 @@ api_a_mrecv_cancel_udp(InitState) -> #{desc => "try recv request (with nowait, expect select)", cmd => fun(#{sock := Sock, recv := Recv} = State) -> case Recv(Sock) of - {ok, {select, _, _} = SelectInfo} -> + {select, SelectInfo} -> {ok, State#{recv_select_info => SelectInfo}}; {ok, X} -> {error, {unexpected_select_info, X}}; @@ -4722,16 +4742,14 @@ api_a_mrecv_cancel_udp(InitState) -> end}, #{desc => "await abort message", cmd => fun(#{sock := Sock, - recv_select_info := {select, _, Ref}} = State) -> + recv_select_info := {select_info, _, Ref}} = State) -> receive {'$socket', Sock, select, Ref} -> {error, {unexpected_select, Ref}}; {'$socket', Sock, abort, {Ref, closed}} -> {ok, maps:remove(sock, State)} after 5000 -> - ?SEV_IPRINT("message queue: ~p", - [process_info(self(), - messages)]), + ?SEV_EPRINT("message queue: ~p", [mq()]), {error, timeout} end end}, @@ -4788,7 +4806,7 @@ api_a_mrecv_cancel_udp(InitState) -> #{desc => "try recv request (with nowait, expect select)", cmd => fun(#{sock := Sock, recv := Recv} = State) -> case Recv(Sock) of - {ok, {select, _, _} = SelectInfo} -> + {select, SelectInfo} -> {ok, State#{recv_select_info => SelectInfo}}; {ok, X} -> {error, {unexpected_select_info, X}}; @@ -4803,16 +4821,14 @@ api_a_mrecv_cancel_udp(InitState) -> end}, #{desc => "await abort message", cmd => fun(#{sock := Sock, - recv_select_info := {select, _, Ref}} = State) -> + recv_select_info := {select_info, _, Ref}} = State) -> receive {'$socket', Sock, select, Ref} -> {error, {unexpected_select, Ref}}; {'$socket', Sock, abort, {Ref, closed}} -> {ok, maps:remove(sock, State)} after 5000 -> - ?SEV_IPRINT("message queue: ~p", - [process_info(self(), - messages)]), + ?SEV_EPRINT("message queue: ~p", [mq()]), {error, timeout} end end}, @@ -5033,6 +5049,8 @@ api_a_maccept_cancel_tcp4(_Config) when is_list(_Config) -> case socket:accept(Sock, nowait) of {ok, _} = OK -> OK; + {select, _} = SELECT -> + SELECT; {error, _} = ERROR -> ERROR end @@ -5106,7 +5124,7 @@ api_a_maccept_cancel_tcp(InitState) -> #{desc => "await connection (nowait)", cmd => fun(#{lsock := LSock, accept := Accept} = State) -> case Accept(LSock) of - {ok, {select, T, R} = SelectInfo} -> + {select, {select_info, T, R} = SelectInfo} -> ?SEV_IPRINT("accept select: " "~n T: ~p" "~n R: ~p", [T, R]), @@ -5124,16 +5142,14 @@ api_a_maccept_cancel_tcp(InitState) -> end}, #{desc => "await select message (without success)", cmd => fun(#{lsock := Sock, - accept_select_info := {select, _, Ref}} = State) -> + accept_select_info := {select_info, _, Ref}} = State) -> receive {'$socket', Sock, select, Ref} -> {error, {unexpected_select, Ref}}; {'$socket', Sock, abort, {Ref, closed}} -> {ok, maps:remove(lsock, State)} after 5000 -> - ?SEV_IPRINT("message queue: ~p", - [process_info(self(), - messages)]), + ?SEV_EPRINT("message queue: ~p", [mq()]), {error, timeout} end end}, @@ -5186,7 +5202,7 @@ api_a_maccept_cancel_tcp(InitState) -> #{desc => "try accept request (with nowait, expect select)", cmd => fun(#{lsock := Sock, accept := Accept} = State) -> case Accept(Sock) of - {ok, {select, _, _} = SelectInfo} -> + {select, SelectInfo} -> {ok, State#{accept_select_info => SelectInfo}}; {ok, X} -> {error, {unexpected_select_info, X}}; @@ -5201,16 +5217,14 @@ api_a_maccept_cancel_tcp(InitState) -> end}, #{desc => "await abort message", cmd => fun(#{lsock := Sock, - accept_select_info := {select, _, Ref}} = State) -> + accept_select_info := {select_info, _, Ref}} = State) -> receive {'$socket', Sock, select, Ref} -> {error, {unexpected_select, Ref}}; {'$socket', Sock, abort, {Ref, closed}} -> {ok, maps:remove(sock, State)} after 5000 -> - ?SEV_IPRINT("message queue: ~p", - [process_info(self(), - messages)]), + ?SEV_EPRINT("message queue: ~p", [mq()]), {error, timeout} end end}, @@ -5544,7 +5558,7 @@ api_a_mrecv_cancel_tcp(InitState) -> #{desc => "try recv request (with nowait, expect select)", cmd => fun(#{csock := Sock, recv := Recv} = State) -> case Recv(Sock) of - {ok, {select, T, R} = SelectInfo} -> + {select, {select_info, T, R} = SelectInfo} -> ?SEV_IPRINT("recv select: " "~n Tag: ~p" "~n Ref: ~p", [T, R]), @@ -5562,7 +5576,7 @@ api_a_mrecv_cancel_tcp(InitState) -> end}, #{desc => "await select message", cmd => fun(#{csock := Sock, - recv_select_info := {select, _, Ref}} = State) -> + recv_select_info := {select_info, _, Ref}} = State) -> receive {'$socket', Sock, select, Ref} -> {error, {unexpected_select, Ref}}; @@ -5624,7 +5638,7 @@ api_a_mrecv_cancel_tcp(InitState) -> #{desc => "try recv request (with nowait, expect select)", cmd => fun(#{sock := Sock, recv := Recv} = State) -> case Recv(Sock) of - {ok, {select, _, _} = SelectInfo} -> + {select, SelectInfo} -> {ok, State#{recv_select_info => SelectInfo}}; {ok, X} -> {error, {unexpected_select_info, X}}; @@ -5639,16 +5653,14 @@ api_a_mrecv_cancel_tcp(InitState) -> end}, #{desc => "await abort message", cmd => fun(#{sock := Sock, - recv_select_info := {select, _, Ref}} = State) -> + recv_select_info := {select_info, _, Ref}} = State) -> receive {'$socket', Sock, select, Ref} -> {error, {unexpected_select, Ref}}; {'$socket', Sock, abort, {Ref, closed}} -> {ok, maps:remove(sock, State)} after 5000 -> - ?SEV_IPRINT("message queue: ~p", - [process_info(self(), - messages)]), + ?SEV_EPRINT("message queue: ~p", [mq()]), {error, timeout} end end}, diff --git a/erts/emulator/test/socket_test_ttest_tcp_server.erl b/erts/emulator/test/socket_test_ttest_tcp_server.erl index f0a2ae73ec..27b561d4b7 100644 --- a/erts/emulator/test/socket_test_ttest_tcp_server.erl +++ b/erts/emulator/test/socket_test_ttest_tcp_server.erl @@ -169,7 +169,7 @@ server_init(Starter, Parent, Transport, Active) -> end. process_transport(Mod, _) when is_atom(Mod) -> - {Mod, false, fun(Port) -> Mod:listen(Port) end, infinity}; + {Mod, fun(Port) -> Mod:listen(Port) end, infinity}; process_transport({Mod, #{stats_interval := T} = Opts}, Active) when (Active =/= false) -> {Mod, fun(Port) -> Mod:listen(Port, Opts#{stats_to => self()}) end, T}; diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam Binary files differindex 7f5a27c980..fb4d9850e5 100644 --- a/erts/preloaded/ebin/socket.beam +++ b/erts/preloaded/ebin/socket.beam diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index ec63eeba64..60f162d37d 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -593,9 +593,13 @@ -type select_tag() :: atom(). -type select_ref() :: reference(). --type select_info() :: {select, select_tag(), select_ref()}. --define(SELECT_INFO(T, R), {select, T, R}). +-record(select_info, {tag :: select_tag(), ref :: select_ref()}). + +-type select_info() :: #select_info{}. + +-define(SELECT_INFO(T, R), #select_info{tag = T, ref = R}). +-define(SELECT(T, R), {select, ?SELECT_INFO(T, R)}). %% This is used in messages sent from the nif-code to erlang processes: @@ -1283,7 +1287,7 @@ accept(Socket) -> -spec accept(LSocket, nowait) -> {ok, Socket} | - {ok, SelectInfo} | + {select, SelectInfo} | {error, Reason} when LSocket :: socket(), Socket :: socket(), @@ -1314,7 +1318,7 @@ do_accept(LSockRef, Timeout) -> {error, eagain} when (Timeout =:= nowait) -> - {ok, ?SELECT_INFO(accept, AccRef)}; + ?SELECT(accept, AccRef); {error, eagain} -> @@ -1360,7 +1364,7 @@ send(Socket, Data) -> Flags :: send_flags(), Reason :: term() ; (Socket, Data, Timeout :: nowait) -> ok | - {ok, SelectInfo} | + {select, SelectInfo} | {ok, {RestData, SelectInfo}} | {error, Reason} when Socket :: socket(), @@ -1380,7 +1384,7 @@ send(Socket, Data, Timeout) -> send(Socket, Data, ?SOCKET_SEND_FLAGS_DEFAULT, Timeout). -spec send(Socket, Data, Flags, nowait) -> ok | - {ok, SelectInfo} | + {select, SelectInfo} | {ok, {RestData, SelectInfo}} | {error, Reason} when Socket :: socket(), @@ -1418,6 +1422,8 @@ do_send(SockRef, Data, EFlags, Timeout) -> {ok, Written} when (Timeout =:= nowait) -> <<_:Written/binary, Rest/binary>> = Data, + %% We are partially done, but the user don't want to wait (here) + %% for completion {ok, {Rest, ?SELECT_INFO(send, SendRef)}}; @@ -1445,7 +1451,7 @@ do_send(SockRef, Data, EFlags, Timeout) -> {error, eagain} when (Timeout =:= nowait) -> - {ok, ?SELECT_INFO(send, SendRef)}; + ?SELECT(send, SendRef); {error, eagain} -> @@ -1489,7 +1495,7 @@ sendto(Socket, Data, Dest) -> Flags :: send_flags(), Reason :: term() ; (Socket, Data, Dest, Timeout :: nowait) -> ok | - {ok, SelectInfo} | + {select, SelectInfo} | {error, Reason} when Socket :: socket(), Data :: iodata(), @@ -1510,7 +1516,7 @@ sendto(Socket, Data, Dest, Timeout) -> -spec sendto(Socket, Data, Dest, Flags, nowait) -> ok | - {ok, SelectInfo} | + {select, SelectInfo} | {error, Reason} when Socket :: socket(), Data :: binary(), @@ -1584,7 +1590,7 @@ do_sendto(SockRef, Data, Dest, EFlags, Timeout) -> {error, eagain} when (Timeout =:= nowait) -> - {ok, ?SELECT_INFO(sendto, SendRef)}; + ?SELECT(sendto, SendRef); {error, eagain} -> @@ -1631,7 +1637,7 @@ sendmsg(Socket, MsgHdr) -> Flags :: send_flags(), Reason :: term() ; (Socket, MsgHdr, Timeout :: nowait) -> ok | - {ok, SelectInfo} | + {select, SelectInfo} | {error, Reason} when Socket :: socket(), MsgHdr :: msghdr(), @@ -1653,7 +1659,7 @@ sendmsg(Socket, MsgHdr, Timeout) -spec sendmsg(Socket, MsgHdr, Flags, nowait) -> ok | {ok, Remaining} | - {ok, SelectInfo} | + {select, SelectInfo} | {error, Reason} when Socket :: socket(), MsgHdr :: msghdr(), @@ -1711,7 +1717,7 @@ do_sendmsg(SockRef, MsgHdr, EFlags, Timeout) -> {error, eagain} when (Timeout =:= nowait) -> - {ok, ?SELECT_INFO(sendmsg, SendRef)}; + ?SELECT(sendmsg, SendRef); {error, eagain} -> @@ -1795,7 +1801,7 @@ recv(Socket, Length) -> Data :: binary(), Reason :: term() ; (Socket, Length, Timeout :: nowait) -> {ok, Data} | - {ok, SelectInfo} | + {select, SelectInfo} | {ok, {Data, SelectInfo}} | {error, Reason} when Socket :: socket(), @@ -1817,7 +1823,7 @@ recv(Socket, Length, Timeout) -> recv(Socket, Length, ?SOCKET_RECV_FLAGS_DEFAULT, Timeout). -spec recv(Socket, Length, Flags, nowait) -> {ok, Data} | - {ok, SelectInfo} | + {select, SelectInfo} | {ok, {Data, SelectInfo}} | {error, Reason} when Socket :: socket(), @@ -1926,14 +1932,10 @@ do_recv(SockRef, _OldRef, Length, EFlags, Acc, Timeout) %% The user will be informed that there is something to read %% via the select socket message (see below). + {error, eagain} when (Timeout =:= nowait) andalso (size(Acc) =:= 0) -> + ?SELECT(recv, RecvRef); {error, eagain} when (Timeout =:= nowait) -> - SelectInfo = ?SELECT_INFO(recv, RecvRef), - if - (size(Acc) =:= 0) -> - {ok, SelectInfo}; - true -> - {ok, {Acc, SelectInfo}} - end; + {ok, {Acc, ?SELECT_INFO(recv, RecvRef)}}; %% We return with the accumulated binary (if its non-empty) @@ -2028,7 +2030,7 @@ recvfrom(Socket, BufSz) -> -spec recvfrom(Socket, Flags, nowait) -> {ok, {Source, Data}} | - {ok, SelectInfo} | + {select, SelectInfo} | {error, Reason} when Socket :: socket(), Flags :: recv_flags(), @@ -2055,7 +2057,7 @@ recvfrom(Socket, BufSz) -> Reason :: term() ; (Socket, BufSz, nowait) -> {ok, {Source, Data}} | - {ok, SelectInfo} | + {select, SelectInfo} | {error, Reason} when Socket :: socket(), BufSz :: non_neg_integer(), @@ -2081,7 +2083,7 @@ recvfrom(Socket, BufSz, Timeout) -> -spec recvfrom(Socket, BufSz, Flags, nowait) -> {ok, {Source, Data}} | - {ok, SelectInfo} | + {select, SelectInfo} | {error, Reason} when Socket :: socket(), BufSz :: non_neg_integer(), @@ -2119,7 +2121,7 @@ do_recvfrom(SockRef, BufSz, EFlags, Timeout) -> {error, eagain} when (Timeout =:= nowait) -> - {ok, ?SELECT_INFO(recvfrom, RecvRef)}; + ?SELECT(recvfrom, RecvRef); {error, eagain} -> @@ -2163,8 +2165,8 @@ recvmsg(Socket) -> MsgHdr :: msghdr(), Reason :: term() ; (Socket, Timeout :: nowait) -> {ok, MsgHdr} | - {ok, SelectInfo} | - {error, Reason} when + {select, SelectInfo} | + {error, Reason} when Socket :: socket(), MsgHdr :: msghdr(), SelectInfo :: select_info(), @@ -2181,7 +2183,7 @@ recvmsg(Socket, Timeout) -> recvmsg(Socket, 0, 0, ?SOCKET_RECV_FLAGS_DEFAULT, Timeout). -spec recvmsg(Socket, Flags, nowait) -> {ok, MsgHdr} | - {ok, SelectInfo} | + {select, SelectInfo} | {error, Reason} when Socket :: socket(), Flags :: recv_flags(), @@ -2211,7 +2213,7 @@ recvmsg(Socket, BufSz, CtrlSz) when is_integer(BufSz) andalso is_integer(CtrlSz) -spec recvmsg(Socket, BufSz, CtrlSz, Flags, nowait) -> {ok, MsgHdr} | - {ok, SelectInfo} | + {select, SelectInfo} | {error, Reason} when Socket :: socket(), BufSz :: non_neg_integer(), @@ -2250,7 +2252,7 @@ do_recvmsg(SockRef, BufSz, CtrlSz, EFlags, Timeout) -> {error, eagain} when (Timeout =:= nowait) -> - {ok, ?SELECT_INFO(recvmsg, RecvRef)}; + ?SELECT(recvmsg, RecvRef); {error, eagain} -> @@ -2603,7 +2605,7 @@ peername(#socket{ref = SockRef}) -> SelectInfo :: select_info(), Reason :: term(). -cancel(#socket{ref = SockRef}, {select, Tag, Ref}) -> +cancel(#socket{ref = SockRef}, #select_info{tag = Tag, ref = Ref}) -> cancel(SockRef, Tag, Ref). |