Example #1
0
VOID
VmDnsSockPosixFreeEventQueue(
    PVM_SOCK_EVENT_QUEUE pQueue
    )
{
    if (pQueue->pSignalReader)
    {
        VmDnsSockPosixReleaseSocket(pQueue->pSignalReader);
    }
    if (pQueue->pSignalWriter)
    {
        VmDnsSockPosixReleaseSocket(pQueue->pSignalWriter);
    }
    if (pQueue->pMutex)
    {
        VmDnsFreeMutex(pQueue->pMutex);
    }
    if (pQueue->epollFd >= 0)
    {
        close(pQueue->epollFd);
    }
    if (pQueue->pEventArray)
    {
        VmDnsFreeMemory(pQueue->pEventArray);
        pQueue->pEventArray = NULL;
    }
    VmDnsFreeMemory(pQueue);
}
Example #2
0
VOID
VmDnsSockPosixFreeIoBuffer(
    PVM_SOCK_IO_BUFFER     pIoBuffer
    )
{
//    VMDNS_LOG_DEBUG("pIoBuffer:%p released from thread %p", pIoBuffer, pthread_self());
    if (pIoBuffer && pIoBuffer->pClientSocket)
    {
        VmDnsSockPosixReleaseSocket(pIoBuffer->pClientSocket);
    }
    PVM_SOCK_IO_CONTEXT pIoContext = CONTAINING_RECORD(pIoBuffer, VM_SOCK_IO_CONTEXT, IoBuffer);
    VMDNS_SAFE_FREE_MEMORY(pIoContext);
}
Example #3
0
VOID
VmDnsSockPosixFreeIoBuffer(
    PVM_SOCK_IO_BUFFER     pIoBuffer
    )
{
    PVM_SOCK_IO_CONTEXT pIoContext = NULL;

    if (pIoBuffer)
    {
        if (pIoBuffer->pClientSocket)
        {
            VmDnsSockPosixReleaseSocket(pIoBuffer->pClientSocket);
        }
        pIoContext = CONTAINING_RECORD(pIoBuffer, VM_SOCK_IO_CONTEXT, IoBuffer);
        VMDNS_SAFE_FREE_MEMORY(pIoContext);
    }
}
Example #4
0
static
DWORD
VmDnsSockPosixEventQueueDelete_inlock(
    PVM_SOCK_EVENT_QUEUE pQueue,
    PVM_SOCKET           pSocket
    )
{
    DWORD dwError = 0;
    struct epoll_event event = {0};

    if (pSocket->bInEventQueue == TRUE &&
        epoll_ctl(pQueue->epollFd, EPOLL_CTL_DEL, pSocket->fd, &event) < 0)
    {
        dwError = LwErrnoToWin32Error(errno);
        BAIL_ON_POSIX_SOCK_ERROR(dwError);
    }
    pSocket->bInEventQueue = FALSE;
    VmDnsSockPosixReleaseSocket(pSocket);

error:

    return dwError;
}
Example #5
0
DWORD
VmDnsSockPosixWaitForEvent(
    PVM_SOCK_EVENT_QUEUE pQueue,
    int                  iTimeoutMS,
    PVM_SOCKET*          ppSocket,
    PVM_SOCK_EVENT_TYPE  pEventType,
    PVM_SOCK_IO_BUFFER*  ppIoBuffer
    )
{
    DWORD  dwError = 0;
    BOOLEAN bLocked = FALSE;
    VM_SOCK_EVENT_TYPE eventType = VM_SOCK_EVENT_TYPE_UNKNOWN;
    PVM_SOCKET pSocket = NULL;
    PVM_SOCK_IO_BUFFER pIoBuffer = NULL;
    PVM_SOCK_IO_CONTEXT pIoContext = NULL;
    uint64_t uiTriggerCount = 0;

    if (!pQueue || !ppSocket || !pEventType)
    {
        dwError = ERROR_INVALID_PARAMETER;
        BAIL_ON_POSIX_SOCK_ERROR(dwError);
    }

    dwError = VmDnsLockMutex(pQueue->pMutex);
    BAIL_ON_POSIX_SOCK_ERROR(dwError);

    bLocked = TRUE;

    if (pQueue->bShutdown)
    {
        dwError = ERROR_SHUTDOWN_IN_PROGRESS;
        BAIL_ON_POSIX_SOCK_ERROR(dwError);
    }

    if ((pQueue->state == VM_SOCK_POSIX_EVENT_STATE_PROCESS) &&
        (pQueue->iReady >= pQueue->nReady))
    {
        pQueue->state = VM_SOCK_POSIX_EVENT_STATE_WAIT;
    }

    if (pQueue->state == VM_SOCK_POSIX_EVENT_STATE_WAIT)
    {
        pQueue->iReady = 0;
        pQueue->nReady = -1;

        while (pQueue->nReady < 0)
        {
            pQueue->nReady = epoll_wait(
                                pQueue->epollFd,
                                pQueue->pEventArray,
                                pQueue->dwSize,
                                iTimeoutMS);

            if ((pQueue->nReady < 0) && (errno != EINTR))
            {
                dwError = LwErrnoToWin32Error(errno);
                BAIL_ON_POSIX_SOCK_ERROR(dwError);
            }

            if (pQueue->bShutdown)
            {
                dwError = ERROR_SHUTDOWN_IN_PROGRESS;
                BAIL_ON_POSIX_SOCK_ERROR(dwError);
            }
        }

        pQueue->state = VM_SOCK_POSIX_EVENT_STATE_PROCESS;
    }

    if (pQueue->state == VM_SOCK_POSIX_EVENT_STATE_PROCESS)
    {
        if (pQueue->iReady < pQueue->nReady)
        {
            struct epoll_event* pEvent = &pQueue->pEventArray[pQueue->iReady];
            PVM_SOCKET pEventSocket = (PVM_SOCKET)pEvent->data.ptr;

            if (!pEventSocket)
            {
                dwError = ERROR_INVALID_STATE;
                BAIL_ON_POSIX_SOCK_ERROR(dwError);
            }

            if (pEvent->events & (EPOLLERR | EPOLLHUP))
            {
                eventType = VM_SOCK_EVENT_TYPE_CONNECTION_CLOSED;

                pSocket = VmDnsSockPosixAcquireSocket(pEventSocket);

                dwError = VmDnsSockPosixEventQueueDelete_inlock(
                                        pQueue,
                                        pSocket);
                BAIL_ON_POSIX_SOCK_ERROR(dwError);
            }
            else if (pEventSocket->type == VM_SOCK_TYPE_LISTENER)
            {
                switch (pEventSocket->protocol)
                {
                    case VM_SOCK_PROTOCOL_TCP:

                        dwError = VmDnsSockPosixAcceptConnection(
                                        pEventSocket,
                                        &pSocket);
                        BAIL_ON_POSIX_SOCK_ERROR(dwError);

                        dwError = VmDnsSockPosixSetNonBlocking(pSocket);
                        BAIL_ON_POSIX_SOCK_ERROR(dwError);

                        eventType = VM_SOCK_EVENT_TYPE_TCP_NEW_CONNECTION;

                        break;

                    case VM_SOCK_PROTOCOL_UDP:

                        pSocket = VmDnsSockPosixAcquireSocket(pEventSocket);

                        eventType = VM_SOCK_EVENT_TYPE_DATA_AVAILABLE;

                        break;

                    default:

                        dwError = ERROR_INVALID_STATE;
                        BAIL_ON_POSIX_SOCK_ERROR(dwError);

                        break;
                }
            }
            else if (pEventSocket->type == VM_SOCK_TYPE_SERVER)
            {
                switch (pEventSocket->protocol)
                {
                    case VM_SOCK_PROTOCOL_TCP:
                        if (!pEventSocket->pData)
                        {
                            eventType = VM_SOCK_EVENT_TYPE_TCP_REQUEST_SIZE_READ;
                        }

                        pSocket = VmDnsSockPosixAcquireSocket(pEventSocket);

                        break;

                    default:
                        dwError = ERROR_INVALID_STATE;
                        BAIL_ON_POSIX_SOCK_ERROR(dwError);

                        break;
                }
            }
            else if (pEventSocket->type == VM_SOCK_TYPE_SIGNAL)
            {
                if (pQueue->bShutdown)
                {
                    dwError = ERROR_SHUTDOWN_IN_PROGRESS;
                    BAIL_ON_POSIX_SOCK_ERROR(dwError);
                }
                else
                {
                    pSocket = VmDnsSockPosixAcquireSocket(pEventSocket);
                }
            }
            else if (pEventSocket->type == VM_SOCK_TYPE_TIMER)
            {
                if (pQueue->bShutdown)
                {
                    dwError = ERROR_SHUTDOWN_IN_PROGRESS;
                    BAIL_ON_POSIX_SOCK_ERROR(dwError);
                }
                else
                {
                    pSocket = VmDnsSockPosixAcquireSocket(pEventSocket);

                    if (read(pSocket->fd, &uiTriggerCount, sizeof(uiTriggerCount)) < 0)
                    {
                        VMDNS_LOG_ERROR("%s: read() on timer fd failed (%d)", __FUNCTION__, errno);
                    }

                    eventType = VM_SOCK_EVENT_TYPE_TIMER_EXPIRATION;
                }
            }
            else
            {
                pSocket = VmDnsSockPosixAcquireSocket(pEventSocket);
            }
        }

        pQueue->iReady++;
    }

    dwError = VmDnsSockPosixSetData(pSocket, NULL, (PVOID *)&pIoBuffer);
    BAIL_ON_POSIX_SOCK_ERROR(dwError);

    if (pIoBuffer && eventType == VM_SOCK_EVENT_TYPE_UNKNOWN)
    {
        pIoContext = CONTAINING_RECORD(pIoBuffer, VM_SOCK_IO_CONTEXT, IoBuffer);
        eventType = pIoContext->eventType;
    }

    *ppSocket = pSocket;
    *ppIoBuffer = pIoBuffer;
    *pEventType = eventType;

cleanup:

    if (bLocked)
    {
        VmDnsUnlockMutex(pQueue->pMutex);
    }

    return dwError;

error:

    if (ppSocket)
    {
        *ppSocket = NULL;
    }
    if (ppIoBuffer)
    {
        *ppIoBuffer = NULL;
    }
    if (pEventType)
    {
        *pEventType = VM_SOCK_EVENT_TYPE_UNKNOWN;
    }
    if (pSocket)
    {
        VmDnsSockPosixReleaseSocket(pSocket);
    }

    goto cleanup;
}