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

📄 rvlog.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
Filename   : rvlog.c
Description: log handling
************************************************************************
        Copyright (c) 2001 RADVISION Inc. and RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Inc. and RADVISION Ltd.. No part of this document may be
reproduced in any form whatsoever without written prior approval by
RADVISION Inc. or RADVISION Ltd..

RADVISION Inc. and RADVISION Ltd. reserve the right to revise this
publication and make changes without obligation to notify any person of
such revisions or changes.
***********************************************************************/

#include "rvmemory.h"
#include "rvtimestamp.h"
#include "rvthread.h"
#include "rvstdio.h"
#include "rvlock.h"
#include "rvlog.h"
#include <stdio.h>
#include <stdarg.h>
#include <rvassert.h>


#if defined(__cplusplus)
extern "C" {
#endif


/* Lets make error codes a little easier to type */
#define RvLogErrorCode(_e) RvErrorCode(RV_ERROR_LIBCODE_CCORE, RV_CCORE_MODULE_LOG, (_e))


/* Log manager to use. This object is single and static in the system */
static RvLogMgr rvLogMgr;


/* Lock used for log buffer printing */
static RvLock rvLogLock;






RvStatus RvLogInit(void)
{
    RvStatus status;

    status = RvLockConstruct(&rvLogLock);
    if (status != RV_OK)
        return status;

    status = RvLogConstruct(&rvLogMgr);
    if (status != RV_OK)
        RvLockDestruct(&rvLogLock);

    return status;
}


RvStatus RvLogEnd(void)
{
    RvStatus ret;

    ret = RvLogDestruct(&rvLogMgr);

    /* See if there's a buffer to deallocate in this thread */
    RvLockDestruct(&rvLogLock);
    
    return ret;
}


/********************************************************************************************
 * RvLogGet
 *
 * purpose : Get the pointer to the global log manager
 * input   : None
 * output  : None
 * return  : Pointer to global log manager
 ********************************************************************************************/
RVCOREAPI
RvLogMgr* RVCALLCONV RvLogGet(void)
{
    return &rvLogMgr;
}


/********************************************************************************************
 * RvLogConstruct
 *
 * purpose : Create a log object. Only a single such object is used by the core and the
 *           stacks on top of it.
 * input   : logMgr - Log manager to construct
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogConstruct(IN RvLogMgr* logMgr)
{
    RvStatus ret;

#if defined(RV_NULLCHECK)
    if (logMgr == NULL)
        return RvLogErrorCode(RV_ERROR_NULLPTR);
#endif

    memset(logMgr, 0, sizeof(logMgr));
    logMgr->defaultMask = RV_LOGMASK_COMPILEMASK;
    logMgr->level = 1; /* Default is log by the masks */

    ret = RvLockConstruct(&logMgr->lock);

    return ret;
}


/********************************************************************************************
 * RvLogDestruct
 *
 * purpose : Kill a log object
 * input   : logMgr - Log manager to destruct
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogDestruct(IN RvLogMgr* logMgr)
{
    RvStatus ret;

#if defined(RV_NULLCHECK)
    if (logMgr == NULL)
        return RvLogErrorCode(RV_ERROR_NULLPTR);
#endif

    ret = RvLockDestruct(&logMgr->lock);

    return ret;
}



/********************************************************************************************
 * RvLogRegisterListener
 *
 * purpose : Set a listener function to the log. Multiple listeners can be set on each log
 *           object. The listener is used to actually log the messages.
 * input   : logMgr     - Log manager to use
 *           listener   - Listener function, called on each message
 *           userData   - User data set as a parameter of the listener function
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogRegisterListener(
    IN RvLogMgr*    logMgr,
    IN RvLogPrintCb listener,
    IN void*        userData)
{
    RvStatus ret;

#if defined(RV_NULLCHECK)
    if (logMgr == NULL)
        return RvLogErrorCode(RV_ERROR_NULLPTR);
#endif

    ret = RvLockGet(&logMgr->lock);
    if (ret == RV_OK)
    {
        if (logMgr->numListeners < RV_LOG_MAX_LISTENERS)
        {
#if defined(RV_OTHERCHECK)
            RvInt32 i;

            /* Make sure this listener is not already registered */
            for (i = 0; i < logMgr->numListeners; i++)
            {
                if (logMgr->listener[i] == listener)
                {
                    ret = RvLogErrorCode(RV_LOG_ERROR_ALREADY_REGISTERED);
                    break;
                }
            }
#endif  /* defined(RV_OTHERCHECK) */

            /* Add the listener */
            logMgr->listener[logMgr->numListeners] = listener;
            logMgr->listenerUserData[logMgr->numListeners] = userData;
            logMgr->numListeners++;
        }
        else
            ret = RvLogErrorCode(RV_ERROR_OUTOFRESOURCES);

        if (RvLockRelease(&logMgr->lock) != RV_OK)
            return RvLogErrorCode(RV_ERROR_UNKNOWN);
    }

    return ret;
}


/********************************************************************************************
 * RvLogUnregisterListener
 *
 * purpose : Unset a listener function from the log.
 * input   : logMgr     - Log manager to use
 *           listener   - Listener function, called on each message
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogUnregisterListener(
    IN RvLogMgr*    logMgr,
    IN RvLogPrintCb listener)
{
    RvInt32 i;

#ifdef RV_NULLCHECK
    if (logMgr == NULL)
        return RvLogErrorCode(RV_ERROR_NULLPTR);
#endif

    for (i = 0; i < logMgr->numListeners; i++)
    {
        if (logMgr->listener[i] == listener)
        {
            if (i+1 != logMgr->numListeners)
            {
                /* Seems like it's not the last - move all the bunch after this one */
                memmove(&logMgr->listener[i], &logMgr->listener[i+1], (RvSize_t)(sizeof(listener) * (logMgr->numListeners-i-1)));
            }
            logMgr->numListeners--;
            return RV_OK;
        }
    }

    return RvLogErrorCode(RV_ERROR_UNINITIALIZED);
}


/********************************************************************************************
 * RvLogSourceConstruct
 *
 * purpose : Create a new source of messages in a log manager
 * input   : logMgr     - Log manager
 *           source     - Source of messages to create
 *           libraryCode- Library code number this source is in (RV_LOG_LIBCODE_CBASE for example)
 *                        Constructing a log source with RV_LOG_LIBCODE_ANY allows a logger to
 *                        initialize the logging facilities before anyone actually registers
 *                        here and "catch" their registration.
 *           name       - Name of the source
 *           description- Description of the source
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogSourceConstruct(
    IN RvLogMgr*        logMgr,
    IN RvLogSource*     source,
    IN RvUint32         libraryCode,
    IN const RvChar*    name,
    IN const RvChar*    description)
{
    RvStatus ret;
    RvLogSource curSource;
    int i;
    int vacantIndex = -1;

    /* The description argument is not used. We only want users to use it, so we'll be able
       to tell by the name what does it do when we look at the code */
    RV_UNUSED_ARG(description);

#if defined(RV_NULLCHECK)
    if (logMgr == NULL)
        return RV_ERROR_NULLPTR;
#endif

    ret = RvLockGet(&logMgr->lock);
    if (ret != RV_OK)
        return ret;


    /* Look for a source with the same name - we can't allow it... */
    curSource = logMgr->source;
    for (i = 0; i < logMgr->numSources; i++)
    {
        if ((vacantIndex < 0) && (curSource->timesConstructed == 0))
            vacantIndex = i; /* Found a place if we'll need one */

        if ((curSource->timesConstructed > 0) &&
            (strcmp(curSource->name, name) == 0) &&
            ((curSource->libraryCode == libraryCode) ||
             (curSource->libraryCode == RV_LOG_LIBCODE_ANY) || (libraryCode == RV_LOG_LIBCODE_ANY)))
        {
            /* This one was already constructed... */
            curSource->timesConstructed++;
            *source = curSource;

            ret = RvLockRelease(&logMgr->lock);
            return ret;
        }

        /* Get the next one */
        curSource++;
    }

    /* We have to add this as a new source */
    if (vacantIndex < 0)
    {
        /* No luck in finding a free place */
        if (logMgr->numSources == RV_LOG_MAX_SOURCES)
        {
            /* No more source elements left */
            ret =  RvLogErrorCode(RV_ERROR_OUTOFRESOURCES);
        }
        else
        {
            /* Add a new place in the array */
            vacantIndex = logMgr->numSources;
            logMgr->numSources++;
        }
    }

    if (ret == RV_OK)
    {
        /* Set the new source information */
        curSource = &(logMgr->source[vacantIndex]);
        curSource->logMgr = logMgr;
        strncpy(curSource->name, name, sizeof(curSource->name));
        curSource->name[sizeof(curSource->name)-1] = '\0';
        curSource->libraryCode = libraryCode;
        curSource->messageTypes = logMgr->defaultMask;
        curSource->timesConstructed = 1;
        *source = curSource;
    }

    if (RvLockRelease(&logMgr->lock) != RV_OK)
        return RvLogErrorCode(RV_ERROR_UNKNOWN);

    return ret;
}


/********************************************************************************************
 * RvLogSourceDestruct
 *
 * purpose : Delete a source of messages from a log manager
 * input   : logMgr     - Log manager
 *           source     - Source of messages to delete
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvLogSourceDestruct(
    IN RvLogMgr*        logMgr,
    IN RvLogSource*     source)
{
    RvStatus ret;

#ifdef RV_RANGECHECK
    if (((*source)->logMgr != logMgr) || ((*source)->timesConstructed == 0))
        return RvLogErrorCode(RV_ERROR_OUTOFRANGE);
#endif

    ret = RvLockGet(&logMgr->lock);
    if (ret != RV_OK)
        return ret;

    (*source)->timesConstructed--;
    if ((*source)->timesConstructed == 0)
        memset(*source, 0, sizeof(**source));

    if (RvLockRelease(&logMgr->lock) != RV_OK)
        return RvLogErrorCode(RV_ERROR_UNKNOWN);

    return ret;
}


/********************************************************************************************
 * RvLogGetSourceByName
 *
 * purpose : Get the source for a specific log source name
 * input   : logMgr     - Log manager
 *           libraryCode- Library code number this source is in (RV_LOG_LIBCODE_CBASE for example)
 *           name       - Name of the source to find
 * output  : source     - Source found on success
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI RvStatus RVCALLCONV RvLogGetSourceByName(
    IN  RvLogMgr*       logMgr,
    IN  RvUint32        libraryCode,
    IN  const RvChar*   name,
    OUT RvLogSource*    source)
{
    RvLogSource curSource;
    int i;

#ifdef RV_NULLCHECK
    if ((logMgr == NULL) || (name == NULL) || (source == NULL))
        return RvLogErrorCode(RV_ERROR_NULLPTR);

⌨️ 快捷键说明

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