]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Revert change to add a poll flag for one-shot callbacks.
authorOliver Kurth <okurth@vmware.com>
Mon, 23 Oct 2017 21:21:21 +0000 (14:21 -0700)
committerOliver Kurth <okurth@vmware.com>
Mon, 23 Oct 2017 21:21:21 +0000 (14:21 -0700)
open-vm-tools/lib/asyncsocket/asyncsocket.c

index 758dd88f42d3c8bed86b36bc98cc5f0eb4f10465..bdea2f56dfbdca754dc4819a4a2db03cac0416a8 100644 (file)
@@ -94,7 +94,6 @@
 #include "msg.h"
 #include "posix.h"
 #include "vmci_sockets.h"
-#include "vm_basic_asm.h"
 #ifndef VMX86_TOOLS
 #include "vmdblib.h"
 #endif
@@ -4755,22 +4754,22 @@ AsyncTCPSocketIPollRecvCallback(void *clientData)  // IN:
 
    AsyncTCPSocketLock(asock);
    if (asock->recvCbTimer) {
-      /* IVmdbPoll only has periodic timer callbacks. */
+      /* IVmdbPoll only has periodic callbacks. */
       AsyncTCPSocketIPollRemove(asock, FALSE, 0, asock->internalRecvFn);
       asock->recvCbTimer = FALSE;
    }
    lock = AsyncTCPSocketPollParams(asock)->lock;
+   asock->inIPollCb |= IN_IPOLL_RECV;
    if (asock->recvCb && asock->inBlockingRecv == 0) {
-      asock->inIPollCb |= IN_IPOLL_RECV;
-      AsyncTCPSocketRecvCallback(clientData);
-      asock->inIPollCb &= ~IN_IPOLL_RECV;
       /*
-       * Re-register the callback if it has not been canceled.  Lock may have
-       * been dropped to fire recv callback so re-check inBlockingRecv.
+       * There is no need to take a reference here -- the fact that this
+       * callback is running means AsyncsocketIPollRemove would not release a
+       * reference if it is called.
        */
-      if (asock->recvCb && asock->inBlockingRecv == 0) {
-         AsyncTCPSocketIPollAdd(asock, TRUE, POLL_FLAG_READ,
-                                asock->internalRecvFn, asock->fd);
+      int error = AsyncTCPSocketFillRecvBuffer(asock);
+
+      if (error == ASOCKERR_GENERIC || error == ASOCKERR_REMOTE_DISCONNECT) {
+         AsyncTCPSocketHandleError(asock, error);
       }
    } else {
       TCPSOCKLG0(asock, ("Skip recv because %s\n",
@@ -4778,11 +4777,19 @@ AsyncTCPSocketIPollRecvCallback(void *clientData)  // IN:
                                        : "recv callback is cancelled"));
    }
 
-   /* This is a one-shot callback so we always release the reference taken. */
-   AsyncTCPSocketRelease(asock);
-   AsyncTCPSocketUnlock(asock);
-   if (lock != NULL) {
-      MXUser_DecRefRecLock(lock);
+   asock->inIPollCb &= ~IN_IPOLL_RECV;
+   if (asock->recvCb) {
+      AsyncTCPSocketUnlock(asock);
+   } else {
+      /*
+       * Callback has been unregistered.  Per above, we need to release the
+       * reference explicitly.
+       */
+      AsyncTCPSocketRelease(asock);
+      AsyncTCPSocketUnlock(asock);
+      if (lock != NULL) {
+         MXUser_DecRefRecLock(lock);
+      }
    }
 #endif
 }
@@ -4890,15 +4897,21 @@ AsyncTCPSocketIPollSendCallback(void *clientData)  // IN:
    AsyncTCPSocketLock(s);
    s->inIPollCb |= IN_IPOLL_SEND;
    lock = AsyncTCPSocketPollParams(s)->lock;
-   if (s->sendCbTimer) {
-      /* IVmdbPoll only has periodic timer callback. */
-      AsyncTCPSocketIPollRemove(s, FALSE, 0, AsyncTCPSocketIPollSendCallback);
-      s->sendCbTimer = FALSE;
-   }
    if (s->sendCb) {
+      /*
+       * Unregister this callback as we want the non-periodic behavior.  There
+       * is no need to take a reference here -- the fact that this callback is
+       * running means AsyncsocketIPollRemove would not release a reference.
+       * We would release that reference at the end.
+       */
+      if (s->sendCbTimer) {
+         AsyncTCPSocketIPollRemove(s, FALSE, 0, AsyncTCPSocketIPollSendCallback);
+      } else {
+         AsyncTCPSocketIPollRemove(s, TRUE, POLL_FLAG_WRITE,
+                                   AsyncTCPSocketIPollSendCallback);
+      }
+
       AsyncTCPSocketSendCallback(s);
-   } else {
-      TCPSOCKLG0(s, ("cancelled send callback fired\n"));
    }
 
    s->inIPollCb &= ~IN_IPOLL_SEND;
@@ -5052,9 +5065,8 @@ AsyncTCPSocketIPollAdd(AsyncTCPSocket *asock,         // IN
    poll = AsyncTCPSocketPollParams(asock)->iPoll;
 
    if (socket) {
-      int pollFlags = VMDB_PRF_ONE_SHOT |
-                      ((flags & POLL_FLAG_READ) != 0 ? VMDB_PRF_READ
-                                                     : VMDB_PRF_WRITE);
+      int pollFlags = (flags & POLL_FLAG_READ) != 0 ? VMDB_PRF_READ
+                                                    : VMDB_PRF_WRITE;
 
       ret = poll->Register(poll, pollFlags, callback, asock, info);
    } else {
@@ -5112,9 +5124,8 @@ AsyncTCPSocketIPollRemove(AsyncTCPSocket *asock,         // IN
    poll = AsyncTCPSocketPollParams(asock)->iPoll;
 
    if (socket) {
-      int pollFlags = VMDB_PRF_ONE_SHOT |
-                      ((flags & POLL_FLAG_READ) != 0 ? VMDB_PRF_READ
-                                                     : VMDB_PRF_WRITE);
+      int pollFlags = (flags & POLL_FLAG_READ) != 0 ? VMDB_PRF_READ
+                                                    : VMDB_PRF_WRITE;
 
       ret = poll->Unregister(poll, pollFlags, callback, asock);
    } else {