Esempio n. 1
0
static void sendHashDeleteCallBack(ClCntKeyHandleT userKey,
                                   ClCntDataHandleT userData)
{
    ClRmdRecordSendT *rec = (ClRmdRecordSendT *) userData;
    CL_FUNC_ENTER();
    if (userData)
    {
        /*
         * The check on the flag is a must now since sync
         * path also invokes this code. Added as a fix to
         * Bug - 3748.
         */
        if (rec->flags & CL_RMD_CALL_ASYNC)
        {
            /*
             * cleanup for Async Info 
             */
            if (rec->recType.asyncRec.timerID)
            {
                clTimerDeleteAsync(&rec->recType.asyncRec.timerID);
            }
            
            clHeapFree(rec);
        }
        else
        {
            /* Before destroying the condition variable, make sure it is not being used in clOsalCondWait(). */
            clOsalCondSignal(&rec->recType.syncRec.syncCond);
            /*
             * cleanup for Sync Info
             */
            clOsalCondDestroy(&rec->recType.syncRec.syncCond);
        }
    }

    CL_FUNC_EXIT();
}
static ClRcT rmdSendTimerFunc(void *pData)
{
    ClCntNodeHandleT    nodeHandle;
    ClRmdRecordSendT    *rec         = NULL;
    ClRcT               rc;
    ClRcT               retCode      = 0;
    ClRmdObjT           *pRmdObject;
    ClRmdAsyncCallbackT fpTempPtr;
    void                *cookie;
    ClBufferHandleT     outMsgHdl;
    ClEoExecutionObjT   *pThis       = NULL;
    ClUint64T           msgId        = (ClUint32T)(ClWordT) pData;

    CL_FUNC_ENTER();
    if (pData == NULL)
    {
        return (CL_RMD_RC(CL_ERR_INVALID_BUFFER));
    }
    rc = clEoMyEoObjectGet(&pThis);

    if ( CL_OK != rc )
    {
        return rc;
    }

    pRmdObject = (ClRmdObjT *) (pThis->rmdObj);
    if (pRmdObject == NULL)
    {
        return (CL_RMD_RC(CL_ERR_INVALID_BUFFER));
    }

    rc = clOsalMutexLock(pRmdObject->semaForSendHashTable);
    CL_ASSERT(rc == CL_OK);
    clLogNotice("CALLBACK", "TASKS","Enter rmdSendTimerFunc 0");
    rc = clCntNodeFind(pRmdObject->sndRecContainerHandle, (ClPtrT)(ClWordT)msgId,
                       &nodeHandle);
    if (rc == CL_OK)
    {
        clLogNotice("CALLBACK", "TASKS","Enter rmdSendTimerFunc 1");

        rc = clCntNodeUserDataGet(pRmdObject->sndRecContainerHandle, nodeHandle,
                                  (ClCntDataHandleT *) &rec);
        if (rc == CL_OK)
        {
            clLogNotice("CALLBACK", "TASKS","Enter rmdSendTimerFunc 2");
            if (rec)
            {
                /*
                 * Disabling retries for ASYNC since we dont want
                 * to land up in duplicate send mess as anyway we have
                 * accounted for the retries while creating the async timer.
                 */
                if (0 && rec->recType.asyncRec.noOfRetry > 0)
                {
                    /*
                     * key is part of record so no need to free just reuse
                     */
                    retCode = resendMsg(rec, pRmdObject, pThis);
                }
                else
                {
                    /*
                     * key is part of record so no need to free, it will be
                     * freed by hash delete callback
                     */
                    RMD_STAT_INC(pRmdObject->rmdStats.nCallTimeouts);
                    retCode = clTimerDeleteAsync(&rec->recType.asyncRec.timerID);
                    if (rec->recType.asyncRec.func)
                    {
                        /*
                         * unlocking it as callback func can make the rmd call
                         */
                        ClBufferHandleT message;

                        fpTempPtr = rec->recType.asyncRec.func;
                        cookie = rec->recType.asyncRec.cookie;
                        outMsgHdl = rec->recType.asyncRec.outMsgHdl;
                        message = rec->recType.asyncRec.sndMsgHdl;
                        clBufferHeaderTrim(message, rec->hdrLen);
                        rc = clCntNodeDelete(pRmdObject->sndRecContainerHandle,
                                             nodeHandle);
                        rc = clOsalMutexUnlock(pRmdObject->
                                               semaForSendHashTable);
                        fpTempPtr((CL_RMD_RC(CL_ERR_TIMEOUT)), cookie, message,
                                  outMsgHdl);
                        clBufferDelete(&(message));
                        rc = clOsalMutexLock(pRmdObject->semaForSendHashTable);
                    }
                }
            }
        }
    }

    rc = clOsalMutexUnlock(pRmdObject->semaForSendHashTable);
    CL_ASSERT(rc == CL_OK);
    CL_FUNC_EXIT();
    return CL_OK;

}
/*
 * Paket are added in the record after converting them in the nw order so msgid
 * here is network order. Called with lock held.
 */
ClRcT clRmdCreateAndAddRmdSendRecord(ClEoExecutionObjT *pThis,
                                     ClIocAddressT destAddr,
                                     ClUint32T hdrLen,
                                     ClBufferHandleT outMsgHdl,
                                     ClUint32T flags, ClRmdOptionsT *pOptions,
                                     ClRmdAsyncOptionsT *pAsyncOptions,
                                     ClBufferHandleT message,
                                     ClUint64T msgId, ClUint32T payloadLen,
                                     ClRmdRecordSendT ** ppSendRec)
{
    ClRmdRecordSendT *rec;

    ClRcT retVal = CL_OK;
    ClRcT retCode = 0;

    /*
     * it will be called only for async
     */
    CL_FUNC_ENTER();
    rec = (ClRmdRecordSendT*) clHeapAllocate((ClUint32T) sizeof(ClRmdRecordSendT));
    if (rec == NULL)
    {
        CL_FUNC_EXIT();
        return (CL_RMD_RC(CL_ERR_NO_MEMORY));
    }

    rec->flags = flags;
    rec->hdrLen = hdrLen;
    rec->recType.asyncRec.rcvMsg = NULL;
    rec->recType.asyncRec.outLen = payloadLen;
    rec->recType.asyncRec.priority = pOptions->priority;
    rec->recType.asyncRec.destAddr = destAddr;
    rec->recType.asyncRec.sndMsgHdl = message;
    rec->recType.asyncRec.timerID   = 0;
    rec->recType.asyncRec.outMsgHdl = outMsgHdl;

    /*
     * options can't be 0 as we are creating and passing it
     */
    rec->recType.asyncRec.noOfRetry = pOptions->retries;
    rec->recType.asyncRec.timeout = pOptions->timeout;
    rec->recType.asyncRec.cookie = pAsyncOptions->pCookie;
    rec->recType.asyncRec.func = pAsyncOptions->fpCallback;

    RMD_DBG4((" RMD CALL is Async and reply needed create the timer\n"));
    retVal =
        createAsyncSendTimer(&rec->recType.asyncRec,(ClPtrT)(ClWordT)msgId);

    if (retVal != CL_OK)
    {
        clHeapFree(rec);
        CL_FUNC_EXIT();
        return retVal;

    }

    retVal =
        clCntNodeAdd(((ClRmdObjT *) pThis->rmdObj)->sndRecContainerHandle,
                     (ClPtrT)(ClWordT)msgId, (ClCntDataHandleT) rec, NULL);
    if (retVal == CL_OK) *ppSendRec = rec;
    else
    {
        RMD_DBG4((" RMD  createandaddrec:node add failed1."
                  " Delete timer and return.\n"));

        /*
         * Free the timer additionally for Async Call
         */
        if (flags & CL_RMD_CALL_ASYNC)
            retCode = clTimerDeleteAsync(&rec->recType.asyncRec.timerID);

        clHeapFree(rec);
    }

    CL_FUNC_EXIT();
    return retVal;
}