diff options
author | Micael Karlberg <bmk@erlang.org> | 2023-04-12 10:06:35 +0200 |
---|---|---|
committer | Micael Karlberg <bmk@erlang.org> | 2023-04-14 11:09:09 +0200 |
commit | 5a3fc96153503fecf4ec47d3658932e60382eb0b (patch) | |
tree | 6f32f041ab2875e8d133ce1aa307a365c55bccb9 | |
parent | 68609e0fe065b15d1bf1cd0a267294b1dddbf22b (diff) | |
download | erlang-5a3fc96153503fecf4ec47d3658932e60382eb0b.tar.gz |
[kernel] Socket cancel operation race
A race when cancel an operation, which has just been 'selected'
(in gen_tcp_socket) could cause a crash.
Update the spec of the function socket:cancel/2 to include
error Reason select_sent.
OTP-18029
-rw-r--r-- | lib/kernel/src/gen_tcp_socket.erl | 6 | ||||
-rw-r--r-- | lib/kernel/src/socket.erl | 4 |
2 files changed, 7 insertions, 3 deletions
diff --git a/lib/kernel/src/gen_tcp_socket.erl b/lib/kernel/src/gen_tcp_socket.erl index 84ea036c3f..d092faf213 100644 --- a/lib/kernel/src/gen_tcp_socket.erl +++ b/lib/kernel/src/gen_tcp_socket.erl @@ -730,7 +730,11 @@ socket_close(Socket) -> socket_cancel(Socket, SelectInfo) -> case socket:cancel(Socket, SelectInfo) of ok -> ok; - {error, closed} -> ok + {error, closed} -> ok; + + %% Race - shall we await the message or just ignore? + {error, select_sent} -> ok + end. %%% ======================================================================== diff --git a/lib/kernel/src/socket.erl b/lib/kernel/src/socket.erl index 25be82543f..4781167c26 100644 --- a/lib/kernel/src/socket.erl +++ b/lib/kernel/src/socket.erl @@ -4547,11 +4547,11 @@ ioctl(Socket, SetRequest, Arg1, Arg2) -> -spec cancel(Socket, SelectInfo) -> 'ok' | {'error', Reason} when Socket :: socket(), SelectInfo :: select_info(), - Reason :: 'closed' | invalid(); + Reason :: 'closed' | 'select_sent' | invalid(); (Socket, CompletionInfo) -> 'ok' | {'error', Reason} when Socket :: socket(), CompletionInfo :: completion_info(), - Reason :: 'closed' | invalid(). + Reason :: 'closed' | 'select_sent' | invalid(). cancel(?socket(SockRef), ?SELECT_INFO(SelectTag, SelectHandle) = SelectInfo) when is_reference(SockRef) -> |