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; }