$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: chris_at_[hidden]
Date: 2007-12-07 07:53:40
Author: chris_kohlhoff
Date: 2007-12-07 07:53:39 EST (Fri, 07 Dec 2007)
New Revision: 41823
URL: http://svn.boost.org/trac/boost/changeset/41823
Log:
Try to fix stall when sending large amounts of data over SSL.
Text files modified: 
   trunk/boost/asio/ssl/detail/openssl_operation.hpp |    38 +++++++++++++++++++++++++++++++-------  
   1 files changed, 31 insertions(+), 7 deletions(-)
Modified: trunk/boost/asio/ssl/detail/openssl_operation.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_operation.hpp	(original)
+++ trunk/boost/asio/ssl/detail/openssl_operation.hpp	2007-12-07 07:53:39 EST (Fri, 07 Dec 2007)
@@ -101,6 +101,10 @@
       &openssl_operation::do_async_write, 
       this, boost::arg<1>(), boost::arg<2>()
     );
+    read_ = boost::bind(
+      &openssl_operation::do_async_read, 
+      this
+    );
     handler_= boost::bind(
       &openssl_operation::async_user_handler, 
       this, boost::arg<1>(), boost::arg<2>()
@@ -123,6 +127,10 @@
       &openssl_operation::do_sync_write, 
       this, boost::arg<1>(), boost::arg<2>()
     );
+    read_ = boost::bind(
+      &openssl_operation::do_sync_read, 
+      this
+    );
     handler_ = boost::bind(
       &openssl_operation::sync_user_handler, 
       this, boost::arg<1>(), boost::arg<2>()
@@ -135,7 +143,7 @@
   int start()
   {
     int rc = primitive_( session_ );
-    int sys_error_code = ERR_get_error();
+
     bool is_operation_done = (rc > 0);  
                 // For connect/accept/shutdown, the operation
                 // is done, when return code is 1
@@ -145,6 +153,8 @@
     int error_code =  !is_operation_done ?
           ::SSL_get_error( session_, rc ) :
           0;        
+    int sys_error_code = ERR_get_error();
+
     bool is_read_needed = (error_code == SSL_ERROR_WANT_READ);
     bool is_write_needed = (error_code == SSL_ERROR_WANT_WRITE ||
                               ::BIO_ctrl_pending( ssl_bio_ ));
@@ -212,6 +222,10 @@
 
         return start();
       }
+      else if (is_read_needed)
+      {
+        return read_();
+      }
     }
 
     // Continue with operation, flush any SSL data out to network...
@@ -223,10 +237,12 @@
   typedef boost::function<int (const boost::system::error_code&, int)>
     int_handler_func;
   typedef boost::function<int (bool, int)> write_func;
+  typedef boost::function<int ()> read_func;
 
   ssl_primitive_func  primitive_;
   user_handler_func  user_handler_;
   write_func  write_;
+  read_func  read_;
   int_handler_func handler_;
     
   net_buffer send_buf_; // buffers for network IO
@@ -250,8 +266,15 @@
     throw boost::system::system_error(error);
   }
     
-  int async_user_handler(const boost::system::error_code& error, int rc)
+  int async_user_handler(boost::system::error_code error, int rc)
   {
+    if (rc < 0)
+    {
+      if (!error)
+        error = boost::asio::error::no_recovery;
+      rc = 0;
+    }
+
     user_handler_(error, rc);
     return 0;
   }
@@ -316,8 +339,8 @@
     }
     
     // OPeration is not done and writing to net has been made...
-    // start reading...
-    do_async_read();
+    // start operation again
+    start();
           
     return 0;
   }
@@ -340,7 +363,7 @@
       handler_(error, rc);
   }
 
-  void do_async_read()
+  int do_async_read()
   {
     // Wait for new data
     socket_.async_read_some
@@ -355,6 +378,7 @@
         boost::asio::placeholders::bytes_transferred
       ) 
     );
+    return 0;
   }
 
   void async_read_handler(const boost::system::error_code& error,
@@ -433,8 +457,8 @@
       // Finish the operation, with success
       return rc;
                 
-    // Operation is not finished, read data from net...
-    return do_sync_read();
+    // Operation is not finished, start again.
+    return start();
   }
 
   int do_sync_read()