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.


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/a489480e
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/a489480e
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/a489480e

Branch: refs/heads/1696-update-mochiweb-2-4-2
Commit: a489480e4fa3ffffe04d1fb888029944fb0f0e98
Parents: 49f12c8
Author: Wei Cao <[email protected]>
Authored: Thu Aug 16 10:53:07 2012 +0800
Committer: Dave Cottlehuber <[email protected]>
Committed: Tue Mar 12 20:45:34 2013 +0100

----------------------------------------------------------------------
 src/mochiweb/mochiweb_acceptor.erl |    7 ++++---
 src/mochiweb/mochiweb_socket.erl   |   15 +++++++--------
 2 files changed, 11 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/a489480e/src/mochiweb/mochiweb_acceptor.erl
----------------------------------------------------------------------
diff --git a/src/mochiweb/mochiweb_acceptor.erl 
b/src/mochiweb/mochiweb_acceptor.erl
index efedfbd..c1192e2 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},

http://git-wip-us.apache.org/repos/asf/couchdb/blob/a489480e/src/mochiweb/mochiweb_socket.erl
----------------------------------------------------------------------
diff --git a/src/mochiweb/mochiweb_socket.erl b/src/mochiweb/mochiweb_socket.erl
index 76b018c..ad27204 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) ->

Reply via email to