static ClRcT 
clBitmapInfoInitialize(ClBitmapInfoT  *pBitmapInfo, 
                       ClUint32T      bitNum)
{
    ClRcT          rc           = CL_OK;    

    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Enter"));

    rc = clOsalMutexCreate(&(pBitmapInfo->bitmapLock));
    if( CL_OK != rc )
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("clOsalMutexCreate() rc: %x", rc));
        return rc;
    }

    pBitmapInfo->pBitmap  = NULL;
    pBitmapInfo->nBytes   = 0;
    pBitmapInfo->nBits    = 0;
    pBitmapInfo->nBitsSet = 0;
    rc = clBitmapRealloc(pBitmapInfo, bitNum);    
    if( CL_OK != rc )
    {
        clOsalMutexDelete(pBitmapInfo->bitmapLock);
        return rc;
    }
    pBitmapInfo->nBits = bitNum + 1; /* bitNum is 0-based FIXME i felt this is
                                      wrong*/
    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Exit"));
    return rc;
}
ClRcT clEvtTestAppInitialize(ClUint32T argc, ClCharT *argv[])
{
    ClRcT rc = CL_OK;
    ClEoExecutionObjT *pEoObj;

#if 0
    ClSvcHandleT svcHandle = { 0 };
    ClOsalTaskIdT taskId = 0;
#endif

    /*
     * Create the list to hold the mapping b/n Init Name & evtHandle 
     */
    rc = clCntLlistCreate(clEvtContInitKeyCompare, clEvtContInitDataDelete,
                          clEvtContInitDataDelete, CL_CNT_UNIQUE_KEY,
                          &gEvtTestInitInfo);
    if (CL_OK != rc)
    {
        clOsalPrintf("Creating linked list for Init Failed, rc[0x%X]\r\n", rc);
        return rc;
    }

    rc = clCntLlistCreate(clChanContainerKeyCompare, clChanContainerDataDelete,
                          clChanContainerDataDelete, CL_CNT_UNIQUE_KEY,
                          &gChanHandleInitInfo);
    if(rc!=CL_OK)
    {
        clOsalPrintf("Creating Linked List for Channel handles failed\n\r");
        return rc;
    }
    /*
     * Create a Mutex to lock the containers before accessing them 
     */
    rc = clOsalMutexCreate(&gEvtTestInitMutex);
    if (CL_OK != rc)
    {
        clOsalPrintf("Creating Mutex for Init Failed, rc[0x%X]\r\n", rc);
        return rc;
    }

    rc = clEoMyEoObjectGet(&pEoObj);
    rc = clEoClientInstall(pEoObj, CL_EO_NATIVE_COMPONENT_TABLE_ID,
                           gClEvtTestAppFuncList, (ClEoDataT) NULL,
                           (int) sizeof(gClEvtTestAppFuncList) /
                           (int) sizeof(ClEoPayloadWithReplyCallbackT));
    rc = clEvtCpmInit();

#if 0
    svcHandle.cpmHandle = &gEvtTestAppCpmHandle;
    rc = clDispatchThreadCreate(pEoObj, &taskId, svcHandle);
#endif

    return CL_OK;
}
/*
 * The container creation api
 */
ClRcT clAlarmPayloadCntListCreate()
{
    ClRcT rc = CL_OK;

    clOsalMutexCreate (&gClAlarmPayloadCntMutex);
    
    rc = clCntLlistCreate(clAlarmPayloadCntCompare, 
                          clAlarmPayloadCntEntryDeleteCallback,
                          clAlarmPayloadCntEntryDestroyCallback, 
                          CL_CNT_UNIQUE_KEY, 
                          &gPayloadCntHandle );
    return rc;
}
static ClRcT
tsActiveTimersQueueCreate (void)
{
    ClRcT returnCode = CL_ERR_INVALID_HANDLE;
    CL_FUNC_ENTER();

    gActiveTimerQueue.pFirstTimer = NULL;
    gActiveTimerQueue.pLastTimer = NULL;


    returnCode = clOsalMutexCreate (&gActiveTimerQueue.timerMutex);
    if (returnCode != CL_OK) {
        CL_FUNC_EXIT();
        return (returnCode);
    }

    gActiveTimerQueue.tickInMilliSec = gTimerConfig.timerResolution;

    /* spawn off the timer-task */
    returnCode = clOsalTaskCreateAttached("TIMER TASK",
                                          CL_OSAL_SCHED_OTHER,
                                          CL_OSAL_THREAD_PRI_NOT_APPLICABLE,  /* gTimerConfig.timerTaskPriority: Normally it would be this, but OTHER scheduling has no priority */
                                          TIMER_TASK_STACK_SIZE,
                                          tsTimerTask,
                                          NULL,
                                          &gActiveTimerQueue.timerTaskId);

    if (returnCode != CL_OK) {
        if(CL_OK != clOsalMutexDelete (gActiveTimerQueue.timerMutex)) {
            CL_FUNC_EXIT();
            return(returnCode);
        }
        CL_FUNC_EXIT();
        return (returnCode);
    }

    gActiveTimerQueue.timerServiceInitialized = 1;

    CL_FUNC_EXIT();
    return (CL_OK);
}
ClRcT
clAmsSAInitialize(
        CL_OUT      ClAmsClientHandleT                      *amsHandle,
        CL_IN       const ClAmsSAClientCallbacksT           *amsClientCallbacks,
        CL_INOUT    ClVersionT                              *version )
{

    ClRcT                                       rc = CL_OK; 
    clAmsClientInitializeRequestT               req;
    clAmsClientInitializeResponseT              *res = NULL;
    struct ams_instance                         *ams_instance = NULL;


    if (amsHandle == NULL || version == NULL)
    {
        return CL_AMS_RC(CL_ERR_NULL_POINTER);
    }
   
    /* 
     * Initialize the library and database 
     */

    if ((rc = check_lib_init())
            != CL_OK)
        goto error;

    /* 
     * Verify the version information 
     */

    if (( rc = clVersionVerify (
                    &version_database,
                    version))
            != CL_OK)
        goto error;

    /* 
     * Create the handle  
     */

    if ((rc = clHandleCreate (
                    handle_database,
                    sizeof(struct ams_instance),
                    amsHandle))
            != CL_OK)
        goto error;

    /* 
     * Check-Out the handle 
     */

    if ((rc = clHandleCheckout(
                    handle_database,
                    *amsHandle,
                    (void *)&ams_instance))
            != CL_OK)
        goto error;


    /* 
     * Initialize instance entry 
     */

    if (amsClientCallbacks) 
    {
        memcpy(&ams_instance->callbacks, amsClientCallbacks, sizeof(ClAmsSAClientCallbacksT));
    } 
    else 
    {
        memset(&ams_instance->callbacks, 0, sizeof(ClAmsSAClientCallbacksT));
    }

     if ( ( rc = clOsalMutexCreate(&ams_instance->response_mutex)) != CL_OK )
         goto error;

    /* 
     * Inform the server 
     */

    req.handle = *amsHandle;
    if ( (rc = cl_ams_client_initialize(
                    &req,
                    &res))
            != CL_OK)
        goto error;

    /* 
     * Decrement handle use count and return 
     */

    if ((rc = clHandleCheckin(
                    handle_database,
                    *amsHandle))
            != CL_OK)
        goto error;
   
    clHeapFree((void*)res);
    res = NULL;
    return CL_OK;

error:

    clHeapFree((void*)res);
    res = NULL;
    return CL_AMS_RC(rc);
}
ClRcT   clDispatchRegister(
        CL_OUT  ClHandleT*                      pDispatchHandle,
        CL_IN   ClHandleT                       svcInstanceHandle,
        CL_IN   ClDispatchCallbackT             wrapperCallback,
        CL_IN   ClDispatchQueueDestroyCallbackT queueDestroyCallback)
{
    ClRcT   rc = CL_OK;
    ClDispatchDbEntryT* thisDbEntry = NULL;
    ClFdT   fds[2] = {0};

    if (svcInstanceHandle == CL_HANDLE_INVALID_VALUE)
    {
        return CL_ERR_INVALID_PARAMETER;
    }

    if ((wrapperCallback == NULL) || (pDispatchHandle == NULL))
    {
        return CL_ERR_NULL_POINTER;
    }

    CHECK_LIB_INIT;

    /* Create the handle for this initialization of the library */
    rc = clHandleCreate (databaseHandle,
                         sizeof(ClDispatchDbEntryT),
                         pDispatchHandle);
    if (rc != CL_OK)
    {
        return rc;
    }
    CL_ASSERT (*pDispatchHandle != CL_HANDLE_INVALID_VALUE);

    /* Checkout the handle */
    rc = clHandleCheckout(databaseHandle, *pDispatchHandle, (void *)&thisDbEntry);

    if (rc != CL_OK)
    {
        return rc;
    }
    CL_ASSERT (thisDbEntry != NULL);

    /* Store SVC instance handle */
    thisDbEntry->svcInstanceHandle = svcInstanceHandle;
    thisDbEntry->svcCallback = wrapperCallback;
    thisDbEntry->queueDestroyCallback = queueDestroyCallback;

    /* Create the queue */
    rc = clQueueCreate(0x0,
                       clDispatchQueueDequeueCallback,
                       clDispatchQueueDestroyCallback,
                       &thisDbEntry->cbQueue);
    if (rc != CL_OK)
    {
        goto error_return;
    }

    /* Create Mutex to protect the queue */
    rc = clOsalMutexCreate(&thisDbEntry->dispatchMutex);
    if (rc != CL_OK)
    {
        goto error_return;
    }

    errno = 0;
    /* Create the pipe */
    ClInt32T ec = pipe(fds); // since return code for system call can be -ve
    if (ec < 0)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                ("Unable to create pipe: %s",strerror(errno)));
        rc = CL_ERR_LIBRARY;
        goto error_return;
    }
    /* 
     * Reinitialize rc to CL_OK as it would have changed with
     * above assignment
     */
    rc = CL_OK;

    thisDbEntry->readFd = fds[0];
    thisDbEntry->writeFd = fds[1];

    thisDbEntry->shouldDelete = CL_FALSE;

error_return:
    if ((clHandleCheckin(databaseHandle, *pDispatchHandle)) != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                ("clHandleCheckin failed"));
    }
    return rc;
}
ClRcT clSnmpMutexInit(void)
{
    return clOsalMutexCreate(&gOper.mtx);
}
/**
 *  Create a new State machine type.
 *
 *  API to create a new State macine Type. Maximum states in the
 *  state machine is passed in the parameter. Each state is 
 *  identified by a state id (index) and captures the transition
 *  table at each table.
 *                                                                        
 *  @param maxStates maximum states in State Machine 
 *  @param sm        [out] handle to the newly created state machine type
 *
 *  @returns 
 *    CL_OK on CL_OK <br/>
 *    CL_SM_RC(CL_ERR_NO_MEMORY) on memory allocation FAILURE <br/>
 *    CL_SM_RC(CL_ERR_NULL_POINTER) on invalid/null state machine handle <br/>
 *
 *  @see #clSmTypeDelete
 */
ClRcT
clSmTypeCreate(ClUint16T maxStates,
             ClSmTemplatePtrT* sm
             )
{
  ClRcT ret = CL_OK;
  int sz = 0;

  CL_FUNC_ENTER();
  CL_ASSERT(sm);  

  CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Create State Machine Type [%d]", maxStates));

  if(sm && (maxStates > 0)) {
    /* allocate the states and assign to top */
    *sm = (ClSmTemplatePtrT) mALLOC(sizeof(ClSmTemplateT));
    if(*sm!=0) 
      {
        sz = sizeof(ClSmStatePtrT)*(int)maxStates;
        /* allocate space to hold maxStates handles  */
        (*sm)->top = (ClSmStatePtrT*) mALLOC((size_t)sz);
        if((*sm)->top) 
          {
            (*sm)->maxStates = maxStates;
            (*sm)->objects = 0;
            /* Introduced a semaphore for handling concurrent
             * SM Instance creation/deletion
             */
            ret = clOsalMutexCreate( &((*sm)->sem));
            if (CL_OK != ret)
            {
                mFREE((*sm)->top);
                mFREE(*sm);
                ret = SM_ERR_NO_SEMA;
            }
            else
            {
                /* 
                 * default initial state to first state
                 */
                (*sm)->init = (*sm)->top[0];
                (*sm)->type = SIMPLE_STATE_MACHINE;
#ifdef DEBUG
                (*sm)->name[0] = 0;
#endif
            }
          }
        else
          {
            mFREE(*sm);
          }
      }
    if(!(*sm) || !(*sm)->top)
      {
        ret = CL_SM_RC(CL_ERR_NO_MEMORY);
      }
  } else 
    {
      ret = CL_SM_RC(CL_ERR_NULL_POINTER);
    }

  CL_FUNC_EXIT();
  return ret;
}
ClRcT clCkptSvrInitialize(void)
{
    ClRcT             rc         = CL_OK;
    /* Variable related ckptDataBackup feature thats not supported
       ClUint8T          ckptRead   = 0;
    */
    ClTimerTimeOutT   timeOut    = {0}; 
    ClIocNodeAddressT deputy = 0;
    ClIocNodeAddressT master = 0;
    ClBoolT           addressUpdate = CL_FALSE;
    SaNameT           appName    = {0};   
 
    /*
     * Allocate the memory for server control block.
     */
    rc = ckptSvrCbAlloc(&gCkptSvr);
    CKPT_ERR_CHECK(CL_CKPT_SVR,CL_LOG_SEV_ERROR, 
                   ("Checkpoint service CB create failed rc[0x %x]\n", rc), rc); 

    /*
     * Mark server as not ready.
     */
    gCkptSvr->serverUp        = CL_FALSE;
    gCkptSvr->condVarWaiting  = CL_TRUE;    

    /*
     * Create condition variable that indicate the receipt
     * of master and deputy ckpt addresses from gms.
     */
    clOsalCondCreate(&gCkptSvr->condVar);
    clOsalMutexCreate(&gCkptSvr->mutexVar);
    
    gCkptSvr->masterInfo.masterAddr = CL_CKPT_UNINIT_ADDR;
    gCkptSvr->masterInfo.deputyAddr = CL_CKPT_UNINIT_ADDR;
    gCkptSvr->masterInfo.compId     = CL_CKPT_UNINIT_VALUE; 
    gCkptSvr->masterInfo.clientHdlCount = 0;
    gCkptSvr->masterInfo.masterHdlCount = 0; 

    /*
     * Initialize gms to get the master and deputy addresses.
     */
    clOsalMutexLock(&gCkptSvr->ckptClusterSem);
    rc = clCkptMasterAddressesSet();
    master = gCkptSvr->masterInfo.masterAddr;
    deputy = gCkptSvr->masterInfo.deputyAddr;
    clOsalMutexUnlock(&gCkptSvr->ckptClusterSem);

    rc = clEoMyEoObjectGet(&gCkptSvr->eoHdl);
    rc = clEoMyEoIocPortGet(&gCkptSvr->eoPort);
   
    /*
     * Install the ckpt native table.
     */
    rc = clCkptEoClientInstall();
    CL_ASSERT(rc == CL_OK);
    
    rc = clCkptEoClientTableRegister(CL_IOC_CKPT_PORT);
    CL_ASSERT(rc == CL_OK);

    /*
     * Initialize the event client library.
     */
    ckptEventSvcInitialize();
    
    /* 
     * Initialize ckpt lib for persistent memory.
     * Obtain ckptRead flag that will tell whether ckpt server needs to 
     * read data from persistent memory or not.
     */

    /*
      Feature not yet supported see bug 6017 -- Do not forget to uncomment ckptDataBackupFinalize
      rc = ckptDataBackupInitialize(&ckptRead);
    */

    if(rc != CL_OK)
    {
        clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_SEV_WARNING, NULL,
                   CL_LOG_MESSAGE_2_LIBRARY_INIT_FAILED, "ckpt", rc);
    }

    if( gCkptSvr->localAddr == master )
    {
        /*
         * The node coming up is master. If deputy exists, syncup with deputy
         * else syncup with persistant memory (if existing).
         */
        rc = clCpmComponentNameGet(gCkptSvr->amfHdl, &appName);
        if(clCpmIsCompRestarted(appName))
        {
            if((deputy != CL_CKPT_UNINIT_ADDR) && ( (ClInt32T) deputy != -1))
            {
                rc = ckptMasterDatabaseSyncup(deputy);
                /*
                 * If deputy server is not reachable then pull info from the 
                 * persistent memory.
                 */
                if(CL_RMD_TIMEOUT_UNREACHABLE_CHECK(rc))
                {
                    clLogNotice(CL_CKPT_AREA_ACTIVE, "DBS", 
                                "Database Syncup with ckpt master failed with RMD timeout error. rc 0x%x",rc);
                    /* This is dead code as the feature is not supported
                       if(ckptRead == 1)
                       {
                       rc = ckptPersistentMemoryRead();
                       }
                    */
                }
            }
        }
        /* This is dead code as the feature is not supported
           else
           {
           if(ckptRead == 1)
           {
           rc = ckptPersistentMemoryRead();
           }
           }
        */
    }
    
    /*TODO:This check is only for seleting the deputy or for what */
    clOsalMutexLock(gCkptSvr->mutexVar);    
    if( (clIocLocalAddressGet() != master) &&
        (gCkptSvr->condVarWaiting == CL_TRUE)     )
    {
        /*
         * Ensure that the node gets the master and deputy addresses before
         * proceeding further.
         */
        timeOut.tsSec            = 5;
        timeOut.tsMilliSec       = 0;
        clOsalCondWait(gCkptSvr->condVar, gCkptSvr->mutexVar, timeOut);
        gCkptSvr->condVarWaiting = CL_FALSE;
        addressUpdate = CL_TRUE;
    }
    clOsalMutexUnlock(gCkptSvr->mutexVar);    

    /*  
     * We double check again incase we had waited for the gms cluster track.
     * but with the right lock sequence below instead of shoving it in the
     * condwait above.
     */
    if(addressUpdate == CL_TRUE)
    {
        clOsalMutexLock(&gCkptSvr->ckptClusterSem);
        master = gCkptSvr->masterInfo.masterAddr;
        deputy = gCkptSvr->masterInfo.deputyAddr;
        clOsalMutexUnlock(&gCkptSvr->ckptClusterSem);
    }
    /* 
     * Announce the arrival to peer in the n/w. Master server announces to 
     * all and other servers announce to master server.
     */
    ckptSvrArrvlAnnounce();
    
    /*
     * If the node coming up is deputy, syncup the metadata and ckpt info 
     * from the master. Treat all SC capable nodes except the master as deputy.
     */
    if(  gCkptSvr->localAddr != master && clCpmIsSCCapable())
    {
        /*
         * Just freezing the deputy till syncup, not to receive any master
         * related calls, this is to ensure that deputy is in full synup with
         * master and any calls from master to update deputy will sleep on the
         * lock.
         */
        CKPT_LOCK(gCkptSvr->masterInfo.ckptMasterDBSem);
        ckptMasterDatabaseSyncup(gCkptSvr->masterInfo.masterAddr);
        CKPT_UNLOCK(gCkptSvr->masterInfo.ckptMasterDBSem);
    }
    
    /* 
     * Server is up.
     */
    gCkptSvr->serverUp = CL_TRUE;
    return rc;
    exitOnError:
    {
        return rc;
    }
}
Пример #10
0
ClRcT clRmdObjInit(ClRmdObjHandleT *p)
{
    ClRcT retCode = CL_OK;
    ClRmdObjT *pRmdObject = NULL;
    //unsigned long timeStamp = 0;
    struct timeval tm1;

#ifdef DEBUG
    static ClUint8T rmdAddedTodbgComp = CL_FALSE;

    if (CL_FALSE == rmdAddedTodbgComp)
    {
        retCode = dbgAddComponent(COMP_PREFIX, COMP_NAME, COMP_DEBUG_VAR_PTR);
        rmdAddedTodbgComp = CL_TRUE;
        if (CL_OK != retCode)
        {
            clLogError("OBG","INI","dbgAddComponent FAILED ");
            CL_FUNC_EXIT();
            return retCode;
        }
    }
#endif
    CL_FUNC_ENTER();

    if (NULL == p)
    {
        RMD_DBG1((" RMD Invalid Object handle passed\n"));
        CL_FUNC_EXIT();
        return ((CL_RMD_RC(CL_ERR_INVALID_PARAMETER)));
    }

    retCode = clOsalInitialize(NULL);

    retCode = clTimerInitialize(NULL);
    pRmdObject = (ClRmdObjT *) clHeapAllocate(sizeof(ClRmdObjT));

    if (NULL == pRmdObject)
    {
        RMD_DBG1((" RMD No Memory\n"));
        CL_FUNC_EXIT();
        return ((CL_RMD_RC(CL_ERR_NO_MEMORY)));
    }

    gettimeofday(&tm1, NULL);
    //timeStamp = tm1.tv_sec * 1000000 + tm1.tv_usec;
    pRmdObject->msgId = 1;
    retCode = clOsalMutexCreate(&pRmdObject->semaForSendHashTable);

    if (CL_OK != CL_GET_ERROR_CODE(retCode))
    {
        RMD_DBG1((" RMD send Mutex creation failed\n"));
        CL_FUNC_EXIT();
        return (retCode);
    }
    retCode = clOsalMutexCreate(&pRmdObject->semaForRecvHashTable);

    if (CL_OK != CL_GET_ERROR_CODE(retCode))
    {
        RMD_DBG1((" RMD  recv Mutex creation failed\n"));

        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForSendHashTable));
        CL_FUNC_EXIT();
        return (retCode);
    }

    retCode =
        clCntHashtblCreate(NUMBER_OF_RECV_BUCKETS, recvKeyCompare,
                           recvHashFunction, recvHashDeleteCallBack,
                           recvHashDeleteCallBack, CL_CNT_UNIQUE_KEY,
                           &pRmdObject->rcvRecContainerHandle);
    if (CL_OK != CL_GET_ERROR_CODE(retCode))
    {
        RMD_DBG1((" RMD  send Hash table creation failed\n"));

        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForRecvHashTable));
        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForSendHashTable));
        CL_FUNC_EXIT();
        return (retCode);
    }
    retCode =
        clCntHashtblCreate(NUMBER_OF_SEND_BUCKETS, sendKeyCompare,
                           sendHashFunction, sendHashDeleteCallBack,
                           sendHashDestroyCallBack, CL_CNT_UNIQUE_KEY,
                           &pRmdObject->sndRecContainerHandle);
    if (CL_OK != CL_GET_ERROR_CODE(retCode))
    {
        RMD_DBG1((" RMD  recv Hash table creation failed\n"));

        IGNORE_RETURN(clCntDelete(pRmdObject->rcvRecContainerHandle));
        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForRecvHashTable));
        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForSendHashTable));
        CL_FUNC_EXIT();
        return (retCode);
    }

    pRmdObject->responseCntxtDbHdl = 0;
    retCode = clHandleDatabaseCreate(NULL, &pRmdObject->responseCntxtDbHdl);
    if (retCode != CL_OK)
    {
        RMD_DBG1((" RMD  Sync Handle Database create failed\n"));
        IGNORE_RETURN(clCntDelete(pRmdObject->sndRecContainerHandle));
        IGNORE_RETURN(clCntDelete(pRmdObject->rcvRecContainerHandle));
        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForRecvHashTable));
        IGNORE_RETURN(clOsalMutexDelete(pRmdObject->semaForSendHashTable));

        CL_FUNC_EXIT();
        return retCode;
    }

    pRmdObject->numAtmostOnceEntry = 0;
    pRmdObject->lastAtmostOnceCleanupTime = clOsalStopWatchTimeGet();
    pRmdObject->rmdStats.nRmdCalls = 0;
    pRmdObject->rmdStats.nFailedCalls = 0;
    pRmdObject->rmdStats.nResendRequests = 0;
    pRmdObject->rmdStats.nRmdReplies = 0;
    pRmdObject->rmdStats.nBadReplies = 0;
    pRmdObject->rmdStats.nRmdRequests = 0;
    pRmdObject->rmdStats.nBadRequests = 0;
    pRmdObject->rmdStats.nCallTimeouts = 0;
    pRmdObject->rmdStats.nDupRequests = 0;
    pRmdObject->rmdStats.nAtmostOnceCalls = 0;
    pRmdObject->rmdStats.nResendReplies = 0;
    pRmdObject->rmdStats.nReplySend = 0;
    pRmdObject->rmdStats.nRmdCallOptimized = 0;
    *p = (ClRmdObjHandleT) pRmdObject;
    CL_FUNC_EXIT();
    return (CL_OK);
}
/**
 *  Creates a new Extended State machine Instance.
 *
 *  This API creates a new Extended State macine Instance of given
 *  state machine type.  The extended state machine shall include
 *  all the regular state machine instance functionalities, plus
 *  additional event queue, history, and lock capabilities.
 *                                                                        
 *  @param sm       State machine type 
 *  @param instance [out] newly created extended state machine instance
 *
 *  @returns 
 *    CL_OK on CL_OK <br/>
 *    CL_SM_RC(CL_ERR_NO_MEMORY) on memory allocation FAILURE <br/>
 *    CL_SM_RC(CL_ERR_NULL_POINTER) on invalid/null sm / instance <br/>
 *
 *  @see #clEsmInstanceDelete
 */
ClRcT
clEsmInstanceCreate(ClSmTemplatePtrT sm, 
                  ClExSmInstancePtrT* instance
                  )
{
  ClRcT ret = CL_OK;

  CL_FUNC_ENTER();
  CL_ASSERT(instance);  
  CL_ASSERT(sm);  

  clLogTrace(ESM_LOG_AREA,ESM_LOG_CTX_CREATE,"Create Extended State Machine Instance");

  if(sm && instance) 
    {
      /* allocate the instance space */
      *instance = (ClExSmInstancePtrT) mALLOC(sizeof(ClExSmInstanceT));
      if(*instance!=0) 
        {
          memset(*instance, 0, sizeof(ClExSmInstanceT));
          /* call sm create here */
          ret = clSmInstanceCreate(sm, &(*instance)->fsm);
          if(ret == CL_OK)
            {
              ret = clOsalMutexCreate(&(*instance)->lock);
              if (CL_OK != ret)
              {
                  clSmInstanceDelete((*instance)->fsm);
                  mFREE(*instance);
                  ret = SM_ERR_NO_SEMA;
              }
              else
              {
              /* create queue and init */
              ret = SMQ_CREATE((*instance)->q);
              if(ret == CL_OK)
                {
                  /* init log buffer */
                  ESM_LOG_INIT((*instance)->log, ESM_LOG_ENTRIES);
                }
              if(!(*instance)->log.buffer || ret != CL_OK)
                {
                  /* delete the instance */
                  ret = clSmInstanceDelete((*instance)->fsm);
                  /* delete the mutex */
                  clOsalMutexDelete((*instance)->lock);
                  /* check if q init succeeded */
                  if(ret == CL_OK)
                    {
                      /* delete the queue */
                      clQueueDelete(&((*instance)->q));
                    }
                  /* free the instance */
                  mFREE(*instance);
                  ret = CL_SM_RC(CL_ERR_NO_MEMORY);
                }
              }
            }
          
        } else 
          {
            ret = CL_SM_RC(CL_ERR_NO_MEMORY);
          }
    } else 
      {
        ret = CL_SM_RC(CL_ERR_NULL_POINTER);
      }
  
  CL_FUNC_EXIT();
  return ret;
}