Allow unregistering connect callback in AsyncSocket
authorViswanath Sivakumar <viswanath@fb.com>
Tue, 23 Dec 2014 20:16:48 +0000 (12:16 -0800)
committerDave Watson <davejwatson@fb.com>
Mon, 29 Dec 2014 18:40:21 +0000 (10:40 -0800)
Summary:
Sometimes when the socket is destroyed from a destructor, we wouldn't
want further callbacks on shutdown. We can unregister the readCallback_
by calling setReadCB(nullptr), but if the state is CONNECTING, we can
still get connectErr() callback. I found an ASAN trace (https://phabricator.fb.com/P18837265)
that turned out to be because of this inability to cancel this callback.
This provides a way to unregister the connect callback as well.

Test Plan: fbconfig -r folly && fbmake runtests

Reviewed By: afrind@fb.com

Subscribers: folly-diffs@

FB internal diff: D1751778

Tasks: 5852935

Signature: t1:1751778:1419363638:26967c2d4fc5819e4d65ae706d217a954dfd784f

folly/io/async/AsyncSocket.cpp
folly/io/async/AsyncSocket.h

index 172b5bed235bd7b1c7bfb279472440c2e3539a6c..167a49bfdd3b105ec2804128ae9151de4fff02c5 100644 (file)
@@ -481,6 +481,13 @@ void AsyncSocket::connect(ConnectCallback* callback,
   }
 }
 
+void AsyncSocket::cancelConnect() {
+  connectCallback_ = nullptr;
+  if (state_ == StateEnum::CONNECTING) {
+    closeNow();
+  }
+}
+
 void AsyncSocket::setSendTimeout(uint32_t milliseconds) {
   sendTimeout_ = milliseconds;
   assert(eventBase_ == nullptr || eventBase_->isInEventBaseThread());
index 30a5615f75b6db8021d29580f17758bf3b9df113..7819647bfee30ca85ba74d93ff4d8c010f0c8010 100644 (file)
@@ -260,6 +260,15 @@ class AsyncSocket : virtual public AsyncTransportWrapper {
                int timeout = 00,
                const OptionMap &options = emptyOptionMap) noexcept;
 
+  /**
+   * If a connect request is in-flight, cancels it and closes the socket
+   * immediately. Otherwise, this is a no-op.
+   *
+   * This does not invoke any connection related callbacks. Call this to
+   * prevent any connect callback while cleaning up, etc.
+   */
+  void cancelConnect();
+
   /**
    * Set the send timeout.
    *