ClRcT clTimerStop (ClTimerHandleT timerHandle) { /* make sure the timer actually exists */ ClRcT returnCode = CL_ERR_INVALID_HANDLE; TsTimer_t* pUserTimer = NULL; CL_FUNC_ENTER(); pUserTimer = (TsTimer_t*) timerHandle; if (pUserTimer == NULL) { /* debug message */ returnCode = CL_TIMER_RC(CL_ERR_INVALID_HANDLE); clDbgCodeError(returnCode, ("Bad timer handle")); CL_FUNC_EXIT(); return (returnCode); } if (pUserTimer->state == TIMER_FREE) { returnCode = CL_TIMER_RC(CL_TIMER_ERR_INVALID_TIMER); clDbgCodeError(returnCode, ("Attempt to stop a deleted timer.")); CL_FUNC_EXIT(); return (returnCode); } /* if the timer is active, remove it from the active-timers queue */ if (pUserTimer->state == TIMER_ACTIVE) { returnCode = clOsalMutexLock (gActiveTimerQueue.timerMutex); if (returnCode != CL_OK) { CL_FUNC_EXIT(); return (returnCode); } returnCode = tsActiveTimerDequeue (pUserTimer); if (returnCode != CL_OK) { if(CL_OK != clOsalMutexUnlock (gActiveTimerQueue.timerMutex)) { CL_FUNC_EXIT(); return(returnCode); } CL_FUNC_EXIT(); return (returnCode); } returnCode = clOsalMutexUnlock (gActiveTimerQueue.timerMutex); if (returnCode != CL_OK) { CL_FUNC_EXIT(); return (returnCode); } } /* mark the timer as inactive */ pUserTimer->state = TIMER_INACTIVE; CL_FUNC_EXIT(); return (CL_OK); }
ClRcT clTimerDelete (ClTimerHandleT* pTimerHandle) { TsTimer_t* pUserTimer = NULL; ClRcT returnCode = CL_ERR_INVALID_HANDLE; CL_FUNC_ENTER(); if (NULL == pTimerHandle) { returnCode = CL_TIMER_RC(CL_ERR_NULL_POINTER); clDbgCodeError(returnCode, ("Bad timer handle storage")); CL_FUNC_EXIT(); return (returnCode); } pUserTimer = (TsTimer_t*) *pTimerHandle; if (pUserTimer == NULL) { returnCode = CL_TIMER_RC(CL_ERR_INVALID_HANDLE); clDbgCodeError(returnCode, ("Bad timer handle")); CL_FUNC_EXIT(); return (returnCode); } if (pUserTimer->state == TIMER_FREE) { returnCode = CL_TIMER_RC(CL_TIMER_ERR_INVALID_TIMER); clDbgCodeError(returnCode, ("Double delete of a timer")); CL_FUNC_EXIT(); return (returnCode); } /* if timer is active, remove it from the active-timers queue */ returnCode = clTimerStop (*pTimerHandle); if (returnCode != CL_OK) { CL_DEBUG_PRINT (CL_DEBUG_WARN, ("\nTimer delete failed")); CL_FUNC_EXIT(); return (returnCode); } /* null out all the values */ pUserTimer->fpTimeOutAction = NULL; pUserTimer->pActionArgument = NULL; pUserTimer->state = TIMER_FREE; pUserTimer->pNextActiveTimer = NULL; /* valid only for active timers */ pUserTimer->pPreviousActiveTimer = NULL; /* valid only for active timers */ /* return timer to the free pool */ tsFreeTimerReturn (pUserTimer); *pTimerHandle = NULL; CL_FUNC_EXIT(); return (CL_OK); }
ClRcT cosPosixSemCreate (ClUint8T* pName, ClUint32T count, ClOsalSemIdT* pSemId) { ClInt32T rc = CL_OK; sem_t *pSem = NULL; ClInt32T semValue = 0; ClInt32T i = 0; nullChkRet(pSemId); nullChkRet(pName); CL_FUNC_ENTER(); if ((count == 0) || count > CL_SEM_MAX_VALUE) { rc = CL_OSAL_RC(CL_ERR_INVALID_PARAMETER); clDbgCodeError(rc, ("Number of semaphores to create (count) [%d] must be between [1] and [%d]", count, CL_SEM_MAX_VALUE)); CL_FUNC_EXIT(); return(rc); } pSem = sem_open((ClCharT*)pName, O_CREAT, 0777, count); if(pSem == SEM_FAILED) { rc = CL_OSAL_RC(CL_ERR_LIBRARY); clDbgCodeError(rc, ("Failed at sem_open. system error code %d.\n", errno)); return rc; } sem_getvalue(pSem, &semValue); if (semValue < (ClInt32T)count) { for (i = semValue; i < (ClInt32T)count; ++i) { sem_post(pSem); } } else { for (i = count; i < semValue; ++i) { sem_wait(pSem); } } *pSemId = *(ClOsalSemIdT*)&pSem; CL_FUNC_EXIT(); return (rc); }
ClRcT clTimerTypeGet (ClTimerHandleT timerHandle, ClUint32T* pTimerType) { /* make sure the timer actually exists */ TsTimer_t* pUserTimer = NULL; ClRcT returnCode; CL_FUNC_ENTER(); pUserTimer = (TsTimer_t*) timerHandle; if (pUserTimer == NULL) { /* debug message */ returnCode = CL_TIMER_RC(CL_ERR_INVALID_HANDLE); clDbgCodeError(returnCode, ("Bad timer handle")); CL_FUNC_EXIT(); return (returnCode); } if (pTimerType == NULL) { CL_FUNC_EXIT(); return (CL_ERR_UNSPECIFIED); } /* extract the timer-type from the timer */ *pTimerType = pUserTimer->type; CL_FUNC_EXIT(); return (CL_OK); }
ClRcT __cosSysvMutexUnlock (ClOsalMutexIdT mutexId, ClBoolT verbose) { ClRcT rc = CL_OK; ClOsalMutexT* pMutex = (ClOsalMutexT*) mutexId; static struct sembuf sembuf = {0, 1, SEM_UNDO }; ClInt32T err = 0; CL_FUNC_ENTER(); retry: err = semop(pMutex->shared_lock.sem.semId,&sembuf,1); if(err < 0) { if(errno == EINTR) { goto retry; } rc = CL_OSAL_RC(CL_ERR_LIBRARY); if(verbose) { clDbgCodeError(rc,("semop unlock returned [%s]\n",strerror(errno))); } } CL_FUNC_EXIT(); return (rc); }
/** * Delete transaction definition */ ClRcT clTxnDefnDelete( CL_IN ClTxnDefnT *pTxnDefn) { CL_FUNC_ENTER(); /* Clean-up all other memory allocated with this transaction */ if (NULL != pTxnDefn) { CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Removing transaction definition. txnId:0x%x:0x%x", pTxnDefn->serverTxnId.txnMgrNodeAddress, pTxnDefn->serverTxnId.txnId)); if(pTxnDefn->jobList) { //clCntAllNodesDelete(pTxnDefn->jobList); /* This can be removed by giving the destroy callback */ clCntDelete(pTxnDefn->jobList); } else { clDbgCodeError(0,("Where did the jobList go?")); } clHeapFree(pTxnDefn); } CL_FUNC_EXIT(); return (CL_OK); }
ClRcT __cosPosixMutexLock (ClOsalMutexIdT mutexId, ClBoolT verbose) { ClRcT rc = CL_OK; ClOsalMutexT *pMutex = (ClOsalMutexT*)mutexId; ClInt32T err=0; if(verbose) { nullChkRet(pMutex); } else if(!pMutex) { return CL_OSAL_RC(CL_ERR_NULL_POINTER); } CL_FUNC_ENTER(); retry: err = sem_wait(&pMutex->shared_lock.sem.posSem); if(err < 0 ) { if(errno == EINTR) goto retry; rc = CL_OSAL_RC(CL_ERR_LIBRARY); if(verbose) { clDbgCodeError(rc,("sem_wait returned [%s]\n",strerror(errno))); } } CL_FUNC_EXIT(); return (rc); }
/** * Delete/free transaction-job definition */ ClRcT clTxnAppJobDelete( CL_IN ClTxnAppJobDefnT *pTxnAppJob) { CL_FUNC_ENTER(); if (NULL == pTxnAppJob) { CL_FUNC_EXIT(); clDbgCodeError(CL_ERR_NULL_POINTER, ("Null pointer on the job list")); return CL_ERR_NULL_POINTER; } CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Deleting txn-job %p", (ClPtrT) pTxnAppJob)); if(pTxnAppJob->compList) { //clCntAllNodesDelete(pTxnAppJob->compList); clCntDelete(pTxnAppJob->compList); } if (pTxnAppJob->appJobDefn) clHeapFree( (ClPtrT) pTxnAppJob->appJobDefn); memset(pTxnAppJob, 0, sizeof(ClTxnAppJobDefnT)); /* to crash uses after delete */ clHeapFree(pTxnAppJob); return (CL_OK); }
ClRcT cosPosixProcessSharedSemInit(ClOsalMutexT *pMutex, ClUint8T *pKey, ClUint32T keyLen, ClInt32T value) { ClRcT rc = CL_OK; int err; nullChkRet(pKey); if(keyLen == 0) { clDbgCodeError(CL_ERR_INVALID_PARAMETER,("Invalid keylen [%d]\n",keyLen)); return CL_OSAL_RC(CL_ERR_INVALID_PARAMETER); } pthread_mutex_lock(&gClSemAccessLock); err = sem_init(&pMutex->shared_lock.sem.posSem,1, value); if(err < 0) { pthread_mutex_unlock(&gClSemAccessLock); rc = CL_OSAL_RC(CL_ERR_LIBRARY); goto out; } pthread_mutex_unlock(&gClSemAccessLock); pMutex->shared_lock.sem.numSems = 1; rc = CL_OK; out: return rc; }
ClRcT cosSysvProcessSharedSemInit(ClOsalMutexT *pMutex, ClUint8T *pKey, ClUint32T keyLen, ClInt32T value) { ClInt32T semId = 0; ClUint32T semKey = 0; ClRcT rc = CL_OK; ClUint32T flags = 0666; ClInt32T err = 0; nullChkRet(pKey); if(keyLen == 0) { clDbgCodeError(CL_ERR_INVALID_PARAMETER,("Invalid keylen [%d]\n",keyLen)); return CL_OSAL_RC(CL_ERR_INVALID_PARAMETER); } rc = clCrc32bitCompute(pKey, keyLen, &semKey, NULL); CL_ASSERT(rc == CL_OK && semKey ); pthread_mutex_lock(&gClSemAccessLock); retry: semId = semget(semKey, 1, flags); if(semId < 0 ) { if(errno == EINTR) goto retry; if(errno == ENOENT) { flags |= IPC_CREAT; goto retry; } pthread_mutex_unlock(&gClSemAccessLock); rc = CL_OSAL_RC(CL_ERR_LIBRARY); goto out; } pthread_mutex_unlock(&gClSemAccessLock); if( (flags & IPC_CREAT) ) { CosSemCtl_t arg = {0}; arg.val = value; retry1: err = semctl(semId,0,SETVAL,arg); if(err < 0 ) { if(errno == EINTR) goto retry1; rc = CL_OSAL_RC(CL_ERR_LIBRARY); goto out; } } pMutex->shared_lock.sem.semId = semId; pMutex->shared_lock.sem.numSems = 1; rc = CL_OK; out: return rc; }
ClRcT cosSysvSemCreate (ClUint8T* pName, ClUint32T count, ClOsalSemIdT* pSemId) { ClInt32T retCode = CL_OK; CosSemCtl_t semArg = {0}; ClUint32T len = 0; ClUint32T key = 0; ClInt32T semId = -1; nullChkRet(pSemId); nullChkRet(pName); CL_FUNC_ENTER(); if ((count == 0) || count > CL_SEM_MAX_VALUE) { retCode = CL_OSAL_RC(CL_ERR_INVALID_PARAMETER); clDbgCodeError(retCode, ("Number of semaphores to create (count) [%d] must be between [1] and [%d]", count, CL_SEM_MAX_VALUE)); CL_FUNC_EXIT(); return(retCode); } len = (ClUint32T)strlen ((ClCharT*)pName); #if 0 /* Stone: why this limitation? */ if(len > 20) if(len > 256) { CL_DEBUG_PRINT (CL_DEBUG_INFO,("Sanity check, semaphore name length is suspiciously long")); retCode = CL_OSAL_RC(CL_OSAL_ERR_NAME_TOO_LONG); CL_FUNC_EXIT(); return(retCode); } #endif if(len > 256) { CL_DEBUG_PRINT (CL_DEBUG_INFO,("Sanity check, semaphore name [%s] is suspiciously long",pName)); } retCode = (ClInt32T)clCrc32bitCompute (pName, len, &key, NULL); CL_ASSERT(retCode == CL_OK); /* There is no possible error except for pName == NULL, which I've already checked, so don't check the retCode */ sysErrnoChkRet(semId = semget ((key_t)key, (int)count, IPC_CREAT|0666)); semArg.val = (int)count; /* Initialize all the semaphores to 0. This should never fail, because I just created the semaphores */ sysErrnoChkRet(semctl (semId, 0, SETVAL, semArg)); *pSemId = (ClOsalSemIdT)semId; CL_FUNC_EXIT(); return (CL_OK); }
ClRcT cosPosixMutexValueSet(ClOsalMutexIdT mutexId, ClInt32T value) { ClRcT rc = CL_OSAL_RC(CL_ERR_NOT_SUPPORTED); CL_FUNC_ENTER(); clDbgCodeError(rc, ("POSIX semaphores dont support setval operations\n")); CL_FUNC_EXIT(); return rc; }
ClRcT cosSysvMutexDestroy (ClOsalMutexT *pMutex) { ClRcT rc = CL_OK; ClInt32T err; CL_FUNC_ENTER(); err = semctl(pMutex->shared_lock.sem.semId,0,IPC_RMID,0); if(err < 0 ) { rc = CL_OSAL_RC(CL_ERR_LIBRARY); clDbgCodeError(CL_ERR_LIBRARY,("semctl returned [%s]\n",strerror(errno))); } CL_FUNC_EXIT(); return (rc); }
ClRcT __cosPosixMutexUnlock (ClOsalMutexIdT mutexId, ClBoolT verbose) { ClRcT rc = CL_OK; ClUint32T retCode = 0; ClOsalMutexT* pMutex = (ClOsalMutexT*) mutexId; ClInt32T err = 0; CL_FUNC_ENTER(); if (NULL == pMutex) { retCode = CL_OSAL_RC(CL_ERR_NULL_POINTER); if(verbose) { clLogError(CL_LOG_AREA_UNSPECIFIED, CL_LOG_CONTEXT_UNSPECIFIED,"Mutex Unlock : FAILED, mutex is NULL (used after delete?)"); clDbgPause(); } CL_FUNC_EXIT(); return(retCode); } retry: err = sem_post(&pMutex->shared_lock.sem.posSem); if(err < 0) { if(errno == EINTR) { goto retry; } rc = CL_OSAL_RC(CL_ERR_LIBRARY); if(verbose) { clDbgCodeError(rc,("sem_post unlock returned [%s]\n",strerror(errno))); } } CL_FUNC_EXIT(); return (rc); }
ClRcT cosPosixMutexDestroy (ClOsalMutexT *pMutex) { ClRcT rc = CL_OK; ClUint32T retCode = 0; CL_FUNC_ENTER(); if (NULL == pMutex) { clLogError(CL_LOG_AREA_UNSPECIFIED, CL_LOG_CONTEXT_UNSPECIFIED,"Mutex Destroy failed, mutex is NULL (double delete?)"); retCode = CL_OSAL_RC(CL_ERR_NULL_POINTER); CL_FUNC_EXIT(); return(retCode); } ClInt32T err = sem_destroy(&pMutex->shared_lock.sem.posSem); if(err < 0 ) { rc = CL_OSAL_RC(CL_ERR_LIBRARY); clDbgCodeError(CL_ERR_LIBRARY,("sem_destroy() returned [%s]\n",strerror(errno))); } CL_FUNC_EXIT(); return (rc); }
ClRcT clHandleCheckin( ClHandleDatabaseHandleT databaseHandle, ClHandleT handle) { ClRcT rc = CL_OK; void *instance = NULL; ClHdlDatabaseT *hdbp = (ClHdlDatabaseT*) databaseHandle; ClRcT ec = CL_OK; ClInt32T refcount = 0; hdlDbValidityChk(hdbp); /* sometimes people want to create the same handle across multiple nodes hdlValidityChk(handle,hdbp); */ handle = CL_HDL_IDX(handle); /* once we've verified it, we only care about the index */ /* * Decrementing handle to ensure the non-zero handle interface. */ if (CL_HANDLE_INVALID_VALUE == handle--) { clLogError(CL_HDL_AREA, CL_HDL_CTX_CHECKIN, "Passed handle [%p:%#llX] is invalid", (ClPtrT) hdbp, handle); return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); /* 0 no longer allowed */ } ec = pthread_mutex_lock(&hdbp->mutex); if (ec != 0) { int err = errno; clDbgCodeError(CL_HANDLE_RC(CL_ERR_MUTEX_ERROR), ("Handle database mutex lock failed error: %s (%d)", strerror(err), err) ); return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); } if (handle >= (ClHandleT)hdbp->n_handles) { pthread_mutex_unlock( &hdbp->mutex); clLogError(CL_HDL_AREA, CL_HDL_CTX_CHECKIN,"Passed handle [%p:%#llX] is invalid handle", (ClPtrT) hdbp, handle); return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); } refcount = hdbp->handles[handle].ref_count; if( (--refcount <= 0) && (hdbp->handles[handle].state != HANDLE_STATE_PENDINGREMOVAL) ) { pthread_mutex_unlock( &hdbp->mutex); clLogError(CL_HDL_AREA, CL_HDL_CTX_CHECKIN, "There is no balance between checkout, checkin for handle [%p:%#llX]", (ClPtrT) hdbp, (handle + 1)); return CL_HANDLE_RC(CL_ERR_INVALID_STATE); } CL_ASSERT(hdbp->handles[handle].ref_count > 0); // unsigned compare (CID 196 on #1780) hdbp->handles[handle].ref_count -= 1; if (hdbp->handles[handle].ref_count == 0) { instance = (hdbp->handles[handle].instance); if (hdbp->handle_instance_destructor != NULL) { hdbp->handle_instance_destructor(instance); } if (hdbp->handles[handle].flags & HANDLE_ALLOC_FLAG) /* Clean up the handle if we allocated it */ clHeapFree(instance); memset(&hdbp->handles[handle], 0, /* This also makes entry EMPTY */ sizeof(ClHdlEntryT)); CL_ASSERT(hdbp->n_handles_used > 0); // unsigned compare (CID 196 on #1780) hdbp->n_handles_used--; } ec = pthread_mutex_unlock(&hdbp->mutex); if (ec != 0) { int err = errno; clDbgCodeError(CL_HANDLE_RC(CL_ERR_MUTEX_ERROR), ("Handle database mutex unlock failed error: %s (%d)", strerror(err), err) ); return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */ } /* This check to avoid recursive call from LogClient */ if( refcount > 0 ) { #if 0 clLogTrace(CL_HDL_AREA, CL_HDL_CTX_CHECKIN, "Checkin for handle [%p:%#llX]", (ClPtrT) hdbp, (handle + 1)); #endif } return rc; }
ClRcT clTimerStart (ClTimerHandleT timerHandle) { ClRcT returnCode = CL_ERR_INVALID_HANDLE; TsTimer_t* pUserTimer = NULL; CL_FUNC_ENTER(); /* make sure the timer actually exists */ pUserTimer = (TsTimer_t*) timerHandle; if (pUserTimer == NULL) { /* debug message */ returnCode = CL_TIMER_RC(CL_ERR_INVALID_HANDLE); clDbgCodeError(returnCode, ("Bad timer handle")); CL_FUNC_EXIT(); return (returnCode); } if (pUserTimer->state == TIMER_FREE) { returnCode = CL_TIMER_RC(CL_TIMER_ERR_INVALID_TIMER); clDbgCodeError(returnCode, ("Attempt to start deleted timer.")); CL_FUNC_EXIT(); return (returnCode); } if (pUserTimer->fpTimeOutAction == NULL) { /* user has probably deleted the timer! otherwise there's some other corruption! */ returnCode = CL_TIMER_RC(CL_TIMER_ERR_INVALID_TIMER); clDbgCodeError(returnCode, ("Attempt to start deleted or corrupt timer.")); CL_FUNC_EXIT(); return (returnCode); } if (pUserTimer->state == TIMER_ACTIVE) { returnCode = CL_TIMER_RC(CL_TIMER_ERR_INVALID_TIMER); clDbgCodeError(returnCode, ("Attempt to start an already started timer.")); CL_FUNC_EXIT(); return (returnCode); } /* mark timer as active */ pUserTimer->state = TIMER_ACTIVE; returnCode = clOsalMutexLock (gActiveTimerQueue.timerMutex); if (returnCode != CL_OK) { /* debug message */ CL_FUNC_EXIT(); return (returnCode); } /* put it on the active timer's queue */ pUserTimer->timestamp = currentTime+pUserTimer->timeInterval; pUserTimer->timestamp += skew/(iteration?iteration:1)/CL_TIMER_TICK_USECS; returnCode = tsActiveTimerEnqueue (pUserTimer); if (returnCode != CL_OK) { /* debug message */ if (CL_OK != clOsalMutexUnlock (gActiveTimerQueue.timerMutex)) { CL_FUNC_EXIT(); return(returnCode); } CL_FUNC_EXIT(); return (returnCode); } returnCode = clOsalMutexUnlock (gActiveTimerQueue.timerMutex); if (returnCode != CL_OK) { /* debug message */ CL_FUNC_EXIT(); return (returnCode); } CL_FUNC_EXIT(); return (CL_OK); }
ClRcT clHandleDestroy ( ClHandleDatabaseHandleT databaseHandle, ClHandleT handle) { ClHdlDatabaseT *hdbp = (ClHdlDatabaseT*) databaseHandle; ClRcT ec = CL_OK; hdlDbValidityChk(hdbp); handle = CL_HDL_IDX(handle); /* once we've verified it, we only care about the index */ /* * Decrementing handle to ensure the non-zero handle interface. */ if (CL_HANDLE_INVALID_VALUE == handle--) { clLogError("HDL", CL_LOG_CONTEXT_UNSPECIFIED, "Passed handle [%p:%#llX] is invalid", (ClPtrT) hdbp, handle); return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); /* 0 no longer allowed */ } /* Verify this particular handle has been already created */ if( (NULL == hdbp->handles) || (0 == hdbp->n_handles_used) ) { clLogError("HDL", CL_LOG_CONTEXT_UNSPECIFIED, "Invalid attempt to delete the non exiting handle [%p:%#llX]", (ClPtrT) hdbp, handle); return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); } ec = pthread_mutex_lock (&hdbp->mutex); if (ec != 0) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); } if (handle >= (ClHandleT)hdbp->n_handles) { ec = pthread_mutex_unlock (&hdbp->mutex); if (ec != 0) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */ } clLogError("HDL", CL_LOG_CONTEXT_UNSPECIFIED, "Passed handle [%p:%#llX] has not been created", (ClPtrT) hdbp, handle); return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); } clDbgResourceNotify(clDbgHandleResource, clDbgRelease, hdbp, handle+1, ("Handle [%p:%#llX] (state: %d, ref: %d) released", (ClPtrT)hdbp, handle+1,hdbp->handles[handle].state,hdbp->handles[handle].ref_count)); if (HANDLE_STATE_USED == hdbp->handles[handle].state) { hdbp->handles[handle].state = HANDLE_STATE_PENDINGREMOVAL; ec = pthread_mutex_unlock (&hdbp->mutex); if (ec != 0) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */ } /* * Adding 1 to handle to ensure the non-zero handle interface. */ ec = clHandleCheckin (databaseHandle, handle+1); return ec; } else if (HANDLE_STATE_EMPTY == hdbp->handles[handle].state) { ec = CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); } else if (HANDLE_STATE_PENDINGREMOVAL == hdbp->handles[handle].state) { ec = pthread_mutex_unlock( &hdbp->mutex); if( ec != 0 ) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */ } clLogWarning(CL_HDL_AREA, CL_HDL_CTX_DESTROY, "Destroy has been called for this handle [%p:%#llX]" "returning CL_OK", (ClPtrT) hdbp, (handle + 1)); return CL_OK; } else { clDbgCodeError(CL_ERR_INVALID_HANDLE, ("Passed handle [%p:%#llX] doesn't have any proper state," "corrupted code", (ClPtrT) hdbp, (handle + 1))); /* * Invalid state - this musn't happen! */ } if(pthread_mutex_unlock (&hdbp->mutex) != 0) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */ } #if 0 clLogTrace(CL_HDL_AREA, CL_HDL_CTX_DESTROY, "Handle [%p:%#llX] has been deleted successfully", (ClPtrT) hdbp, (handle + 1)); #endif return ec; }
ClRcT clHandleCheckout( ClHandleDatabaseHandleT databaseHandle, ClHandleT handleArg, void **instance) { ClRcT rc = CL_OK; ClHdlDatabaseT *hdbp = (ClHdlDatabaseT*)databaseHandle; ClHdlStateT state = HANDLE_STATE_EMPTY; ClRcT ec = CL_OK; ClHandleT handle; hdlDbValidityChk(hdbp); /* sometimes people want to create the same handle across multiple nodes hdlValidityChk(handle,hdbp); */ handle = CL_HDL_IDX(handleArg); /* once we've verified it, we only care about the index */ nullChkRet(instance); /* * Decrementing handle to ensure the non-zero handle interface. */ if (CL_HANDLE_INVALID_VALUE == handle--) { clDbgCodeError(CL_HANDLE_RC(CL_ERR_INVALID_HANDLE), ("Passed Invalid Handle [0x0]")); return CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); /* 0 no longer allowed */ } ec = pthread_mutex_lock (&hdbp->mutex); if (ec != 0) { return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); } if (handle >= (ClHandleT)hdbp->n_handles) { rc = CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); pthread_mutex_unlock(&hdbp->mutex); clDbgCodeError(rc, ("Passed Invalid Handle [%p:%#llx]", (ClPtrT) hdbp, handleArg)); return rc; } if ( ( state = hdbp->handles[handle].state ) != HANDLE_STATE_USED) { pthread_mutex_unlock(&hdbp->mutex); if (state == HANDLE_STATE_EMPTY) { /* In some of our ASP components the assumption made, * like checkout handle returns CL_ERR_INVALID_HANDLE * to verify the handle does exist or not. * so removing the debug pause */ #if 0 clDbgCodeError(rc, ("Handle [%p:%#llX] is not allocated", (ClPtrT) hdbp, (handle+1))); #endif } else if (state == HANDLE_STATE_PENDINGREMOVAL) { clDbgCodeError(rc, ("Handle [%p:%#llX] is being removed", (ClPtrT) hdbp, handleArg)); } else { clDbgCodeError(rc, ("Handle [%p:%#llX] invalid state %d", (ClPtrT) hdbp, handleArg, state)); } rc = CL_HANDLE_RC(CL_ERR_INVALID_HANDLE); clDbgCodeError(rc, ("Handle [%p:%#llX] is invalid", (ClPtrT) hdbp, handleArg)); return rc; } *instance = hdbp->handles[handle].instance; hdbp->handles[handle].ref_count += 1; ec = pthread_mutex_unlock (&hdbp->mutex); if (ec != 0) { clDbgCodeError(CL_HANDLE_RC(CL_ERR_MUTEX_ERROR), ("Mutex unlock failed errno %d", errno)); return CL_HANDLE_RC(CL_ERR_MUTEX_ERROR); /* This can be devastating */ } #if 0 clLogTrace(CL_HDL_AREA, CL_HDL_CTX_CHECKOUT, "Checked out handle [%p:%#llX]", (ClPtrT) hdbp, handleArg); #endif return rc; }
/* This function handles msg send request from clients */ static ClRcT clMsgIocRequestHandle(ClEoExecutionObjT *pThis, ClBufferHandleT eoRecvMsg, ClUint8T priority, ClUint8T protoType, ClUint32T length, ClIocPhysicalAddressT srcAddr) { ClRcT rc = CL_OK; ClRcT ret; ClUint32T sendType; ClNameT pDestination; SaMsgMessageT pMessage; ClInt64T sendTime; ClHandleT senderHandle; ClInt64T timeout; ClInt64T msgId; ClUint8T syncType; memset(&(pDestination), 0, sizeof(ClNameT)); memset(&(pMessage), 0, sizeof(SaMsgMessageT)); memset(&(senderHandle), 0, sizeof(ClHandleT)); rc = clXdrUnmarshallClUint32T( eoRecvMsg,&(sendType)); if (CL_OK != rc) { goto out1; } rc = clXdrUnmarshallClNameT( eoRecvMsg,&(pDestination)); if (CL_OK != rc) { goto out1; } rc = clXdrUnmarshallSaMsgMessageT_4_0_0( eoRecvMsg,&(pMessage)); if (CL_OK != rc) { goto out1; } rc = clXdrUnmarshallClInt64T( eoRecvMsg,&(sendTime)); if (CL_OK != rc) { goto out1; } rc = clXdrUnmarshallClHandleT( eoRecvMsg,&(senderHandle)); if (CL_OK != rc) { goto out1; } rc = clXdrUnmarshallClInt64T( eoRecvMsg,&(timeout)); if (CL_OK != rc) { goto out1; } rc = clXdrUnmarshallClInt64T( eoRecvMsg,&(msgId)); if (CL_OK != rc) { goto out1; } rc = clXdrUnmarshallClUint8T( eoRecvMsg,&(syncType)); if (CL_OK != rc) { goto out1; } /* Call remote function */ ret = VDECL_VER(clMsgMessageReceived, 4, 0, 0)(sendType, &(pDestination), &(pMessage), sendTime, senderHandle, timeout); /* Prepare to send return value to the caller */ ClIocSendOptionT sendOption = { 0 }; ClBufferHandleT replyMsg = NULL; ClUint8T replyProto = CL_IOC_SAF_MSG_REPLY_PROTO; /* Set Ioc send option */ sendOption.msgOption = CL_IOC_PERSISTENT_MSG; sendOption.priority = CL_IOC_DEFAULT_PRIORITY; sendOption.timeout = 10000; /* Create buffer for input message */ rc = clBufferCreate(&replyMsg); if (CL_OK != rc) { clDbgResourceLimitExceeded(clDbgMemoryResource, 0, ("Out of memory")); goto out1; } /* Marshall reply data */ rc = clMsgReplyDataMarshall(replyMsg, ret, msgId, syncType); if (CL_OK != rc) { clDbgCodeError(rc, ("Cannot marshal reply data.")); goto out2; } /* Send return value to the caller */ rc = clIocSend(pThis->commObj, replyMsg, replyProto,(ClIocAddressT *) &srcAddr, &sendOption); if (CL_OK != CL_GET_ERROR_CODE(rc)) { clLogError("MSG", "REPLY", "clIocSend(): error code [0x%x].", rc); } out2: clBufferDelete(&replyMsg); out1: return rc; }
ClRcT clTimerCreate (ClTimerTimeOutT timeOut, /* the timeout, in clockticks */ ClTimerTypeT type, /* one shot or repetitive */ ClTimerContextT timerTaskSpawn, /* whether to spawn off the timer function * as a separate task or invoke it in the * same context as the timer-task */ ClTimerCallBackT fpAction, /* the function to be called on timeout */ void* pActionArgument,/* the argument to the function called on timeout */ ClTimerHandleT* pTimerHandle) /* The pointer to the timer handle */ { TsTimer_t* pUserTimer = NULL; ClRcT errorCode; CL_FUNC_ENTER(); if (fpAction == NULL) { errorCode = CL_TIMER_RC(CL_TIMER_ERR_NULL_TIMER_CALLBACK); clDbgCodeError(errorCode, ("Timer create failed: Null callback function passed")); CL_FUNC_EXIT(); return (errorCode); } if (pTimerHandle == NULL) { errorCode = CL_TIMER_RC(CL_ERR_NULL_POINTER); clDbgCodeError(returnCode, ("Bad timer handle")); CL_FUNC_EXIT(); return (errorCode); } switch (type) { case CL_TIMER_ONE_SHOT: case CL_TIMER_REPETITIVE: break; default: errorCode = CL_TIMER_RC(CL_TIMER_ERR_INVALID_TIMER_TYPE); clDbgCodeError(errorCode,("Timer create failed: Invalid timer type")); CL_FUNC_EXIT(); return (errorCode); } switch (timerTaskSpawn) { case CL_TIMER_TASK_CONTEXT: case CL_TIMER_SEPARATE_CONTEXT: break; default: errorCode = CL_TIMER_RC(CL_TIMER_ERR_INVALID_TIMER_CONTEXT_TYPE); clDbgCodeError(errorCode,("Timer create failed: Invalid context type")); CL_FUNC_EXIT(); return (errorCode); } /* TBD: ensure that user-timeout is more than timer resolution */ /* allocate a timer from the free pool */ pUserTimer = tsFreeTimerGet (); if (pUserTimer == NULL) { /* debug message */ errorCode = CL_TIMER_RC(CL_ERR_NO_MEMORY); CL_DEBUG_PRINT (CL_DEBUG_WARN, ("\nTimer create failed")); CL_FUNC_EXIT(); return (errorCode); } timeOut.tsSec = timeOut.tsSec + (timeOut.tsMilliSec/1000); timeOut.tsMilliSec = timeOut.tsMilliSec % 1000; /* fill in the appropriate values */ pUserTimer->timeOut.tsSec = timeOut.tsSec; pUserTimer->timeOut.tsMilliSec = timeOut.tsMilliSec; pUserTimer->timeInterval = CL_TIMER_INTERVAL(timeOut); pUserTimer->type = type; /* one-shot/repetitive */ pUserTimer->spawnTask = timerTaskSpawn; pUserTimer->fpTimeOutAction = fpAction; pUserTimer->pActionArgument = pActionArgument; pUserTimer->state = TIMER_INACTIVE; /* active/inactive/free */ pUserTimer->pNextActiveTimer = NULL; /* valid only for active timers */ pUserTimer->pPreviousActiveTimer = NULL; /* valid only for active timers */ /* return handle to the user */ *pTimerHandle = pUserTimer; CL_FUNC_EXIT(); return (CL_OK); }