Allow error message callback cancellation regardless of socket state.
authorMaxim Georgiev <maxgeorg@fb.com>
Mon, 17 Apr 2017 19:04:17 +0000 (12:04 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Mon, 17 Apr 2017 19:08:41 +0000 (12:08 -0700)
Summary: We should be able to reset error message callback in AsyncSocket evein if the socket is closed yet. It's common to keep callback installed while the socket is connected. Once the socket is closed, the deinitialization process starts. If the callback callee component gets deallocated before the socket object is deallocated, it should be able to cancel callbacks.

Reviewed By: yfeldblum

Differential Revision: D4897335

fbshipit-source-id: 8eee26f9ebcb78a01d55598be3aff6595a3ed852

folly/io/async/AsyncSocket.cpp

index 013813f..17040bf 100644 (file)
@@ -612,7 +612,7 @@ void AsyncSocket::setErrMessageCB(ErrMessageCallback* callback) {
           << ", fd=" << fd_ << ", callback=" << callback
           << ", state=" << state_;
 
           << ", fd=" << fd_ << ", callback=" << callback
           << ", state=" << state_;
 
-  // Short circuit if callback is the same as the existing timestampCallback_.
+  // Short circuit if callback is the same as the existing errMessageCallback_.
   if (callback == errMessageCallback_) {
     return;
   }
   if (callback == errMessageCallback_) {
     return;
   }
@@ -625,6 +625,14 @@ void AsyncSocket::setErrMessageCB(ErrMessageCallback* callback) {
   DestructorGuard dg(this);
   assert(eventBase_->isInEventBaseThread());
 
   DestructorGuard dg(this);
   assert(eventBase_->isInEventBaseThread());
 
+  if (callback == nullptr) {
+    // We should be able to reset the callback regardless of the
+    // socket state. It's important to have a reliable callback
+    // cancellation mechanism.
+    errMessageCallback_ = callback;
+    return;
+  }
+
   switch ((StateEnum)state_) {
     case StateEnum::CONNECTING:
     case StateEnum::FAST_OPEN:
   switch ((StateEnum)state_) {
     case StateEnum::CONNECTING:
     case StateEnum::FAST_OPEN: