From 9dcdb6714391c4f496e91f95cb293bf7bdf97f2c Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 8 Mar 2019 15:37:15 +0100 Subject: [socket] Messages from the nif code now has a proper socket The messages sent from the nif code to an erlang process has been changed to: {'$socket', Socket :: socket(), Tag :: atom(), Info :: term()} This is in preparation for (using) the new enif select API. OTP-15496 --- erts/emulator/nifs/common/socket_nif.c | 84 +++++++++++++++------------------ erts/preloaded/ebin/socket.beam | Bin 70312 -> 70284 bytes erts/preloaded/src/socket.erl | 30 +++++++----- 3 files changed, 56 insertions(+), 58 deletions(-) (limited to 'erts') diff --git a/erts/emulator/nifs/common/socket_nif.c b/erts/emulator/nifs/common/socket_nif.c index b06b93236d..666e39b07c 100644 --- a/erts/emulator/nifs/common/socket_nif.c +++ b/erts/emulator/nifs/common/socket_nif.c @@ -2428,6 +2428,9 @@ static char* esock_send_msg(ErlNifEnv* env, ErlNifPid* pid, ErlNifEnv* msg_env); +static ERL_NIF_TERM make_socket_record(ErlNifEnv* env, + ERL_NIF_TERM sockRef); + static int esock_select_read(ErlNifEnv* env, ErlNifEvent event, void* obj, @@ -16851,45 +16854,10 @@ size_t my_strnlen(const char *s, size_t maxlen) #endif -/* Send an error closed message to the specified process: - * - * This message is for processes that are waiting in the - * erlang API functions for a select message. - */ -/* -static -char* send_msg_error_closed(ErlNifEnv* env, - ErlNifPid* pid) -{ - return send_msg_error(env, atom_closed, pid); -} -*/ - -/* Send an error message to the specified process: - * A message in the form: - * - * {error, Reason} - * - * This message is for processes that are waiting in the - * erlang API functions for a select message. - */ -/* -static -char* send_msg_error(ErlNifEnv* env, - ERL_NIF_TERM reason, - ErlNifPid* pid) -{ - ERL_NIF_TERM msg = enif_make_tuple2(env, atom_error, reason); - - return send_msg(env, msg, pid); -} -*/ - - /* Send an close message to the specified process: * A message in the form: * - * {'$socket', SockRef, close, CloseRef} + * {'$socket', Socket, close, CloseRef} * * This message is for processes that is waiting in the * erlang API (close-) function for the socket to be "closed" @@ -16919,7 +16887,7 @@ char* esock_send_close_msg(ErlNifEnv* env, /* Send an abort message to the specified process: * A message in the form: * - * {'$socket', SockRef, abort, {RecvRef, Reason}} + * {'$socket', Socket, abort, {RecvRef, Reason}} * * This message is for processes that is waiting in the * erlang API functions for a select message. @@ -16946,10 +16914,11 @@ char* esock_send_abort_msg(ErlNifEnv* env, * This function sends a general purpose socket message to an erlang * process. A general 'socket' message has the ("erlang") form: * - * {'$socket', SockRef, Tag, Info} + * {'$socket', Socket, Tag, Info} * * Where * + * Socket: #socket{ref = SockRef} ({socket, SockRef}) * SockRef: reference() * Tag: atom() * Info: term() @@ -16962,18 +16931,26 @@ char* esock_send_socket_msg(ErlNifEnv* env, ERL_NIF_TERM tag, ERL_NIF_TERM info, ErlNifPid* pid, - ErlNifEnv* msg_env) + ErlNifEnv* msgEnv) { + ErlNifEnv* menv; + ERL_NIF_TERM msock, mtag, minfo; ERL_NIF_TERM msg; - if (!msg_env) { - msg_env = enif_alloc_env(); - sockRef = enif_make_copy(msg_env, sockRef); - tag = enif_make_copy(msg_env, tag); - info = enif_make_copy(msg_env, info); + + if (msgEnv == NULL) { + menv = enif_alloc_env(); + msock = make_socket_record(menv, enif_make_copy(menv, sockRef)); + mtag = enif_make_copy(menv, tag); + minfo = enif_make_copy(menv, info); + } else { + menv = msgEnv; + msock = make_socket_record(menv, sockRef); + mtag = tag; + minfo = info; } - msg = MKT4(msg_env, esock_atom_socket_tag, sockRef, tag, info); + msg = MKT4(menv, esock_atom_socket_tag, socket, mtag, minfo); - return esock_send_msg(env, msg, pid, msg_env); + return esock_send_msg(env, msg, pid, menv); } @@ -16997,6 +16974,21 @@ char* esock_send_msg(ErlNifEnv* env, #endif // #if defined(__WIN32__) +/* *** make_socket_record *** + * + * Simple utility function that construct the socket resord: + * + * #socket{ref = SockRef} => {socket, SockRef :: reference()} + */ +static +ERL_NIF_TERM make_socket_record(ErlNifEnv* env, + ERL_NIF_TERM sockRef) +{ + return MKT2(env, esock_atom_socket, sockRef); +} + + + /* ---------------------------------------------------------------------- * S e l e c t W r a p p e r F u n c t i o n s * ---------------------------------------------------------------------- diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam index e44dff8475..23b3269990 100644 Binary files a/erts/preloaded/ebin/socket.beam and b/erts/preloaded/ebin/socket.beam differ diff --git a/erts/preloaded/src/socket.erl b/erts/preloaded/src/socket.erl index 5c1647290d..5687b067f3 100644 --- a/erts/preloaded/src/socket.erl +++ b/erts/preloaded/src/socket.erl @@ -586,6 +586,12 @@ #{level := integer(), type := integer(), data := binary()}. +%% This is used in messages sent from the nif-code to erlang processes: +%% +%% {?SOCKET_TAG, Socket, Tag, Info} +%% +-define(SOCKET_TAG, '$socket'). + -define(SOCKET_DOMAIN_LOCAL, 1). -define(SOCKET_DOMAIN_UNIX, ?SOCKET_DOMAIN_LOCAL). -define(SOCKET_DOMAIN_INET, 2). @@ -1347,7 +1353,7 @@ do_accept(LSockRef, Timeout) -> {select, LSockRef, AccRef, ready_input} -> do_accept(LSockRef, next_timeout(TS, Timeout)); - {'$socket', _, abort, {AccRef, Reason}} -> + {?SOCKET_TAG, _, abort, {AccRef, Reason}} -> {error, Reason} after NewTimeout -> @@ -1424,7 +1430,7 @@ do_send(SockRef, Data, EFlags, Timeout) -> do_send(SockRef, Data, EFlags, next_timeout(TS, Timeout)); - {'$socket', _, abort, {SendRef, Reason}} -> + {?SOCKET_TAG, _, abort, {SendRef, Reason}} -> {error, Reason} after NewTimeout -> @@ -1437,7 +1443,7 @@ do_send(SockRef, Data, EFlags, Timeout) -> do_send(SockRef, Data, EFlags, next_timeout(TS, Timeout)); - {'$socket', _, abort, {SendRef, Reason}} -> + {?SOCKET_TAG, _, abort, {SendRef, Reason}} -> {error, Reason} after Timeout -> @@ -1529,7 +1535,7 @@ do_sendto(SockRef, Data, Dest, EFlags, Timeout) -> do_sendto(SockRef, Data, Dest, EFlags, next_timeout(TS, Timeout)); - {'$socket', _, abort, {SendRef, Reason}} -> + {?SOCKET_TAG, _, abort, {SendRef, Reason}} -> {error, Reason} after Timeout -> @@ -1543,7 +1549,7 @@ do_sendto(SockRef, Data, Dest, EFlags, Timeout) -> do_sendto(SockRef, Data, Dest, EFlags, next_timeout(TS, Timeout)); - {'$socket', _, abort, {SendRef, Reason}} -> + {?SOCKET_TAG, _, abort, {SendRef, Reason}} -> {error, Reason} after Timeout -> @@ -1793,7 +1799,7 @@ do_recv(SockRef, _OldRef, Length, EFlags, Acc, Timeout) Bin, next_timeout(TS, Timeout)); - {'$socket', _, abort, {RecvRef, Reason}} -> + {?SOCKET_TAG, _, abort, {RecvRef, Reason}} -> {error, Reason} after NewTimeout -> @@ -1813,7 +1819,7 @@ do_recv(SockRef, _OldRef, Length, EFlags, Acc, Timeout) <>, next_timeout(TS, Timeout)); - {'$socket', _, abort, {RecvRef, Reason}} -> + {?SOCKET_TAG, _, abort, {RecvRef, Reason}} -> {error, Reason} after NewTimeout -> @@ -1838,7 +1844,7 @@ do_recv(SockRef, _OldRef, Length, EFlags, Acc, Timeout) Acc, next_timeout(TS, Timeout)); - {'$socket', _, abort, {RecvRef, Reason}} -> + {?SOCKET_TAG, _, abort, {RecvRef, Reason}} -> {error, Reason} after NewTimeout -> @@ -1977,7 +1983,7 @@ do_recvfrom(SockRef, BufSz, EFlags, Timeout) -> do_recvfrom(SockRef, BufSz, EFlags, next_timeout(TS, Timeout)); - {'$socket', _, abort, {RecvRef, Reason}} -> + {?SOCKET_TAG, _, abort, {RecvRef, Reason}} -> {error, Reason} after NewTimeout -> @@ -2081,7 +2087,7 @@ do_recvmsg(SockRef, BufSz, CtrlSz, EFlags, Timeout) -> do_recvmsg(SockRef, BufSz, CtrlSz, EFlags, next_timeout(TS, Timeout)); - {'$socket', _, abort, {RecvRef, Reason}} -> + {?SOCKET_TAG, _, abort, {RecvRef, Reason}} -> {error, Reason} after NewTimeout -> @@ -2118,7 +2124,7 @@ do_recvmsg(SockRef, BufSz, CtrlSz, EFlags, Timeout) -> %% 1) nif_close + the socket_stop (nif) callback function %% This is for everything that can be done safely NON-BLOCKING. %% 2) nif_finalize_close which is executed by a *dirty* scheduler -%% Before we call the socket close function, we se the socket +%% Before we call the socket close function, we set the socket %% BLOCKING. Thereby linger is handled properly. @@ -2137,7 +2143,7 @@ do_close(SockRef) -> %% We must wait for the socket_stop callback function to %% complete its work receive - {'$socket', SockRef, close, CloseRef} -> + {?SOCKET_TAG, #socket{ref = SockRef}, close, CloseRef} -> nif_finalize_close(SockRef) end; {error, _} = ERROR -> -- cgit v1.2.3