]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Fix ASSERT of registering the same callback twice
authorOliver Kurth <okurth@vmware.com>
Mon, 23 Oct 2017 21:21:20 +0000 (14:21 -0700)
committerOliver Kurth <okurth@vmware.com>
Mon, 23 Oct 2017 21:21:20 +0000 (14:21 -0700)
The previous change for Poll introduced a bug in AsyncSocket.
When re-registering the recv callback, it needs to check whether
there is a concurrent blocking recv (which means the send callback
has detected a disconnection and is draining the pipe).  The recv
callback should act like a no-op in that case (other than to
release the reference).

open-vm-tools/lib/asyncsocket/asyncsocket.c

index 7a1f43a5e27d1590d895b3ee9f23e0873688f974..7b0539e0010cec65ac25618c6e558a6a98f8f78d 100644 (file)
@@ -4762,22 +4762,22 @@ AsyncTCPSocketIPollRecvCallback(void *clientData)  // IN:
       AsyncTCPSocketIPollRemove(asock, FALSE, 0, asock->internalRecvFn);
       asock->recvCbTimer = FALSE;
    }
-   asock->inIPollCb |= IN_IPOLL_RECV;
    lock = AsyncTCPSocketPollParams(asock)->lock;
    if (asock->recvCb && asock->inBlockingRecv == 0) {
+      asock->inIPollCb |= IN_IPOLL_RECV;
       AsyncTCPSocketRecvCallback(clientData);
+      asock->inIPollCb &= ~IN_IPOLL_RECV;
+      if (asock->recvCb) {
+         /* Re-register the callback if it has not been canceled. */
+         AsyncTCPSocketIPollAdd(asock, TRUE, POLL_FLAG_READ,
+                                asock->internalRecvFn, asock->fd);
+      }
    } else {
       TCPSOCKLG0(asock, ("Skip recv because %s\n",
                          asock->recvCb ? "blocking recv is in progress"
                                        : "recv callback is cancelled"));
    }
 
-   asock->inIPollCb &= ~IN_IPOLL_RECV;
-   if (asock->recvCb) {
-      /* Re-register the callback. */
-      AsyncTCPSocketIPollAdd(asock, TRUE, POLL_FLAG_READ, asock->internalRecvFn,
-                             asock->fd);
-   }
    /* This is a one-shot callback so we always release the reference taken. */
    AsyncTCPSocketRelease(asock);
    AsyncTCPSocketUnlock(asock);