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

📄 rvselect.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:
        {
            RvSprintf(windowName, "%s%p", RV_FD_EVENTS_CLASS, selectEngine);
            selectEngine->hNetEventsWnd =
                CreateWindow(RV_FD_EVENTS_CLASS, windowName,
                    WS_OVERLAPPED | WS_MINIMIZE,
                    0, 0, 0, 0, NULL, NULL, NULL/*hInstance*/, NULL);
            if (selectEngine->hNetEventsWnd == NULL)
            {
                CloseHandle(selectEngine->threadHandle);
                status = RvSelectErrorCode(RV_ERROR_UNKNOWN);
            }
        }

        if (status == RV_OK)
        {
            selectEngine->threadId = GetCurrentThreadId();

#ifdef SetWindowLongPtr
            /* 64bit support for Windows */
            SetWindowLongPtr(selectEngine->hNetEventsWnd, GWLP_USERDATA, (LONG_PTR)selectEngine);
#else
            SetWindowLong(selectEngine->hNetEventsWnd, GWL_USERDATA, (LONG)selectEngine);
#endif
        }
    }


#elif (RV_SELECT_TYPE == RV_SELECT_WIN32_COMPLETION)
    selectEngine->completionPort =
        CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, (ULONG_PTR)0, 0);
    if (selectEngine->completionPort == NULL)
        status = RvSelectErrorCode(RV_ERROR_UNKNOWN);


#elif (RV_SELECT_TYPE == RV_SELECT_SELECT)
    selectEngine->maxFd = rvSelectMaxDescriptors;
    selectEngine->maxFdInSelect = 0;

    /* Clear file descriptor sets */
    FD_ZERO(&selectEngine->rdSet);
    FD_ZERO(&selectEngine->wrSet);
    FD_ZERO(&selectEngine->tmpRdSet);
    FD_ZERO(&selectEngine->tmpWrSet);



#elif (RV_SELECT_TYPE == RV_SELECT_POLL)
    selectEngine->maxFd = rvSelectMaxDescriptors;
    selectEngine->maxFdInPoll = 0;

    status = RvMemoryAlloc(NULL, (void**)&selectEngine->fdArray, sizeof(struct pollfd) * rvSelectMaxDescriptors);


#elif (RV_SELECT_TYPE == RV_SELECT_DEVPOLL)
    selectEngine->maxFd = rvSelectMaxDescriptors;
    selectEngine->maxFdInDevPoll = 0;

    /* Open /dev/poll file descriptor we'll use */
    if ((selectEngine->fdDevPoll = open("/dev/poll", O_RDWR)) < 0)
        status = RvSelectErrorCode(RV_ERROR_UNKNOWN);
    else
    {
        status = RvMemoryAlloc(NULL, (void**)&selectEngine->fdArray, sizeof(struct pollfd) * rvSelectMaxDescriptors);
        if (status != RV_OK)
            close(selectEngine->fdDevPoll);
    }

#endif


    status = rvFdPreemptionConstruct(selectEngine);
#if (RV_SELECT_PREEPEMTION_TYPE == RV_SOCKET_PREEMPTION_SOCKET) || \
    (RV_SELECT_PREEPEMTION_TYPE == RV_SOCKET_PREEMPTION_PIPE)
    if (status == RV_OK)
    {
    }

#endif

    if (status != RV_OK)
    {
        fdBucketHashDestruct(selectEngine);
        RvLockDestruct(&selectEngine->lock);
    }

    return status;
}



/********************************************************************************************
 * RvSelectDestruct
 *
 * purpose : Destruct a file descriptor engine
 * input   : selectEngine - Events engine to destruct
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvSelectDestruct(IN RvSelectEngine* selectEngine)
{
#if (RV_SELECT_TYPE == RV_SELECT_WIN32_WSA)
    DestroyWindow(selectEngine->hNetEventsWnd);
    CloseHandle(selectEngine->threadHandle);


#elif (RV_SELECT_TYPE == RV_SELECT_WIN32_COMPLETION)
    CloseHandle(selectEngine->completionPort);


#elif (RV_SELECT_TYPE == RV_SELECT_SELECT)
    /* Nothing special to do actually */


#elif (RV_SELECT_TYPE == RV_SELECT_POLL)
    RvMemoryFree(selectEngine->fdArray);


#elif (RV_SELECT_TYPE == RV_SELECT_DEVPOLL)
    close(selectEngine->fdDevPoll);
    RvMemoryFree(selectEngine->fdArray);

#endif

    rvFdPreemptionDestruct(selectEngine);

    /* Deallocate the bucket hash we're using */
    fdBucketHashDestruct(selectEngine);

    /* Kill the lock */
    RvLockDestruct(&selectEngine->lock);

    RvLogSourceDestruct(RvLogGet(), &rvSelectLogSource);

    return RV_OK;
}



/********************************************************************************************
 * RvFdConstruct
 *
 * purpose : Construct a file descriptor for a given socket
 * input   : fd - File descriptor to construct
 *           s  - Socket to use for this file descriptor
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvFdConstruct(
    IN RvSelectFd*  fd,
    IN RvSocket*    s)
{
#ifdef RV_NULLCHECK
    if ((fd == NULL) || (s == NULL))
        return RvSelectErrorCode(RV_ERROR_NULLPTR);
#endif

    fd->fd = *s;
    return RV_OK;
}


/********************************************************************************************
 * RvFdDestruct
 *
 * purpose : Destruct a file descriptor of a given socket
 * input   : fd - File descriptor to destruct
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvFdDestruct(
    IN RvSelectFd*        fd)
{
    RV_UNUSED_ARG(fd);
    return RV_OK;
}


/********************************************************************************************
 * RvFdGetSocket
 *
 * purpose : Get the socket associated with the file descriptor struct
 * input   : fd - File descriptor
 * return  : Socket associated with the file descriptor on success
 *           NULL on failure
 ********************************************************************************************/
RVCOREAPI
RvSocket* RVCALLCONV RvFdGetSocket(IN RvSelectFd* fd)
{
#ifdef RV_NULLCHECK
    if (fd == NULL)
        return NULL;
#endif

    return &fd->fd;
}


/********************************************************************************************
 * RvSelectGetEvents
 *
 * purpose : Return the list of events we're waiting on for a given file descriptor
 * input   : fd - File descriptor
 * output  : None
 * return  : Events we're waiting on
 ********************************************************************************************/
RVCOREAPI
RvSelectEvents RVCALLCONV RvSelectGetEvents(IN RvSelectFd* fd)
{
#ifdef RV_NULLCHECK
    if (fd == NULL)
        return (RvSelectEvents)0;
#endif

    return fd->events;
}


/********************************************************************************************
 * RvSelectFindFd
 *
 * purpose : Find the RvSelectFd object by the socket/file descriptor it's connected to.
 *           This one is used by H.323 to allow calls to seliCallOn() from the stack's
 *           API.
 * input   : selectEngine   - Events engine to look in
 *           s              - Socket/file descriptor object to find
 * output  : None
 * return  : RvSelectFd object if one exists, NULL otherwise.
 ********************************************************************************************/
RVCOREAPI
RvSelectFd* RVCALLCONV RvSelectFindFd(
    IN RvSelectEngine*  selectEngine,
    IN RvSocket*        s)
{
#ifdef RV_NULLCHECK
    if ((selectEngine == NULL) || (s == NULL))
        return NULL;
#endif

    return fdBucketHashFind(selectEngine, *s);
}


/********************************************************************************************
 * RvSelectAdd
 *
 * purpose : Add a new file descriptor to those being checked
 * input   : selectEngine   - Events engine of this fd
 *           fd             - File descriptor to check
 *           selectEvents   - Events to check
 *           eventsCb       - Callback to use when these events occur
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvSelectAdd(
    IN RvSelectEngine*      selectEngine,
    IN RvSelectFd*          fd,
    IN RvSelectEvents       selectEvents,
    IN RvSelectCb           eventsCb)
{
    RvBool allocatedBucketHash = RV_FALSE;
    RvStatus ret = RV_OK;

    RvSelectLogEnter((&rvSelectLogSource,
        "RvSelectAdd(fd=%d,events=%s%s%s%s%s,cb=%p)", fd->fd,
        fdGetEventStr((RvSelectEvents)(selectEvents & RvSelectRead)),
        fdGetEventStr((RvSelectEvents)(selectEvents & RvSelectWrite)),
        fdGetEventStr((RvSelectEvents)(selectEvents & RvSelectAccept)),
        fdGetEventStr((RvSelectEvents)(selectEvents & RvSelectConnect)),
        fdGetEventStr((RvSelectEvents)(selectEvents & RvSelectClose)),
        eventsCb));

    /* Add the events to the bucket hash */
    ret = fdBucketHashAdd(selectEngine, fd);
    if (ret == RV_OK)
        allocatedBucketHash = RV_TRUE;

#if (RV_SELECT_TYPE == RV_SELECT_WIN32_WSA)
    if (ret == RV_OK)
    {
        if (WSAAsyncSelect(fd->fd, selectEngine->hNetEventsWnd, FD_NET_MESSAGE, selectEvents) != 0)
            ret = RvSelectErrorCode(RV_ERROR_UNKNOWN);
    }


#elif (RV_SELECT_TYPE == RV_SELECT_WIN32_COMPLETION)
    {
        HANDLE ioCompletionPort;
        ioCompletionPort = CreateIoCompletionPort((HANDLE)fd->fd,
            selectEngine->completionPort, (ULONG_PTR)fd, 0);
        if (ioCompletionPort == NULL)
            ret = RvSelectErrorCode(RV_ERROR_UNKNOWN);
    }


#elif (RV_SELECT_TYPE == RV_SELECT_SELECT)
    if (ret == RV_OK)
    {
        RvSelectEvents translatedEvents;

#if (RV_OS_TYPE != RV_OS_TYPE_WINCE) && defined(RV_RANGECHECK)
        /* Windows CE doesn't really care that the socket's fd value is within
           the range of FD_SETSIZE. This is because the fd_set struct is actually
           defined more like poll - a list of fd's to select and not a bits buffer.
           If we'll range check for WinCE we'll just get errors after several socket
           constructions. */
        if ((fd->fd < 0) || (fd->fd >= selectEngine->maxFd))
            ret = RvSelectErrorCode(RV_ERROR_OUTOFRANGE);
#endif  /* (RV_OS_TYPE != RV_OS_TYPE_WINCE) && defined(RV_RANGECHECK) */

        if (ret == RV_OK)
        {
            RvLockGet(&selectEngine->lock);

            /* Update the maximum limit of select() if we have to */
            if (fd->fd > selectEngine->maxFdInSelect)
                selectEngine->maxFdInSelect = fd->fd;

            /* Since Unix systems support only Read/Write events, we have to translate
               the richer set of events we have */
            translatedEvents = rvSelectToOS(selectEvents);

            if (translatedEvents & RV_SELECT_READ)
                RV_FD_SET(fd->fd, &selectEngine->rdSet);
            if (translatedEvents & RV_SELECT_WRITE)
                RV_FD_SET(fd->fd, &selectEngine->wrSet);

            RvLockRelease(&selectEngine->lock);
        }
    }


#elif (RV_SELECT_TYPE == RV_SELECT_POLL)
    if (ret == RV_OK)
    {
        RvSelectEvents translatedEvents;
        struct pollfd* pollFdElem;

#ifdef RV_RANGECHECK
        if ((fd->fd < 0) || (fd->fd >= selectEngine->maxFd))
            ret = RvSelectErrorCode(RV_ERROR_OUTOFRANGE);
#endif  /* RV_RANGECHANGE */

        if (ret == RV_OK)
        {
            RvLockGet(&selectEngine->lock);

            /* Find the entry to fill in */
            pollFdElem = selectEngine->fdArray + selectEngine->maxFdInPoll;

            /* Since Unix systems support only Read/Write events, we have to translate
               the richer set of events we have */
            translatedEvents = rvSelectToOS(selectEvents);

            /* Fill in the pollfd element */
            pollFdElem->fd = fd->fd;
            pollFdElem->events = 0;
            pollFdElem->revents = 0;
            if (translatedEvents & RV_SELECT_READ)
                pollFdElem->events |= POLLIN;
            if (translatedEvents & RV_SELECT_WRITE)
                pollFdElem->events |= POLLOUT;

            /* Make sure to link the fd to this one */
            fd->fdArrayIndex = selectEngine->maxFdInPoll;

            /* Update the array size for poll() */
            selectEngine->maxFdInPoll++;

            RvLockRelease(&selectEngine->lock);
        }
    }


#elif (RV_SELECT_TYPE == RV_SELECT_DEVPOLL)
    if (ret == RV_OK)
    {
        RvSelectEvents translatedEvents;
        struct pollfd fdUpdate;

#ifdef RV_RANGECHECK
        if ((fd->fd < 0) || (fd->fd >= selectEngine->maxFd))
            ret = RvSelectErrorCode(RV_ERROR_OUTOFRANGE);
#endif  /* RV_RANGECHANGE */

        if (ret == RV_OK)
        {

⌨️ 快捷键说明

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