From: Oliver Kurth Date: Mon, 23 Oct 2017 21:21:20 +0000 (-0700) Subject: Fix ASSERT of registering the same callback twice X-Git-Tag: stable-10.3.0~258 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a20022349089880cb43ccdef082f02de95476984;p=thirdparty%2Fopen-vm-tools.git Fix ASSERT of registering the same callback twice 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). --- diff --git a/open-vm-tools/lib/asyncsocket/asyncsocket.c b/open-vm-tools/lib/asyncsocket/asyncsocket.c index 7a1f43a5e..7b0539e00 100644 --- a/open-vm-tools/lib/asyncsocket/asyncsocket.c +++ b/open-vm-tools/lib/asyncsocket/asyncsocket.c @@ -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);