#include "msg.h"
#include "posix.h"
#include "vmci_sockets.h"
-#include "vm_basic_asm.h"
#ifndef VMX86_TOOLS
#include "vmdblib.h"
#endif
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",
: "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
}
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;
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 {
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 {