diff options
author | Hans Nilsson <[email protected]> | 2018-03-06 11:42:28 +0100 |
---|---|---|
committer | Hans Nilsson <[email protected]> | 2018-03-07 14:18:57 +0100 |
commit | 7a86736c1e2bc0468acd18b1f84c7cbf055befc8 (patch) | |
tree | 5e4ea6b379d26dd70a84a413407c358244f5338d /lib/ssh | |
parent | 249549e8102d68ab086c418fa93494906c4445d0 (diff) | |
download | otp-7a86736c1e2bc0468acd18b1f84c7cbf055befc8.tar.gz otp-7a86736c1e2bc0468acd18b1f84c7cbf055befc8.tar.bz2 otp-7a86736c1e2bc0468acd18b1f84c7cbf055befc8.zip |
ssh: Retry and exponentially backoff listener restart
in case of eaddrinuse. This could happen if the acceptor process dies and is restarted immediatly.
Diffstat (limited to 'lib/ssh')
-rw-r--r-- | lib/ssh/src/ssh_acceptor.erl | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl index d66a34c58a..27d4242dd4 100644 --- a/lib/ssh/src/ssh_acceptor.erl +++ b/lib/ssh/src/ssh_acceptor.erl @@ -86,7 +86,8 @@ acceptor_init(Parent, Port, Address, Opts, AcceptTimeout) -> acceptor_loop(Callback, Port, Address, Opts, LSock, AcceptTimeout); {error,_} -> % Not open, a restart - {ok,NewLSock} = listen(Port, Opts), + %% Allow gen_tcp:listen to fail 4 times if eaddrinuse: + {ok,NewLSock} = try_listen(Port, Opts, 4), proc_lib:init_ack(Parent, {ok, self()}), Opts1 = ?DELETE_INTERNAL_OPT(lsocket, Opts), {_, Callback, _} = ?GET_OPT(transport, Opts1), @@ -98,6 +99,19 @@ acceptor_init(Parent, Port, Address, Opts, AcceptTimeout) -> end. +try_listen(Port, Opts, NtriesLeft) -> + try_listen(Port, Opts, 1, NtriesLeft). + +try_listen(Port, Opts, N, Nmax) -> + case listen(Port, Opts) of + {error,eaddrinuse} when N<Nmax -> + timer:sleep(10*N), % Sleep 10, 20, 30,... ms + try_listen(Port, Opts, N+1, Nmax); + Other -> + Other + end. + + request_ownership(LSock, SockOwner) -> SockOwner ! {request_control,LSock,self()}, receive |