⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rvselect.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:
#if (RV_OS_TYPE == RV_OS_TYPE_NUCLEUS)
        *error = (NU_Is_Connected(*osFd) != NU_TRUE);
#else
        if (RvSocketGetLastError(osFd, &lastError) != RV_OK)
            *error = RV_TRUE;

        if (lastError != 0)
            *error = RV_TRUE;
#endif
    }

    return RV_OK;
}



#endif  /* select(), poll(), /dev/poll */



#if (RV_SELECT_TYPE == RV_SELECT_SELECT)

/* todo: comment the following 4 functions */
RvStatus RvSelectGetSelectFds(
    IN  RvSelectEngine* selectEngine,
    OUT int*            numFds,
    OUT fd_set*         rdSet,
    OUT fd_set*         wrSet)
{
    *numFds = selectEngine->maxFdInSelect + 1;

    /* todo: these memcpy might not work in all operating systems! */
    if (rdSet != NULL)
        memcpy(rdSet, &selectEngine->rdSet, sizeof(fd_set));
    if (wrSet != NULL)
        memcpy(wrSet, &selectEngine->wrSet, sizeof(fd_set));

    return RV_OK;
}


RvStatus RvSelectHandleSelectFds(
    IN RvSelectEngine*  selectEngine,
    IN fd_set*          rdSet,
    IN fd_set*          wrSet,
    IN int              numFds,
    IN int              numEvents)
{
    /* Seems like we'll have to look for these events */
    RvSocket fd;
    RvBool hasRead, hasWrite;

    if (numEvents < 0)
        return RvSelectErrorCode(RV_ERROR_UNKNOWN);

    if (numEvents == 0)
        return RV_OK;

    for (fd = numFds; fd >= 0; fd--)
    {
        hasRead = FD_ISSET(fd, rdSet);
        hasWrite = FD_ISSET(fd, wrSet);

        if (hasRead || hasWrite)
        {
            /* We've got an event */
            RvSelectEvents selectEvent = 0;
            RvSelectFd* fdNode = fdBucketHashFind(selectEngine, fd);

            if ((fdNode != NULL) && (fdNode->callback != NULL))
            {
                RvBool error = RV_FALSE;

                if (hasRead)
                    selectEvent = RV_SELECT_READ;
                if (hasWrite)
                    selectEvent = RV_SELECT_WRITE;

                /* Translate events to the richer set of events */
                RvSelectEventsToUser(&fdNode->fd, fdNode->events, &selectEvent, &error);

                /* Make sure we're actually waiting for this event */
                if ((fdNode->events & selectEvent) != 0)
                {
                    RvSelectLogDebug((&rvSelectLogSource,
                        "Occured event: fd=%d,event=%s,error=%d",
                        fdNode->fd, fdGetEventStr(selectEvent), error));

                    /* Tell the user about this event */
                    fdNode->callback(selectEngine, fdNode, selectEvent, error);
                }
            }

            if (hasRead) numEvents--;
            if (hasWrite) numEvents--;
            if (numEvents == 0)
                break; /* No more events to look for */
        }
    }

    return RV_OK;
}


#endif  /* (RV_SELECT_TYPE == RV_SELECT_SELECT) */


#if ((RV_SELECT_TYPE == RV_SELECT_POLL) || (RV_SELECT_TYPE == RV_SELECT_DEVPOLL))

RvStatus RvSelectGetPollFds(
    IN    RvSelectEngine*   selectEngine,
    INOUT int*              maxFds,
    OUT   struct pollfd*    pollFdSet)
{
    int engineMaxFds;
#if (RV_SELECT_TYPE == RV_SELECT_POLL)
    engineMaxFds = (int)selectEngine->maxFdInPoll;
#elif (RV_SELECT_TYPE == RV_SELECT_DEVPOLL)
    engineMaxFds = (int)selectEngine->maxFdInDevPoll;
#endif

    if (*maxFds < engineMaxFds)
        return RvSelectErrorCode(RV_ERROR_OUTOFRANGE);

    *maxFds = engineMaxFds;
    memcpy(pollFdSet, selectEngine->fdArray, sizeof(struct pollfd) * engineMaxFds);

    return RV_OK;
}


RvStatus RvSelectHandlePollFds(
    IN RvSelectEngine*  selectEngine,
    IN struct pollfd*   pollFdSet,
    IN int              numFds,
    IN int              numEvents)
{
    struct pollfd* pollFdElem;
    RvUint32 i;
    RvSelectFd* fdNode;

    if (numEvents < 0)
        return RvSelectErrorCode(RV_ERROR_UNKNOWN);

    if (numEvents == 0)
        return RV_OK;

    pollFdElem = pollFdSet;
    for (i = 0; i < numFds; i++)
    {
        if (pollFdElem->revents != 0)
        {
            /* Find out which fd are we dealing with */
            fdNode = fdBucketHashFind(selectEngine, pollFdElem->fd);

            if ((fdNode != NULL) && (fdNode->callback != NULL))
            {
                RvSelectEvents selectEvent = 0;
                RvBool error = RV_FALSE;

                /* Get read/write/error from the returned events */
                if ((pollFdElem->revents & POLLIN) || (pollFdElem->revents & POLLHUP))
                    selectEvent |= RV_SELECT_READ;
                if (pollFdElem->revents & POLLOUT)
                    selectEvent |= RV_SELECT_WRITE;
                if (pollFdElem->revents & POLLERR)
                    error = RV_TRUE;

                /* Translate events to the richer set of events */
                RvSelectEventsToUser(&fdNode->fd, fdNode->events, &selectEvent, &error);

                /* Make sure we're actually waiting for this event */
                if ((fdNode->events & selectEvent) != 0)
                {
                    RvInt32 lastError = 0;
                    if (error == RV_TRUE)
                    {
                        RvSocketGetLastError(&fdNode->fd, &lastError);
                        if (lastError == 0)
                            lastError = 1;
                    }
                    RvSelectLogDebug((&rvSelectLogSource,
                        "Occured event: fd=%d,event=%s,error=%d",
                        fdNode->fd, fdGetEventStr(selectEvent), lastError));

                    /* Tell the user about this event */
                    fdNode->callback(selectEngine, fdNode, selectEvent, error);
                }
            }
            else
            {
                RvSelectLogExcep((&rvSelectLogSource,
                    "Event on something that we're not waiting for (fd=%d)", pollFdElem->fd));
            }

            /* We've got one less result to look for */
            numEvents--;
            if (numEvents == 0)
                break;
        }

        /* Get the next one in array */
        pollFdElem++;
    }

    return RV_OK;
}


#endif  /* ((RV_SELECT_TYPE == RV_SELECT_POLL) || (RV_SELECT_TYPE == RV_SELECT_DEVPOLL)) */







/********************************************************************************************
 *
 *                          Public functions
 *
 ********************************************************************************************/




RvStatus RvSelectInit(void)
{
#if (RV_SELECT_TYPE == RV_SELECT_WIN32_WSA)
    {
        WNDCLASS wc;
        WSADATA wsaData;

        /* Start Windows Sockets */
        WORD winsockVersion = MAKEWORD(2, 2);
        if (WSAStartup(winsockVersion, &wsaData) != 0)
            return RvSelectErrorCode(RV_ERROR_UNKNOWN);

        /* Create a window class for network events */
        memset(&wc, 0, sizeof(WNDCLASS));
        wc.lpfnWndProc   = rvSelectWinFunc;
        wc.hInstance     = NULL;
        wc.lpszClassName = RV_FD_EVENTS_CLASS;
        if (!RegisterClass(&wc))
            return RvSelectErrorCode(RV_ERROR_UNKNOWN);

        return RV_OK;
    }


#elif (RV_SELECT_TYPE == RV_SELECT_WIN32_COMPLETION)
    {
        WSADATA wsaData;

        /* Start Windows Sockets */
        WORD winsockVersion = MAKEWORD(2, 2);
        if (WSAStartup(winsockVersion, &wsaData) != 0)
            return RvSelectErrorCode(RV_ERROR_UNKNOWN);
        return RV_OK;
    }


#elif (RV_SELECT_TYPE == RV_SELECT_SELECT)
    rvSelectMaxDescriptors = SELECT_FD_SETSIZE;
    return RV_OK;


#elif ((RV_SELECT_TYPE == RV_SELECT_POLL) || (RV_SELECT_TYPE == RV_SELECT_DEVPOLL))
    /* Find out the limits posed by the OS on the amount of file descriptors */
    {
        struct rlimit r;

        if (getrlimit(RLIMIT_NOFILE, &r) < 0)
            return RvSelectErrorCode(RV_SELECT_ERROR_GETRLIMIT);

        rvSelectMaxDescriptors = r.rlim_cur;
    }

    return RV_OK;


#endif
}



RvStatus RvSelectEnd(void)
{
    RvStatus ret = RV_OK;

#if (RV_SELECT_TYPE == RV_SELECT_WIN32_WSA)
    if (WSACleanup() != 0)
        ret = RvSelectErrorCode(RV_ERROR_UNKNOWN);

    if (UnregisterClass(RV_FD_EVENTS_CLASS, NULL/*hInstance*/) == 0)
        ret = RvSelectErrorCode(RV_ERROR_UNKNOWN);


#elif (RV_SELECT_TYPE == RV_SELECT_WIN32_COMPLETION)
    if (WSACleanup() != 0)
        return RvSelectErrorCode(RV_ERROR_UNKNOWN);


#elif (RV_SELECT_TYPE == RV_SELECT_SELECT)


#elif (RV_SELECT_TYPE == RV_SELECT_POLL)


#elif (RV_SELECT_TYPE == RV_SELECT_DEVPOLL)
#endif

    return ret;
}


RVCOREAPI RvStatus RVCALLCONV RvSelectSetMaxFileDescriptors(IN RvUint32 maxFileDescriptors)
{
#if ((RV_SELECT_TYPE == RV_SELECT_SELECT) || \
    (RV_SELECT_TYPE == RV_SELECT_POLL) || \
    (RV_SELECT_TYPE == RV_SELECT_DEVPOLL))
    rvSelectMaxDescriptors = maxFileDescriptors;
    return RV_OK;
#else
    return RvSelectErrorCode(RV_ERROR_NOTSUPPORTED);
#endif
}


RVCOREAPI RvUint32 RVCALLCONV RvSelectGetMaxFileDescriptors(void)
{
#if ((RV_SELECT_TYPE == RV_SELECT_SELECT) || \
    (RV_SELECT_TYPE == RV_SELECT_POLL) || \
    (RV_SELECT_TYPE == RV_SELECT_DEVPOLL))
    return rvSelectMaxDescriptors;
#else
    return 0;
#endif
}


/********************************************************************************************
 * RvSelectConstruct
 *
 * purpose : Create a new file descriptor engine
 * input   : selectEngine     - Events engine to construct
 *           maxHashSize        - Hash size used by the engine
 *
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvSelectConstruct(
    OUT RvSelectEngine*         selectEngine,
    IN  RvUint32                maxHashSize)
{
    RvStatus status = RV_OK;

    status = RvLogSourceConstruct(RvLogGet(), &rvSelectLogSource, RV_LOG_LIBCODE_CCORE,
        "SELECT", "File Descriptors Events Engine");
    if (status != RV_OK)
        return status;

    memset(selectEngine, 0, sizeof(RvSelectEngine));

    status = RvLockConstruct(&selectEngine->lock);
    if (status != RV_OK)
        return status;

    /* Create a bucket hash if needed */
    status = fdBucketHashConstruct(selectEngine, maxHashSize);
    if (status != RV_OK)
    {
        RvLockDestruct(&selectEngine->lock);
        return status;
    }

#if (RV_SELECT_TYPE == RV_SELECT_WIN32_WSA)
    {
        /* Create a widnow to use for network events */
        char windowName[30];

        if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
            GetCurrentProcess(), &selectEngine->threadHandle,
            DUPLICATE_SAME_ACCESS, FALSE, THREAD_ALL_ACCESS) == 0)
        {
            /* Got an error */
            status = RvSelectErrorCode(RV_ERROR_UNKNOWN);
        }
        else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -