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

📄 osapi_linux.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/**
 * OS Message Queue Remove function.
 *
 * @param mqId     - message queue identifier
 * @param *strMsg  - message pointer, the location of where the removed message is to be placed after it has been removed
 * @param uiSize   - message size (not used)
 *
 * @retval
 *    OS_OK if successful
 *    OS_FAILURE if not successful
 *    OS_TIMEOUT if msg queue is empty
 */
#if defined(NDEBUG)
OS_STATUS OS_MsgQRemove(OS_MSG_Q_ID mqId, char *strMsg, ULONG ulSize)
#else
OS_STATUS OS_MsgQRemoveDbg(OS_MSG_Q_ID mqId, char *strMsg, ULONG ulSize, char *srcFile, int srcLine)
#endif
{
    /* Check the validity of message queue */
    if (mqId == 0)
    {
#if defined(NDEBUG)
        DbgPrint(("%s: BAD POINTER.\n", __FUNCTION__));
#else
        DbgPrint(("%s: BAD POINTER.  Called by %s:%u\n", __FUNCTION__, srcFile, srcLine));
#endif
        return (OS_FAILURE);
    }

    /* Receive message from the head by default */
    return (OS_MsgQReceiveOption(mqId, strMsg, ulSize, OS_NO_WAIT, OS_MSG_Q_TAIL) );
}

/**
 * OS Message Queue Receive Option function. Same as OS_MsgQReceive, but allow message to received
 *      from either the head or the tail of the message queue.
 *
 * @param mqId     - message queue identifier
 * @param *strMsg  - message pointer, the location of where the received message is to be placed after it has been received
 * @param uiSize   - message size (not used)
 * @param iTimeout - send timeout value, in ticks. (-1 = wait forever, 0 = no wait, > 1 = wait)
 * @param iOption  - head or tail of message queue (OS_MSG_Q_HEAD or OS_MSG_Q_TAIL)
 *
 * @retval
 *    OS_OK if successful
 *    OS_FAILURE if not successful
 *    OS_TIMEOUT if a timeout occurred
 */
static OS_STATUS OS_MsgQReceiveOption(OS_MSG_Q_ID mqId, char *strMsg, ULONG ulSize, int iTimeout, int iOption)
{
    OS_STATUS iRet  = OS_OK;
    OS_MBOX   *pmsg = (OS_MBOX *)mqId;
    struct timeval  tv;
    struct timespec abstime;

    /* Check the validity of message queue */
    if (mqId == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: INVALID mqId!\n", __FUNCTION__));
        goto error_handler;
    }

    /* Check the validity of message */
    if (strMsg == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: BAD POINTER!\n", __FUNCTION__));
        goto error_handler;
    }

    if (ulSize != pmsg->ulSize)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: INVALID SIZE!\n", __FUNCTION__));
        goto error_handler;
    }

    /* Get Mutex */
    if (pthread_mutex_lock(&pmsg->mutex) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to obtain lock\n",__FUNCTION__));
        goto error_handler;
    }

    if ( (OS_WAIT_FOREVER != iTimeout) && (OS_NO_WAIT != iTimeout) )
    {
        /* get the current time */
        if (gettimeofday(&tv, NULL) != 0)
        {
            DbgPrint(("%s: gettimeofday Failed!\n",__FUNCTION__));
            pthread_mutex_unlock(&pmsg->mutex);
            iRet = OS_FAILURE;
            goto error_handler;
        }

        /* set our timeout */
        abstime.tv_sec  = tv.tv_sec + iTimeout/CLOCKS_PER_SEC;
        abstime.tv_nsec = ( tv.tv_usec + (iTimeout%CLOCKS_PER_SEC) ) * 1000;

        while ( abstime.tv_nsec > 1000000000 )
        {
            abstime.tv_sec  += 1;
            abstime.tv_nsec -= 1000000000;
        }
    }

    /* If empty queue, wait */
    while (pmsg->ulHead == pmsg->ulTail)
    {
        if (OS_WAIT_FOREVER == iTimeout)
        {
            if (pthread_cond_wait(&pmsg->condWaitEmpty, &pmsg->mutex) != 0)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MsgQReceive: pthread_cond_wait ERROR!\n"));
                iRet = OS_FAILURE;
                break;
            }
        }
        else if (OS_NO_WAIT == iTimeout)
        {
            iRet = OS_TIMEOUT;
            break;
        }
        else
        {
            iRet = pthread_cond_timedwait(&pmsg->condWaitEmpty, &pmsg->mutex, &abstime);
            if (iRet != 0)
            {
                if (iRet == ETIMEDOUT)
                {
                    iRet = OS_TIMEOUT;
                    break;
                }
                else
                {
                    switch ( iRet )
                    {
                        case EINVAL:	DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MsgQReceive: pthread_cond_timedwait ERROR = EINVAL\n"));	break;
                        case EFAULT:    DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MsgQReceive: pthread_cond_timedwait ERROR = EFAULT\n"));	break;
                        case ETIMEDOUT: DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MsgQReceive: pthread_cond_timedwait ERROR = ETIMEDOUT\n"));	break;
                       	default:		DBGPRINT(DBG_ON(DBG_ERROR), ("OS_MsgQReceive: pthread_cond_timedwait ERROR = unknown\n"));	break;
                    }

                    iRet = OS_FAILURE;
                    break;
                }
            }
        }
    }

    /* if we didn't time out, receive it from the queue */
    if (OS_OK == iRet)
    {
        /* Receive it from the queue */
        if (iOption == OS_MSG_Q_TAIL)
        {
            /* Receive from tail of queue */
            pmsg->ulTail = ( (pmsg->ulTail + pmsg->ulDepth) % (pmsg->ulDepth + 1) );
            memcpy(strMsg, pmsg->pbBuffers + (pmsg->ulTail * pmsg->ulSize), pmsg->ulSize);
        }
        else
        {
            /* Receive from head of queue */
            memcpy(strMsg, pmsg->pbBuffers + (pmsg->ulHead * pmsg->ulSize), pmsg->ulSize);
            pmsg->ulHead = ( (pmsg->ulHead + 1) % (pmsg->ulDepth + 1) );
        }

        /* Signal any waiters */
        if (pthread_cond_signal(&pmsg->condWaitFull))
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Broadcast Failed\n",__FUNCTION__));
        }
    }

    /* Release mutex */
    if (pthread_mutex_unlock(&pmsg->mutex))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to release lock\n",__FUNCTION__));
        goto error_handler;
    }

    /* Return success */
    return (iRet);

error_handler:

    /* Return failure */
    return (OS_FAILURE);
}

/**
 * Removes all messages from the queue.
 *
 * @param mqId - message queue identifier
 *
 * @retval OS_OK if successful, else an osapi error code.
 */
OS_STATUS OS_MsgQReset(OS_MSG_Q_ID mqId)
{
    OS_MBOX *pmsg = (OS_MBOX *)mqId;

    /* Check the validity of message queue */
    if (mqId == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: BAD POINTER!\n", __FUNCTION__));
        goto error_handler;
    }

    /* Get Mutex */
    if (pthread_mutex_lock(&pmsg->mutex) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to obtain lock\n",__FUNCTION__));
        goto error_handler;
    }

    /* reset queue */
    pmsg->ulHead = pmsg->ulTail;

    /* Signal any waiters */
    if (pthread_cond_broadcast(&pmsg->condWaitEmpty))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Broadcast Failed\n",__FUNCTION__));
    }
    if (pthread_cond_broadcast(&pmsg->condWaitFull))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Broadcast Failed\n",__FUNCTION__));
    }

    /* Release mutex */
    if (pthread_mutex_unlock(&pmsg->mutex))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s: Failed to release lock\n",__FUNCTION__));
        goto error_handler;
    }

    /* Return success */
    return (OS_OK);

error_handler:

    /* Return failure */
    return (OS_FAILURE);
}

/**
 * OS Message Queue Number of Messages function.
 *
 * @param
 *    OS_MSG_Q_ID mqId - message queue identifier
 *
 * @retval
 *    Returns the number of messages in the given message queue.
 */
int OS_MsgQNumMsgs(OS_MSG_Q_ID mqId)
{
    OS_MBOX *pmsg        = (OS_MBOX *)mqId;
    int     num_messages = 0;

    /* Check the validity of message queue */
    if (mqId == 0)
    {
        DbgPrint(("%s: BAD POINTER!\n", __FUNCTION__));
        return (OS_FAILURE);
    }

    /* Get Mutex */
    if (pthread_mutex_lock(&pmsg->mutex) == 0)
    {
        if (pmsg->ulHead > pmsg->ulTail)
        {
            num_messages = pmsg->ulTail + pmsg->ulDepth + 1 - pmsg->ulHead;
        }
        else
        {
            num_messages = pmsg->ulTail - pmsg->ulHead;
        }

        /* Release mutex */
        pthread_mutex_unlock(&pmsg->mutex);
    }
    else
    {
        num_messages = OS_FAILURE;
    }

    return (num_messages);
}

/******************************************************************************
*******************************************************************************
**                                                                           **
**  Semaphore function definitions                                           **
**                                                                           **
*******************************************************************************
******************************************************************************/

/**
 * OS Semaphore Binary Create function.
 *
 * @param
 *    int iOSOptions - operating system options (not used)
 *
 * @param
 *    OS_SEM_B_STATE semsInitialState - initial semaphore state
 *
 * @retval
 *    OS_SEM_ID semId - semaphore identifier, if successful
 *    0 - if not successful
 */
OS_SEM_ID OS_SemBCreate(int iOSOptions, OS_SEM_B_STATE semsInitialState)
{
    OS_SEMAPHORE *psemRecord = NULL;

    /* Check the validity of the initial semaphore state */
    if ( (semsInitialState != OS_SEM_EMPTY) && (semsInitialState != OS_SEM_FULL) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemBCreate: Invalid initial state (%d)!\n", semsInitialState));
        goto error;
    }

    /* Allocate a record for the semaphore */
    psemRecord = (OS_SEMAPHORE *)OS_MemAlloc(sizeof(OS_SEMAPHORE));
    if (psemRecord == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemBCreate: Could not allocate semaphore record!\n"));
        goto error;
    }

    /* Set the semaphore type as binary */
    psemRecord->ulSemType = OS_SEM_BINARY;

    /* Set maximum to 1  */
    psemRecord->ulMaxCount = 0;

    /* Set count to the parameter */
    psemRecord->ulCount = semsInitialState;

    /* No name was specified for the semaphore */
    strncpy(psemRecord->strName, "\0", MAX_NAME_SIZE);

    /* Create the binary semaphore */
    if (pthread_cond_init(&psemRecord->condWait, NULL) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemBCreate: Could not init condWait"));
        goto error;
    }
    if (pthread_mutex_init(&psemRecord->mutex, NULL) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemBCreate: Could not init mutex"));
        goto error;
    }

    /* Return a handle to the binary semaphore */
    return (OS_SEM_ID)psemRecord;

error:
    if (NULL != psemRecord)
    {
        OS_MemFree(psemRecord);
    }
    return (0);
}

/**
 * OS Semaphore Binary Create function.
 *
 * @param iOSOptions - operating system options (not used)
 * @param semsInitialState - initial semaphore state
 * @param strName - Null terminated string.
 *
 * @retval
 *    OS_SEM_ID semId - semaphore identifier, if successful
 *    0 - if not successful
 */
OS_SEM_ID OS_SemBCreateNamed(int iOSOptions, OS_SEM_B_STATE semsInitialState, char *strName)
{
    OS_SEM_ID semId = 0;
    OS_SEMAPHORE *psemRecord;

    /*
     *  Create a counting semaphore
     */
    semId = OS_SemBCreate(iOSOptions, semsInitialState);
    if (semId == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemBCreateNamed: Could not create named semaphore!\n"));
        return 0;
    }

    /*
     *  Name the semaphore
     */
    psemRecord = (OS_SEMAPHORE *)semId;
    strncpy(psemRecord->strName, strName, MAX_NAME_SIZE);
    psemRecord->strName[MAX_NAME_SIZE-1] = 0;

    /*
     *  Return a handle to the counting semaphore
     */
    return (OS_SEM_ID)psemRecord;
}

/**
 * OS Semaphore Count Create function.
 *
 * @param
 *    int iOSOptions - operating system options
 *
 * @param
 *    int iInitialCount - initial reference count
 *
 * @retval
 *    OS_SEM_ID semId - semaphore identifier, if successful
 *    0 - if not successful
 */
OS_SEM_ID OS_SemCCreate(int iOSOptions, int iInitialCount)
{
    OS_SEMAPHORE *psemRecord = NULL;

    /* Check the validity of the given initial count */
    if (iInitialCount < 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemCCreate: Invalid initial count (%d)!\n", iInitialCount));
        goto error;
    }

    /* Allocate a record for the semaphore */
    psemRecord = (OS_SEMAPHORE *)OS_MemAlloc(sizeof(OS_SEMAPHORE));
    if (psemRecord == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemCCreate: Could not allocate semaphore record!\n"));
        goto error;
    }

    /* Set the semaphore type as counting */
    psemRecord->ulSemType = OS_SEM_COUNTING;

    /* No name was specified for the semaphore */
    strncpy(psemRecord->strName, "\0", MAX_NAME_SIZE);

    /* Set maximum count to some large number... */
    psemRecord->ulMaxCount = 32678;

    /* Set count to the parameter */
    psemRecord->ulCount = iInitialCount;

    /* Create the binary semaphore */
    if (pthread_cond_init(&psemRecord->condWait, NULL) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemCCreate: Could not init condWait"));
        goto error;
    }
    if (pthread_mutex_init(&psemRecord->mutex, NULL) != 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("OS_SemCCreate: Could not init mutex"));
        goto error;
    }

    /* Return a handle to the counting semaphore */
    return (OS_SEM_ID)psemRecord;

error:
    if (NULL != psemRecord)
    {
        OS_MemFree(psemRecord);
    }
    return (0);
}

/**
 * OS Semaphore Count Create (Named) function.
 *
 * @param
 *    int iOSOptions - operating system options
 *

⌨️ 快捷键说明

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