aboutsummaryrefslogtreecommitdiffstats
path: root/erts/preloaded
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2019-02-21 14:57:59 +0100
committerMicael Karlberg <[email protected]>2019-02-22 19:45:54 +0100
commit4ff181e69fc129576333c04a9d1d0c97b6770347 (patch)
treefe6b0e6ca67e64948d317c58734d0562563b4b2a /erts/preloaded
parentb71c341212fa1ff07eac914e07bc57303c2c4385 (diff)
downloadotp-4ff181e69fc129576333c04a9d1d0c97b6770347.tar.gz
otp-4ff181e69fc129576333c04a9d1d0c97b6770347.tar.bz2
otp-4ff181e69fc129576333c04a9d1d0c97b6770347.zip
[socket] More fixes to socket close
Better handling of socket close. The 'closeRef' needed its own environment to make if work in both cases (both called and scheduled). Also Introduced the enif select wrapper functions (read, write, stop and cancel). Also add error handling at every time one of these functions are called. OTP-14831
Diffstat (limited to 'erts/preloaded')
-rw-r--r--erts/preloaded/ebin/socket.beambin70288 -> 70312 bytes
-rw-r--r--erts/preloaded/src/socket.erl22
2 files changed, 13 insertions, 9 deletions
diff --git a/erts/preloaded/ebin/socket.beam b/erts/preloaded/ebin/socket.beam
index 93b5fc215b..e44dff8475 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 12b6c3ac55..5c1647290d 100644
--- a/erts/preloaded/src/socket.erl
+++ b/erts/preloaded/src/socket.erl
@@ -2111,6 +2111,16 @@ do_recvmsg(SockRef, BufSz, CtrlSz, EFlags, Timeout) ->
%%
%% close - close a file descriptor
%%
+%% Closing a socket is a two stage rocket (because of linger).
+%% We need to perform the actual socket close while in BLOCKING mode.
+%% But that would hang the entire VM, so what we do is divide the
+%% close in two steps:
+%% 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
+%% BLOCKING. Thereby linger is handled properly.
+
-spec close(Socket) -> ok | {error, Reason} when
Socket :: socket(),
@@ -2124,16 +2134,10 @@ do_close(SockRef) ->
ok ->
nif_finalize_close(SockRef);
{ok, CloseRef} ->
- %% We must wait
+ %% We must wait for the socket_stop callback function to
+ %% complete its work
receive
- {'$socket', _, close, CloseRef} ->
-%% {close, CloseRef} ->
- %% <KOLLA>
- %%
- %% WHAT HAPPENS IF THIS PROCESS IS KILLED
- %% BEFORE WE CAN EXECUTE THE FINAL CLOSE???
- %%
- %% </KOLLA>
+ {'$socket', SockRef, close, CloseRef} ->
nif_finalize_close(SockRef)
end;
{error, _} = ERROR ->