aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2019-04-15 11:35:05 +0200
committerMicael Karlberg <[email protected]>2019-05-29 14:09:04 +0200
commitb030b056c66d2afc8dfd0c03187f0ffafc0612e6 (patch)
treeb8769d42ded277c7277417aa5c372f961da6aa23
parent3419aee8487840941124dbcfc24ddde12df49c63 (diff)
downloadotp-b030b056c66d2afc8dfd0c03187f0ffafc0612e6.tar.gz
otp-b030b056c66d2afc8dfd0c03187f0ffafc0612e6.tar.bz2
otp-b030b056c66d2afc8dfd0c03187f0ffafc0612e6.zip
[socket] Update send to handle Timeout = nowait
Update function send and its spec(s) to handle the Timeout value of nowait.
-rw-r--r--erts/preloaded/ebin/socket.beambin72648 -> 73296 bytes
-rw-r--r--erts/preloaded/src/socket.erl76
2 files changed, 64 insertions, 12 deletions
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 326fe49a69..b7bf0b7377 100644
--- a/erts/preloaded/ebin/socket.beam
+++ b/erts/preloaded/ebin/socket.beam
Binary files differ
diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl
index 5b460ae81b..fb08314d59 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -1278,7 +1278,8 @@ accept(Socket) ->
accept(_, Timeout) when is_integer(Timeout) andalso (Timeout =< 0) ->
{error, timeout};
accept(#socket{ref = LSockRef}, Timeout)
- when is_integer(Timeout) orelse (Timeout =:= infinity) ->
+ when is_integer(Timeout) orelse
+ (Timeout =:= infinity) ->
do_accept(LSockRef, Timeout).
do_accept(LSockRef, Timeout) ->
@@ -1331,29 +1332,65 @@ send(Socket, Data) ->
Data :: iodata(),
Flags :: send_flags(),
Reason :: term()
+ ; (Socket, Data, nowait) -> ok |
+ {ok, SelInfo} |
+ {ok, {RestData, SelInfo}} |
+ {error, Reason} when
+ Socket :: socket(),
+ Data :: iodata(),
+ RestData :: binary(),
+ SelInfo :: {select, SendRef},
+ SendRef :: reference(),
+ Reason :: term()
; (Socket, Data, Timeout) -> ok | {error, Reason} when
- Socket :: socket(),
- Data :: iodata(),
- Timeout :: timeout(),
- Reason :: term().
+ Socket :: socket(),
+ Data :: iodata(),
+ Timeout :: timeout(),
+ Reason :: term().
send(Socket, Data, Flags) when is_list(Flags) ->
send(Socket, Data, Flags, ?SOCKET_SEND_TIMEOUT_DEFAULT);
send(Socket, Data, Timeout) ->
send(Socket, Data, ?SOCKET_SEND_FLAGS_DEFAULT, Timeout).
--spec send(Socket, Data, Flags, Timeout) -> ok | {error, Reason} when
- Socket :: socket(),
- Data :: iodata(),
- Flags :: send_flags(),
- Timeout :: timeout(),
- Reason :: term().
+-spec send(Socket, Data, Flags, nowait) -> ok |
+ {ok, SelInfo} |
+ {ok, {RestData, SelInfo}} |
+ {error, Reason} when
+ Socket :: socket(),
+ Data :: iodata(),
+ Flags :: send_flags(),
+ RestData :: binary(),
+ SelInfo :: {select, SendRef},
+ SendRef :: reference(),
+ Reason :: term()
+ ; (Socket, Data, Flags, nowait) -> ok |
+ {ok, SelInfo} |
+ {ok, {RestData, SelInfo}} |
+ {error, Reason} when
+ Socket :: socket(),
+ Data :: iodata(),
+ Flags :: send_flags(),
+ RestData :: binary(),
+ SelInfo :: {select, SendRef},
+ SendRef :: reference(),
+ Reason :: term()
+ ; (Socket, Data, Flags, Timeout) -> ok | {error, Reason} when
+ Socket :: socket(),
+ Data :: iodata(),
+ Flags :: send_flags(),
+ Timeout :: timeout(),
+ Reason :: term().
send(Socket, Data, Flags, Timeout) when is_list(Data) ->
Bin = erlang:list_to_binary(Data),
send(Socket, Bin, Flags, Timeout);
send(#socket{ref = SockRef}, Data, Flags, Timeout)
- when is_binary(Data) andalso is_list(Flags) ->
+ when is_binary(Data) andalso
+ is_list(Flags) andalso
+ ((Timeout =:= nowait) orelse
+ (Timeout =:= infinity) orelse
+ (is_integer(Timeout) andalso (Timeout > 0))) ->
EFlags = enc_send_flags(Flags),
do_send(SockRef, Data, EFlags, Timeout).
@@ -1363,6 +1400,14 @@ do_send(SockRef, Data, EFlags, Timeout) ->
case nif_send(SockRef, SendRef, Data, EFlags) of
ok ->
ok;
+
+
+ {ok, Written} when (Timeout =:= nowait) ->
+ <<_:Written/binary, Rest/binary>> = Data,
+ SelInfo = {select, SendRef},
+ {ok, {Rest, SelInfo}};
+
+
{ok, Written} ->
NewTimeout = next_timeout(TS, Timeout),
%% We are partially done, wait for continuation
@@ -1384,6 +1429,13 @@ do_send(SockRef, Data, EFlags, Timeout) ->
cancel(SockRef, send, SendRef),
{error, {timeout, size(Data)}}
end;
+
+
+ {error, eagain} ->
+ SelInfo = {select, SendRef},
+ {ok, SelInfo};
+
+
{error, eagain} ->
receive
{?SOCKET_TAG, #socket{ref = SockRef}, select, SendRef} ->