aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/doc/src/socket_usage.xml16
-rw-r--r--erts/emulator/nifs/common/socket_nif.c86
-rw-r--r--erts/preloaded/ebin/socket.beambin56284 -> 56372 bytes
-rw-r--r--erts/preloaded/src/socket.erl16
-rw-r--r--lib/kernel/test/socket_server.erl8
5 files changed, 117 insertions, 9 deletions
diff --git a/erts/doc/src/socket_usage.xml b/erts/doc/src/socket_usage.xml
index 221561c3e2..9ea585694d 100644
--- a/erts/doc/src/socket_usage.xml
+++ b/erts/doc/src/socket_usage.xml
@@ -180,6 +180,13 @@
<cell>none</cell>
</row>
<row>
+ <cell>rcvlowat</cell>
+ <cell>non_neg_integer()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>none</cell>
+ </row>
+ <row>
<cell>rcvtimeo</cell>
<cell>timeval()</cell>
<cell>yes</cell>
@@ -202,12 +209,19 @@
</row>
<row>
<cell>sndbuf</cell>
- <cell>integer()</cell>
+ <cell>non_neg_integer()</cell>
<cell>yes</cell>
<cell>yes</cell>
<cell>none</cell>
</row>
<row>
+ <cell>sndlowat</cell>
+ <cell>non_neg_integer()</cell>
+ <cell>yes</cell>
+ <cell>yes</cell>
+ <cell>not changeable on Linux</cell>
+ </row>
+ <row>
<cell>sndtimeo</cell>
<cell>timeval()</cell>
<cell>yes</cell>
diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c
index 53122ab957..365cbd541b 100644
--- a/erts/emulator/nifs/common/socket_nif.c
+++ b/erts/emulator/nifs/common/socket_nif.c
@@ -502,10 +502,12 @@ typedef union {
#define SOCKET_OPT_SOCK_PRIORITY 17
#define SOCKET_OPT_SOCK_PROTOCOL 18
#define SOCKET_OPT_SOCK_RCVBUF 19
+#define SOCKET_OPT_SOCK_RCVLOWAT 21
#define SOCKET_OPT_SOCK_RCVTIMEO 22
#define SOCKET_OPT_SOCK_REUSEADDR 23
#define SOCKET_OPT_SOCK_REUSEPORT 24
#define SOCKET_OPT_SOCK_SNDBUF 27
+#define SOCKET_OPT_SOCK_SNDLOWAT 29
#define SOCKET_OPT_SOCK_SNDTIMEO 30
#define SOCKET_OPT_SOCK_TYPE 32
@@ -1012,6 +1014,11 @@ static ERL_NIF_TERM nsetopt_lvl_sock_rcvbuf(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(SO_RCVLOWAT)
+static ERL_NIF_TERM nsetopt_lvl_sock_rcvlowat(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(SO_RCVTIMEO)
static ERL_NIF_TERM nsetopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1032,6 +1039,11 @@ static ERL_NIF_TERM nsetopt_lvl_sock_sndbuf(ErlNifEnv* env,
SocketDescriptor* descP,
ERL_NIF_TERM eVal);
#endif
+#if defined(SO_SNDLOWAT)
+static ERL_NIF_TERM nsetopt_lvl_sock_sndlowat(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal);
+#endif
#if defined(SO_SNDTIMEO)
static ERL_NIF_TERM nsetopt_lvl_sock_sndtimeo(ErlNifEnv* env,
SocketDescriptor* descP,
@@ -1351,6 +1363,10 @@ static ERL_NIF_TERM ngetopt_lvl_sock_protocol(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_sock_rcvbuf(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(SO_RCVLOWAT)
+static ERL_NIF_TERM ngetopt_lvl_sock_rcvlowat(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(SO_RCVTIMEO)
static ERL_NIF_TERM ngetopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -1367,6 +1383,10 @@ static ERL_NIF_TERM ngetopt_lvl_sock_reuseport(ErlNifEnv* env,
static ERL_NIF_TERM ngetopt_lvl_sock_sndbuf(ErlNifEnv* env,
SocketDescriptor* descP);
#endif
+#if defined(SO_SNDLOWAT)
+static ERL_NIF_TERM ngetopt_lvl_sock_sndlowat(ErlNifEnv* env,
+ SocketDescriptor* descP);
+#endif
#if defined(SO_SNDTIMEO)
static ERL_NIF_TERM ngetopt_lvl_sock_sndtimeo(ErlNifEnv* env,
SocketDescriptor* descP);
@@ -4379,6 +4399,12 @@ ERL_NIF_TERM nsetopt_lvl_socket(ErlNifEnv* env,
break;
#endif
+#if defined(SO_RCVLOWAT)
+ case SOCKET_OPT_SOCK_RCVLOWAT:
+ result = nsetopt_lvl_sock_rcvlowat(env, descP, eVal);
+ break;
+#endif
+
#if defined(SO_RCVTIMEO)
case SOCKET_OPT_SOCK_RCVTIMEO:
result = nsetopt_lvl_sock_rcvtimeo(env, descP, eVal);
@@ -4403,6 +4429,12 @@ ERL_NIF_TERM nsetopt_lvl_socket(ErlNifEnv* env,
break;
#endif
+#if defined(SO_SNDLOWAT)
+ case SOCKET_OPT_SOCK_SNDLOWAT:
+ result = nsetopt_lvl_sock_sndlowat(env, descP, eVal);
+ break;
+#endif
+
#if defined(SO_SNDTIMEO)
case SOCKET_OPT_SOCK_SNDTIMEO:
result = nsetopt_lvl_sock_sndtimeo(env, descP, eVal);
@@ -4550,6 +4582,17 @@ ERL_NIF_TERM nsetopt_lvl_sock_rcvbuf(ErlNifEnv* env,
#endif
+#if defined(SO_RCVLOWAT)
+static
+ERL_NIF_TERM nsetopt_lvl_sock_rcvlowat(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+ return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_RCVLOWAT, eVal);
+}
+#endif
+
+
#if defined(SO_RCVTIMEO)
static
ERL_NIF_TERM nsetopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
@@ -4594,6 +4637,17 @@ ERL_NIF_TERM nsetopt_lvl_sock_sndbuf(ErlNifEnv* env,
#endif
+#if defined(SO_SNDLOWAT)
+static
+ERL_NIF_TERM nsetopt_lvl_sock_sndlowat(ErlNifEnv* env,
+ SocketDescriptor* descP,
+ ERL_NIF_TERM eVal)
+{
+ return nsetopt_int_opt(env, descP, SOL_SOCKET, SO_SNDLOWAT, eVal);
+}
+#endif
+
+
#if defined(SO_SNDTIMEO)
static
ERL_NIF_TERM nsetopt_lvl_sock_sndtimeo(ErlNifEnv* env,
@@ -6863,6 +6917,12 @@ ERL_NIF_TERM ngetopt_lvl_socket(ErlNifEnv* env,
break;
#endif
+#if defined(SO_RCVLOWAT)
+ case SOCKET_OPT_SOCK_RCVLOWAT:
+ result = ngetopt_lvl_sock_rcvlowat(env, descP);
+ break;
+#endif
+
#if defined(SO_RCVTIMEO)
case SOCKET_OPT_SOCK_RCVTIMEO:
result = ngetopt_lvl_sock_rcvtimeo(env, descP);
@@ -6887,6 +6947,12 @@ ERL_NIF_TERM ngetopt_lvl_socket(ErlNifEnv* env,
break;
#endif
+#if defined(SO_SNDLOWAT)
+ case SOCKET_OPT_SOCK_SNDLOWAT:
+ result = ngetopt_lvl_sock_sndlowat(env, descP);
+ break;
+#endif
+
#if defined(SO_SNDTIMEO)
case SOCKET_OPT_SOCK_SNDTIMEO:
result = ngetopt_lvl_sock_sndtimeo(env, descP);
@@ -7140,6 +7206,16 @@ ERL_NIF_TERM ngetopt_lvl_sock_rcvbuf(ErlNifEnv* env,
#endif
+#if defined(SO_RCVLOWAT)
+static
+ERL_NIF_TERM ngetopt_lvl_sock_rcvlowat(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+ return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_RCVLOWAT);
+}
+#endif
+
+
#if defined(SO_RCVTIMEO)
static
ERL_NIF_TERM ngetopt_lvl_sock_rcvtimeo(ErlNifEnv* env,
@@ -7180,6 +7256,16 @@ ERL_NIF_TERM ngetopt_lvl_sock_sndbuf(ErlNifEnv* env,
#endif
+#if defined(SO_SNDLOWAT)
+static
+ERL_NIF_TERM ngetopt_lvl_sock_sndlowat(ErlNifEnv* env,
+ SocketDescriptor* descP)
+{
+ return ngetopt_int_opt(env, descP, SOL_SOCKET, SO_SNDLOWAT);
+}
+#endif
+
+
#if defined(SO_SNDTIMEO)
static
ERL_NIF_TERM ngetopt_lvl_sock_sndtimeo(ErlNifEnv* env,
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index cd4feb8a46..b8d0e86a20 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 15f9693490..3ccba06f6b 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -575,7 +575,7 @@
-define(SOCKET_OPT_SOCK_PROTOCOL, 18).
-define(SOCKET_OPT_SOCK_RCVBUF, 19).
%% -define(SOCKET_OPT_SOCK_RCVBUFFORCE, 20).
-%% -define(SOCKET_OPT_SOCK_RCVLOWAT, 21).
+-define(SOCKET_OPT_SOCK_RCVLOWAT, 21).
-define(SOCKET_OPT_SOCK_RCVTIMEO, 22).
-define(SOCKET_OPT_SOCK_REUSEADDR, 23).
-define(SOCKET_OPT_SOCK_REUSEPORT, 24).
@@ -583,7 +583,7 @@
%% -define(SOCKET_OPT_SOCK_SETFIB, 26).
-define(SOCKET_OPT_SOCK_SNDBUF, 27).
%% -define(SOCKET_OPT_SOCK_SNDBUFFORCE, 28).
-%% -define(SOCKET_OPT_SOCK_SNDLOWAT, 29).
+-define(SOCKET_OPT_SOCK_SNDLOWAT, 29).
-define(SOCKET_OPT_SOCK_SNDTIMEO, 30).
%% -define(SOCKET_OPT_SOCK_TIMESTAMP, 31).
-define(SOCKET_OPT_SOCK_TYPE, 32).
@@ -2125,6 +2125,8 @@ enc_setopt_value(socket, priority, V, _D, _T, _P) when is_integer(V) ->
V;
enc_setopt_value(socket, rcvbuf, V, _D, _T, _P) when is_integer(V) ->
V;
+enc_setopt_value(socket, rcvlowat, V, _D, _T, _P) when is_integer(V) ->
+ V;
enc_setopt_value(socket, rcvtimeo, #{sec := Sec, usec := USec} = V, _D, _T, _P)
when is_integer(Sec) andalso is_integer(USec) ->
V;
@@ -2134,6 +2136,8 @@ enc_setopt_value(socket, reuseport, V, _D, _T, _P) when is_boolean(V) ->
V;
enc_setopt_value(socket, sndbuf, V, _D, _T, _P) when is_integer(V) ->
V;
+enc_setopt_value(socket, sndlowat, V, _D, _T, _P) when is_integer(V) ->
+ V;
enc_setopt_value(socket, sndtimeo, #{sec := Sec, usec := USec} = V, _D, _T, _P)
when is_integer(Sec) andalso is_integer(USec) ->
V;
@@ -2523,8 +2527,8 @@ enc_sockopt_key(socket, rcvbuf = _Opt, _Dir, _D, _T, _P) ->
enc_sockopt_key(socket = L, rcvbufforce = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
%% May not work on linux.
-enc_sockopt_key(socket = L, rcvlowat = Opt, _Dir, _D, _T, _P) ->
- not_supported({L, Opt});
+enc_sockopt_key(socket = _L, rcvlowat = _Opt, _Dir, _D, _T, _P) ->
+ ?SOCKET_OPT_SOCK_RCVLOWAT;
enc_sockopt_key(socket = _L, rcvtimeo = _Opt, _Dir, _D, _T, _P) ->
?SOCKET_OPT_SOCK_RCVTIMEO;
enc_sockopt_key(socket = _L, reuseaddr = _Opt, _Dir, _D, _T, _P) ->
@@ -2541,8 +2545,8 @@ enc_sockopt_key(socket = _L, sndbuf = _Opt, _Dir, _D, _T, _P) ->
enc_sockopt_key(socket = L, sndbufforce = Opt, _Dir, _D, _T, _P) ->
not_supported({L, Opt});
%% Not changeable on linux.
-enc_sockopt_key(socket = L, sndlowat = Opt, _Dir, _D, _T, _P) ->
- not_supported({L, Opt});
+enc_sockopt_key(socket = _L, sndlowat = _Opt, _Dir, _D, _T, _P) ->
+ ?SOCKET_OPT_SOCK_SNDLOWAT;
enc_sockopt_key(socket = _L, sndtimeo = _Opt, _Dir, _D, _T, _P) ->
?SOCKET_OPT_SOCK_SNDTIMEO;
enc_sockopt_key(socket = L, timestamp = Opt, _Dir, _D, _T, _P) ->
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index 80de3574d1..10239b0265 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -597,8 +597,10 @@ handler_init(Manager, ID, Peek, Sock) ->
RP = GSO(reuseport),
OOBI = GSO(oobinline),
RcvBuf = GSO(rcvbuf),
+ RcvLW = GSO(rcvlowat),
RcvTO = GSO(rcvtimeo),
SndBuf = GSO(sndbuf),
+ SndLW = GSO(sndlowat),
SndTO = GSO(sndtimeo),
Linger = GSO(linger),
MTU = GIP(mtu),
@@ -619,8 +621,10 @@ handler_init(Manager, ID, Peek, Sock) ->
"~n (socket) Bind To Device: ~s"
"~n (socket) OOBInline: ~s"
"~n (socket) RcvBuf: ~s"
+ "~n (socket) RcvLW: ~s"
"~n (socket) RcvTO: ~s"
"~n (socket) SndBuf: ~s"
+ "~n (socket) SndLW: ~s"
"~n (socket) SndTO: ~s"
"~n (socket) Linger: ~s"
"~n (ip) MTU: ~s"
@@ -634,11 +638,11 @@ handler_init(Manager, ID, Peek, Sock) ->
"~n (ip) Recv TTL: ~s",
[Domain, Type, Proto,
RA, RP, B2D, OOBI,
- RcvBuf, RcvTO, SndBuf, SndTO,
+ RcvBuf, RcvLW, RcvTO, SndBuf, SndLW, SndTO,
Linger,
MTU, MTUDisc, MALL, MIF, MLoop, MTTL,
NF, RecvTOS, RecvTTL]),
-
+
handler_loop(#handler{peek = Peek,
manager = Manager,
type = Type,