This is an automated email from the ASF dual-hosted git repository.

baodi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pulsar-client-cpp.git


The following commit(s) were added to refs/heads/main by this push:
     new 8d5a412  Close the socket gracefully on Windows (#284)
8d5a412 is described below

commit 8d5a412cc51f58b3d66c67742f348ec8982cb614
Author: Yunze Xu <[email protected]>
AuthorDate: Tue Jun 20 15:28:00 2023 +0800

    Close the socket gracefully on Windows (#284)
    
    * Close the socket gracefully on Windows
    
    Fixes https://github.com/apache/pulsar-client-cpp/issues/261
    
    ### Motivation
    
    When closing the socket on Windows, the `ERROR_CONNECTION_ABORTED` error
    might be returned in the callback of `async_receive`. It's caused by the
    `socket::close` method is not portable enough, see
    
https://www.boost.org/doc/libs/1_81_0/doc/html/boost_asio/reference/basic_stream_socket/close/overload2.html
    
    > For portable behaviour with respect to graceful closure of a connected 
socket, call shutdown() before closing the socket.
    
    ### Modifications
    
    Call `shutdown` in `ClientConnection::closeSocket` before calling
    `close`. In addition, when no bytes are returned or the `eof` error
    happened,  print the logs with debug level whatever the error code
    is in the read callback.
    
    * Handle operation_failed first
---
 lib/ClientConnection.cc | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/lib/ClientConnection.cc b/lib/ClientConnection.cc
index 4af5da0..828cdaf 100644
--- a/lib/ClientConnection.cc
+++ b/lib/ClientConnection.cc
@@ -609,13 +609,13 @@ void ClientConnection::handleRead(const 
boost::system::error_code& err, size_t b
     incomingBuffer_.bytesWritten(bytesTransferred);
 
     if (err || bytesTransferred == 0) {
-        if (err) {
-            if (err == boost::asio::error::operation_aborted) {
-                LOG_DEBUG(cnxString_ << "Read operation was canceled: " << 
err.message());
-            } else {
-                LOG_ERROR(cnxString_ << "Read operation failed: " << 
err.message());
-            }
-        }  // else: bytesTransferred == 0, which means server has closed the 
connection
+        if (err == boost::asio::error::operation_aborted) {
+            LOG_DEBUG(cnxString_ << "Read operation was canceled: " << 
err.message());
+        } else if (bytesTransferred == 0 || err == boost::asio::error::eof) {
+            LOG_DEBUG(cnxString_ << "Server closed the connection: " << 
err.message());
+        } else {
+            LOG_ERROR(cnxString_ << "Read operation failed: " << 
err.message());
+        }
         close();
     } else if (bytesTransferred < minReadSize) {
         // Read the remaining part, use a slice of buffer to write on the next
@@ -1355,6 +1355,7 @@ Future<Result, SchemaInfo> 
ClientConnection::newGetSchema(const std::string& top
 void ClientConnection::closeSocket() {
     boost::system::error_code err;
     if (socket_) {
+        socket_->shutdown(boost::asio::socket_base::shutdown_both, err);
         socket_->close(err);
         if (err) {
             LOG_WARN(cnxString_ << "Failed to close socket: " << 
err.message());

Reply via email to