diff options
author | Micael Karlberg <[email protected]> | 2019-02-21 14:57:59 +0100 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2019-02-22 19:45:54 +0100 |
commit | 4ff181e69fc129576333c04a9d1d0c97b6770347 (patch) | |
tree | fe6b0e6ca67e64948d317c58734d0562563b4b2a /erts/preloaded/src | |
parent | b71c341212fa1ff07eac914e07bc57303c2c4385 (diff) | |
download | otp-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/src')
-rw-r--r-- | erts/preloaded/src/socket.erl | 22 |
1 files changed, 13 insertions, 9 deletions
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 -> |