From: Oliver Kurth Date: Tue, 24 Oct 2017 21:07:33 +0000 (-0700) Subject: Back out commit d2c18c44...: Make VigorPollImpl FD-based callbacks non-periodic X-Git-Tag: stable-10.3.0~232 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=921f05729bdbcb83a98ab1a28641baabd095af97;p=thirdparty%2Fopen-vm-tools.git Back out commit d2c18c44...: Make VigorPollImpl FD-based callbacks non-periodic Yet another issue is exposed by the change. This is a clean backout but keeping the cleanupOnError fix in SharedStreamFactory::Get. --- diff --git a/open-vm-tools/lib/asyncsocket/asyncsocket.c b/open-vm-tools/lib/asyncsocket/asyncsocket.c index 54c61d269..bdea2f56d 100644 --- a/open-vm-tools/lib/asyncsocket/asyncsocket.c +++ b/open-vm-tools/lib/asyncsocket/asyncsocket.c @@ -4754,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", @@ -4777,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 } @@ -4889,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; @@ -5051,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 { @@ -5111,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 {