//------------------------------------------------------------------------------ // Function: ShbIpcStopSignalingNewData // // Description: Stop signaling of new data (called from reading process) // // Parameters: pShbInstance_p pointer to shared buffer instance // // Return: tShbError = error code //------------------------------------------------------------------------------ tShbError ShbIpcStopSignalingNewData(tShbInstance pShbInstance_p) { tShbMemInst *pShbMemInst; tShbMemHeader *pShbMemHeader; tShbError ShbError; INT iRetVal = -1; sem_t* pSemStopSignalingNewData; sem_t* pSemNewData; struct timespec curTime, timeout; if (pShbInstance_p == NULL) { return (kShbInvalidArg); } pShbMemHeader = ShbIpcGetShbMemHeader (pShbInstance_p); pShbMemInst = ShbIpcGetShbMemInst (pShbInstance_p); pSemNewData = &pShbMemHeader->m_semNewData; pSemStopSignalingNewData = &pShbMemHeader->m_semStopSignalingNewData; ShbError = kShbOk; if (!pShbMemInst->m_fNewDataThreadStarted) { ShbError = kShbBufferAlreadyCompleted; goto Exit; } //set termination flag and signal new data to terminate thread pShbMemInst->m_fThreadTermFlag = TRUE; sem_post(pSemNewData); // waiting for thread to terminate clock_gettime(CLOCK_REALTIME, &curTime); timeout.tv_sec = 1; timeout.tv_nsec = TIMEOUT_WAITING_THREAD * 1000; timespecadd(&timeout, &curTime); iRetVal = sem_timedwait(pSemStopSignalingNewData, &timeout); if (iRetVal != 0) { EPL_DBGLVL_ERROR_TRACE3("%s() Stop Sem TIMEOUT %d (%s)\n", __func__, iRetVal, strerror(errno)); } Exit: return (ShbError); }
//------------------------------------------------------------------------------ // Function: ShbIpcStopSignalingNewData // // Description: Stop signaling of new data (called from reading process) // // Parameters: pShbInstance_p pointer to shared buffer instance // // Return: tShbError = error code //------------------------------------------------------------------------------ tShbError ShbIpcStopSignalingNewData(tShbInstance pShbInstance_p) { tShbMemInst *pShbMemInst; tShbMemHeader *pShbMemHeader; tShbError ShbError; INT iRetVal = -1; if (pShbInstance_p == NULL) { return (kShbInvalidArg); } pShbMemHeader = ShbIpcGetShbMemHeader (pShbInstance_p); pShbMemInst = ShbIpcGetShbMemInst (pShbInstance_p); ShbError = kShbOk; if (!pShbMemInst->m_fNewDataThreadStarted) { ShbError = kShbBufferAlreadyCompleted; goto Exit; } //set termination flag and signal new data to terminate thread pShbMemInst->m_fThreadTermFlag = TRUE; semGive(pShbMemHeader->m_semNewData); iRetVal = semTake(pShbMemHeader->m_semStopSignalingNewData, TIMEOUT_WAITING_THREAD); if (iRetVal == ERROR) { EPL_DBGLVL_ERROR_TRACE3("%s() Stop Sem TIMEOUT %d (%s)\n", __func__, iRetVal, strerror(errno)); } Exit: return (ShbError); }
//------------------------------------------------------------------------------ // Function: ShbIpcAllocBuffer // // Description: Allocates memory for the shared buffers // // Parameters: // ulBufferSize_p size of the shared buffer to allocate // pszBufferId_p string containing the shared buffer identifier // ppShbInstance_p pointer to store the instance of this shared // buffer // pfShbNewCreated_p pointer to store the buffer creation flag // // Return: tShbError = error //------------------------------------------------------------------------------ tShbError ShbIpcAllocBuffer (ULONG ulBufferSize_p, const char* pszBufferID_p, tShbInstance* ppShbInstance_p, UINT* pfShbNewCreated_p) { tShbError ShbError; UINT uiBufferKey; BOOL fShbNewCreated; ULONG ulShMemSize; tShbMemHeader* pShbMemHeader; tShbMemInst* pShbMemInst = NULL; tShbInstance pShbInstance; ulShMemSize = ulBufferSize_p + sizeof(tShbMemHeader); //create Buffer Key uiBufferKey = ShbIpcCrc32GetCrc(pszBufferID_p); EPL_DBGLVL_SHB_TRACE4("%s() Allocate %lu Bytes, sBufferID:%s BufferKey:%08x\n", __func__, ulShMemSize, pszBufferID_p, (key_t)uiBufferKey); //--------------------------------------------------------------- // (1) open an existing or create a new shared memory //--------------------------------------------------------------- // try to create shared memory if ((pShbMemHeader = ShbIpcFindMem(uiBufferKey)) == NULL) { fShbNewCreated = TRUE; if ((pShbMemHeader = ShbIpcAlloc(uiBufferKey, ulShMemSize)) == NULL) { //unable to create mem EPL_DBGLVL_ERROR_TRACE1("%s() Shared memory allocation error!\n", __func__); ShbError = kShbOutOfMem; goto Exit; } else { EPL_DBGLVL_SHB_TRACE4("%s() Shared memory allocated, Addr:%p Key:%08x size:%ld\n", __func__, (void *)pShbMemHeader, uiBufferKey, ulShMemSize); } } else { EPL_DBGLVL_SHB_TRACE4("%s() Attached to shared memory, Addr:%p Key:%08x size:%ld\n", __func__, (void *)pShbMemHeader, uiBufferKey, ulShMemSize); fShbNewCreated = FALSE; } //--------------------------------------------------------------- // (2) setup or update header and management information //--------------------------------------------------------------- // allocate a memory block from process specific mempool to save // process local information to administrate/manage the shared buffer if ((pShbMemInst = (tShbMemInst*)ShbIpcAllocPrivateMem(sizeof(tShbMemInst))) == NULL) { EPL_DBGLVL_ERROR_TRACE1("%s() Couldn't alloc private mem!\n", __func__); ShbError = kShbOutOfMem; goto Exit; } //TRACEX("%s() pShbMemInst:%08x\n", __func__, (unsigned int)pShbMemInst); memset(pShbMemInst, 0, sizeof(tShbMemInst)); // reset complete header to default values pShbMemInst->m_SbiMagicID = SBI_MAGIC_ID; pShbMemInst->m_uiSharedMemId = uiBufferKey; strncpy(pShbMemInst->m_sBufId, pszBufferID_p, MAX_LEN_BUFFER_ID - 1); pShbMemInst->m_pfnSigHndlrNewData = NULL; pShbMemInst->m_fNewDataThreadStarted = FALSE; pShbMemInst->m_ulTimeOutMsJobReady = 0; pShbMemInst->m_pfnSigHndlrJobReady = NULL; pShbMemInst->m_pShbMemHeader = pShbMemHeader; pShbMemInst->m_fThreadTermFlag = FALSE; ShbError = kShbOk; if (fShbNewCreated) { memset (pShbMemHeader, 0, sizeof(tShbMemHeader)); // this process was the first who wanted to use the shared memory, // so a new shared memory was created // -> setup new header information inside the shared memory region // itself pShbMemHeader->m_ulShMemSize = ulShMemSize; pShbMemHeader->m_ulRefCount = 1; pShbMemHeader->m_uiBufferKey = uiBufferKey; //create semaphores for buffer access and signal new data if (pthread_mutex_init(&pShbMemHeader->m_mutexBuffAccess, NULL) != 0) { ShbError = kShbOutOfMem; goto Exit; } if (sem_init(&pShbMemHeader->m_semNewData, 0, 0) == -1) { ShbError = kShbOutOfMem; goto Exit; } if (sem_init(&pShbMemHeader->m_semStopSignalingNewData, 0, 0) == -1) { ShbError = kShbOutOfMem; goto Exit; } if (sem_init(&pShbMemHeader->m_semJobReady, 0, 0) == -1) { ShbError = kShbOutOfMem; goto Exit; } } else { // any other process has created the shared memory and this // process has only attached to it // -> check and update existing header information inside the // shared memory region itself if (pShbMemHeader->m_uiBufferKey != uiBufferKey) { EPL_DBGLVL_ERROR_TRACE3("%s() Shared Mem mismatch buffer key %x:%x!\n", __func__, uiBufferKey, pShbMemHeader->m_uiBufferKey); ShbError = kShbOpenMismatch; goto Exit; } //TRACEX("%s() Check mem size is:%ld should be:%ld \n", __func__, pShbMemHeader->m_ulShMemSize, ulShMemSize); if (pShbMemHeader->m_ulShMemSize != ulShMemSize) { EPL_DBGLVL_ERROR_TRACE3("%s() Shared Mem mismatch size! %ld:%ld\n", __func__, ulShMemSize, pShbMemHeader->m_ulShMemSize); ShbError = kShbOpenMismatch; goto Exit; } pShbMemHeader->m_ulRefCount++; } Exit: if (ShbError != kShbOk) { EPL_DBGLVL_ERROR_TRACE2("%s() allocating shared buf failed!\n (%d)", __func__, ShbError); if (pShbMemInst != NULL) { ShbIpcReleasePrivateMem (pShbMemInst); } if ((pShbMemHeader != NULL) && (fShbNewCreated)) { ShbIpcFree(uiBufferKey); } } pShbInstance = (tShbInstance*)pShbMemInst; *pfShbNewCreated_p = fShbNewCreated; *ppShbInstance_p = pShbInstance; return (ShbError); }