diff options
author | Wei Cao <cyg.cao@gmail.com> | 2012-08-16 10:53:07 +0800 |
---|---|---|
committer | Robert Newson <rnewson@apache.org> | 2012-08-16 11:52:45 +0100 |
commit | b141e2c173d041d42bcfab2b3a7a471ccbd47f96 (patch) | |
tree | f51f6dd9abc4fed72e7944da735d0387ce5a44ab | |
parent | 445e9190fc25e64d7f9d121cb2d2945743a02843 (diff) | |
download | couchdb-b141e2c173d041d42bcfab2b3a7a471ccbd47f96.tar.gz |
Fix Mochiweb acceptor blocked in ssl handshake
Acceptor cannot be recycled until ssl handshake is done,
so it's possible and easy for all acceptors be blocked between the point
where the new socket's connected and the ssl handshake is done.
-rw-r--r-- | src/mochiweb/mochiweb_acceptor.erl | 7 | ||||
-rw-r--r-- | src/mochiweb/mochiweb_socket.erl | 15 |
2 files changed, 11 insertions, 11 deletions
diff --git a/src/mochiweb/mochiweb_acceptor.erl b/src/mochiweb/mochiweb_acceptor.erl index 20a9b4b94..893f99b11 100644 --- a/src/mochiweb/mochiweb_acceptor.erl +++ b/src/mochiweb/mochiweb_acceptor.erl @@ -18,13 +18,14 @@ init(Server, Listen, Loop) -> case catch mochiweb_socket:accept(Listen) of {ok, Socket} -> gen_server:cast(Server, {accepted, self(), timer:now_diff(now(), T1)}), - call_loop(Loop, Socket); + case mochiweb_socket:after_accept(Socket) of + ok -> call_loop(Loop, Socket); + {error, _} -> exit(normal) + end; {error, closed} -> exit(normal); {error, timeout} -> init(Server, Listen, Loop); - {error, esslaccept} -> - exit(normal); Other -> error_logger:error_report( [{application, mochiweb}, diff --git a/src/mochiweb/mochiweb_socket.erl b/src/mochiweb/mochiweb_socket.erl index 76b018c82..ad272048c 100644 --- a/src/mochiweb/mochiweb_socket.erl +++ b/src/mochiweb/mochiweb_socket.erl @@ -4,10 +4,11 @@ -module(mochiweb_socket). --export([listen/4, accept/1, recv/3, send/2, close/1, port/1, peername/1, +-export([listen/4, accept/1, after_accept/1, recv/3, send/2, close/1, port/1, peername/1, setopts/2, type/1]). -define(ACCEPT_TIMEOUT, 2000). +-define(SSL_ACCEPT_TIMEOUT, 30000). listen(Ssl, Port, Opts, SslOpts) -> case Ssl of @@ -25,14 +26,9 @@ listen(Ssl, Port, Opts, SslOpts) -> accept({ssl, ListenSocket}) -> % There's a bug in ssl:transport_accept/2 at the moment, which is the % reason for the try...catch block. Should be fixed in OTP R14. - try ssl:transport_accept(ListenSocket) of + try ssl:transport_accept(ListenSocket, ?ACCEPT_TIMEOUT) of {ok, Socket} -> - case ssl:ssl_accept(Socket) of - ok -> - {ok, {ssl, Socket}}; - {error, _} = Err -> - Err - end; + {ok, {ssl, Socket}}; {error, _} = Err -> Err catch @@ -42,6 +38,9 @@ accept({ssl, ListenSocket}) -> accept(ListenSocket) -> gen_tcp:accept(ListenSocket, ?ACCEPT_TIMEOUT). +after_accept({ssl, Socket}) -> ssl:ssl_accept(Socket, ?SSL_ACCEPT_TIMEOUT); +after_accept(_Socket) -> ok. + recv({ssl, Socket}, Length, Timeout) -> ssl:recv(Socket, Length, Timeout); recv(Socket, Length, Timeout) -> |