/** * cprGetMutex * * Acquire ownership of a mutex * * Parameters: mutex - Which mutex to acquire * * Return Value: Success or failure indication */ cprRC_t cprGetMutex (cprMutex_t mutex) { int32_t rc; static const char fname[] = "cprGetMutex"; cpr_mutex_t *cprMutexPtr; cprMutexPtr = (cpr_mutex_t *) mutex; if (cprMutexPtr != NULL) { /* * Block until mutex is available so this function will * always return success since if it returns we have * gotten the mutex. */ rc = WaitForSingleObject((HANDLE) cprMutexPtr->u.handlePtr, INFINITE); if (rc != WAIT_OBJECT_0) { CPR_ERROR("%s - Error acquiring mutex: %d\n", fname, rc); return (CPR_FAILURE); } return (CPR_SUCCESS); /* Bad application! */ } else { CPR_ERROR("%s - NULL pointer passed in.\n", fname); return (CPR_FAILURE); } }
/** * cprDestroyThread * * @brief Destroys the thread passed in. * * The cprDestroyThread function is called to destroy a thread. The thread * parameter may be any valid thread including the calling thread itself. * * @param[in] thread - thread to destroy. * * @return CPR_SUCCESS or CPR_FAILURE. errno should be set for FAILURE case. * * @note In Linux there will never be a success indication as the * calling thread will have been terminated. */ cprRC_t cprDestroyThread (cprThread_t thread) { static const char fname[] = "cprDestroyThread"; cpr_thread_t *cprThreadPtr; cprThreadPtr = (cpr_thread_t *) thread; if (cprThreadPtr != NULL) { /* * Make sure thread is trying to destroy itself. */ if (cprThreadPtr->u.handlePtr == (void*) pthread_self()) { cprThreadPtr->threadId = 0; cpr_free(cprThreadPtr); pthread_exit(NULL); return CPR_SUCCESS; } CPR_ERROR("%s: Thread attempted to destroy another thread, not itself.\n", fname); errno = EINVAL; return CPR_FAILURE; } /* Bad application! */ CPR_ERROR("%s - NULL pointer passed in.\n", fname); errno = EINVAL; return CPR_FAILURE; }
/** * cprUpdateTimer * * @brief Updates the expiration time for a running timer * * The cprUpdateTimer function cancels a previously started timer referenced by * the parameter timer and then restarts the same timer with the duration passed * in. * * @param[in] timer - which timer to update * @param[in] duration - how long before timer expires in milliseconds * * @return CPR_SUCCESS or CPR_FAILURE */ cprRC_t cprUpdateTimer (cprTimer_t timer, uint32_t duration) { static const char fname[] = "cprUpdateTimer"; cpr_timer_t *cprTimerPtr; void *timerData; cprTimerPtr = (cpr_timer_t *) timer; if (cprTimerPtr != NULL) { /* Grab data before cancelling timer */ timerData = cprTimerPtr->data; } else { CPR_ERROR("%s - NULL pointer passed in.\n", fname); errno = EINVAL; return CPR_FAILURE; } if (cprCancelTimer(timer) == CPR_SUCCESS) { if (cprStartTimer(timer, duration, timerData) == CPR_SUCCESS) { return CPR_SUCCESS; } else { CPR_ERROR("%s - Failed to start timer %s\n", fname, cprTimerPtr->name); return CPR_FAILURE; } } CPR_ERROR("%s - Failed to cancel timer %s\n", fname, cprTimerPtr->name); return CPR_FAILURE; }
/** * cprIsTimerRunning * * @brief Determine if a timer is active * * This function determines whether the passed in timer is currently active. The * "timer" parameter is the handle returned from a previous successful call to * cprCreateTimer. * * @param[in] timer - which timer to check * * @return True is timer is active, False otherwise */ boolean cprIsTimerRunning (cprTimer_t timer) { static const char fname[] = "cprIsTimerRunning"; cpr_timer_t *cprTimerPtr; timerBlk *timerPtr; //CPR_INFO("istimerrunning(): timer=0x%x\n", timer); cprTimerPtr = (cpr_timer_t *) timer; if (cprTimerPtr != NULL) { timerPtr = (timerBlk *) cprTimerPtr->u.handlePtr; if (timerPtr == NULL) { CPR_ERROR("%s - Timer %s has not been initialized.\n", fname, cprTimerPtr->name); errno = EINVAL; return FALSE; } if (timerPtr->timerActive) { return TRUE; } } else { /* Bad application! */ CPR_ERROR("%s - NULL pointer passed in.\n", fname); errno = EINVAL; } return FALSE; }
/** * cprDestroyThread * * @brief Destroys the thread passed in. * * The cprDestroyThread function is called to destroy a thread. The thread * parameter may be any valid thread including the calling thread itself. * * @param[in] thread - thread to destroy. * * @return CPR_SUCCESS or CPR_FAILURE. errno should be set for FAILURE case. * * @note In Linux there will never be a success indication as the * calling thread will have been terminated. */ cprRC_t cprDestroyThread (cprThread_t thread) { cpr_thread_t *cprThreadPtr; cprThreadPtr = (cpr_thread_t *) thread; if (cprThreadPtr) { /* * Make sure thread is trying to destroy itself. */ if ((pthread_t) cprThreadPtr->u.handleInt == pthread_self()) { CPR_INFO("%s: Destroying Thread %d", __FUNCTION__, cprThreadPtr->threadId); pthread_exit(NULL); return CPR_SUCCESS; } CPR_ERROR("%s: Thread attempted to destroy another thread, not itself.", __FUNCTION__); MOZ_ASSERT(PR_FALSE); errno = EINVAL; return CPR_FAILURE; } CPR_ERROR("%s - NULL pointer passed in.", __FUNCTION__); MOZ_ASSERT(PR_FALSE); errno = EINVAL; return CPR_FAILURE; }
/** * cprDestroyTimer * * @brief Destroys a timer. * * This function will cancel the timer and then destroy it. It sets * all links to NULL and then frees the timer block. * * @param[in] timer - which timer to destroy * * @return CPR_SUCCESS or CPR_FAILURE */ cprRC_t cprDestroyTimer (cprTimer_t timer) { static const char fname[] = "cprDestroyTimer"; cpr_timer_t *cprTimerPtr; cprRC_t rc; //CPR_INFO("cprDestroyTimer:destroying timer=%x\n", timer); cprTimerPtr = (cpr_timer_t *) timer; if (cprTimerPtr != NULL) { rc = cprCancelTimer(timer); if (rc == CPR_SUCCESS) { cprTimerPtr->cprTimerId = 0; cpr_free(cprTimerPtr->u.handlePtr); cpr_free(cprTimerPtr); return CPR_SUCCESS; } else { CPR_ERROR("%s - Cancel of Timer %s failed.\n", fname, cprTimerPtr->name); return CPR_FAILURE; } } /* Bad application! */ CPR_ERROR("%s - NULL pointer passed in.\n", fname); errno = EINVAL; return CPR_FAILURE; }
/* * cprDestroyThread * * Destroys the thread passed in. * * Parameters: thread - thread to destroy. * * Return Value: Success or failure indication. * In CNU there will never be a success * indication as the calling thread will * have been terminated. */ cprRC_t cprDestroyThread(cprThread_t thread) { cprRC_t retCode = CPR_FAILURE; static const char fname[] = "cprDestroyThread"; cpr_thread_t *cprThreadPtr; cprThreadPtr = (cpr_thread_t*)thread; if (cprThreadPtr != NULL) { CWinThread * pCWinThread; uint32_t result = 0; uint32_t waitrc = WAIT_FAILED; pCWinThread = (CWinThread *)((cpr_thread_t *)thread)->u.handlePtr; if (pCWinThread !=NULL) { result = pCWinThread->PostThreadMessage(WM_CLOSE, 0, 0); if(result) { waitrc = WaitForSingleObject(pCWinThread->m_hThread, 60000); } } if (result == 0) { CPR_ERROR("%s - Thread exit failure %d\n", fname, GetLastError()); retCode = CPR_FAILURE; } retCode = CPR_SUCCESS; /* Bad application! */ } else { CPR_ERROR("%s - NULL pointer passed in.\n", fname); retCode = CPR_FAILURE; } cpr_free(cprThreadPtr); return (retCode); };
/** * cprDestroyMutex * * @brief Destroys the mutex passed in. * * The cprDestroyMutex function is called to destroy a mutex. It is the * application's responsibility to ensure that the mutex is unlocked when * destroyed. Unpredictiable behavior will occur if an application * destroys a locked mutex. * * @param[in] mutex - mutex to destroy * * @return CPR_SUCCESS or CPR_FAILURE. errno should be set for CPR_FAILURE. */ cprRC_t cprDestroyMutex (cprMutex_t mutex) { static const char fname[] = "cprDestroyMutex"; cpr_mutex_t *cprMutexPtr; int32_t rc; cprMutexPtr = (cpr_mutex_t *) mutex; if (cprMutexPtr != NULL) { rc = pthread_mutex_destroy(cprMutexPtr->u.handlePtr); if (rc != 0) { CPR_ERROR("%s - Failure destroying Mutex %s: %d\n", fname, cprMutexPtr->name, rc); return CPR_FAILURE; } cprMutexPtr->lockId = 0; cpr_free(cprMutexPtr->u.handlePtr); cpr_free(cprMutexPtr); return CPR_SUCCESS; } /* Bad application! */ CPR_ERROR("%s - NULL pointer passed in.\n", fname); errno = EINVAL; return CPR_FAILURE; }
/** * cprPreInit * * @brief The cprPreInit function IS called from pSIPCC @b before any components are initialized. * * This function @b SHOULD initialize those portions of the CPR that * are needed before applications can start using it. The memory subsystem * (sandbox) is initialized from this routine. * * * @return CPR_SUCCESS or CPR_FAILURE * @note pSIPCC will NOT continue and stop initialization if the return value is CPR_FAILURE. */ cprRC_t cprPreInit (void) { static const char fname[] = "cprPreInit"; int32_t returnCode; /* * Make function reentreant */ if (pre_init_called == TRUE) { return CPR_SUCCESS; } pre_init_called = TRUE; /* * Create message queue list mutex */ returnCode = pthread_mutex_init(&msgQueueListMutex, NULL); if (returnCode != 0) { CPR_ERROR("%s: MsgQueue Mutex init failure %d\n", fname, returnCode); return CPR_FAILURE; } #if CPR_TIMERS_ENABLED returnCode = cpr_timer_pre_init(); if (returnCode != 0) { CPR_ERROR("%s: timer pre init failed %d\n", fname, returnCode); return CPR_FAILURE; } #endif return CPR_SUCCESS; }
/** * cprResumeThread * * Resume execution of a previously suspended thread * * Parameters: thread - which system thread to resume * * Return Value: Success or failure indication */ cprRC_t cprResumeThread(cprThread_t thread) { int32_t returnCode; static const char fname[] = "cprResumeThread"; cpr_thread_t *cprThreadPtr; cprThreadPtr = (cpr_thread_t*)thread; if (cprThreadPtr != NULL) { CWinThread *pCWinThread; pCWinThread = (CWinThread *)cprThreadPtr->u.handlePtr; if (pCWinThread != NULL) { returnCode = pCWinThread->ResumeThread(); if (returnCode == -1) { CPR_ERROR("%s - Resume thread failed: %d\n", fname, GetLastError()); return(CPR_FAILURE); } return(CPR_SUCCESS); } /* Bad application! */ } CPR_ERROR("%s - NULL pointer passed in.\n", fname); return(CPR_FAILURE); };
/** * addTimerToList * Send message to timer service to add the timer pointed by cprTimerPtr * to the list. This routine is just sending IPC message to timer service * but the actual addition is done by timer service using the addTimer function. * This function is only called by CPR functions and is not visible to external * applications. * @param[in] cprTimerPtr - timer pointer * @param[in] duration - timer duration in msec. * @param[in] data - opaque data * @return - CPR_SUCCESS or CPR_FAILURE */ static cprRC_t addTimerToList (cpr_timer_t *cprTimerPtr, uint32_t duration, void *data) { // TODO([email protected]): Put this back in when you figure out why it causes crashes #ifdef CPR_TIMERS_ENABLED timer_ipc_t tmr_cmd = {0}; timer_ipc_t tmr_rsp= {0}; API_ENTER(); CPR_INFO("%s: cprTimerptr=0x%x dur=%d user_data=%p\n", fname, cprTimerPtr, duration, data); tmr_cmd.msg_type = TMR_CMD_ADD; tmr_cmd.u.cmd.timer_ptr = cprTimerPtr; tmr_cmd.u.cmd.user_data_ptr = data; tmr_cmd.u.cmd.duration = duration; //CPR_INFO("%s:sending messge of type=%d\n", fname, tmr_cmd.msg_type); /* simply post a request here to the timer service.*/ if (client_sock != -1) { if (sendto(client_sock, &tmr_cmd, sizeof(timer_ipc_t), 0, (struct sockaddr *)&tmr_serv_addr, sizeof(tmr_serv_addr)) < 0) { CPR_ERROR("Failed to tx IPC msg to timer service, errno = %s %s\n", strerror(errno), fname); API_RETURN(CPR_FAILURE); } } else { CPR_ERROR("can not make IPC connection, client_sock is invalid %s\n", __FUNCTION__); API_RETURN(CPR_FAILURE); } /* * wait for the timer service to excute the request * so that we get result of operation */ if (recvfrom(client_sock, &tmr_rsp, sizeof(timer_ipc_t),0, NULL, NULL) < 0) { //CPR_INFO("error in recving the result error=%s\n", strerror(errno)); API_RETURN(CPR_FAILURE); } else { //CPR_INFO("received response from the timer result=%d\n", tmr_rsp.u.result); API_RETURN(tmr_rsp.u.result); } #else cprAssert(FALSE, CPR_FAILURE); CPR_ERROR("CPR Timers are disabled! %s\n", __FUNCTION__); return CPR_SUCCESS; #endif }
/** * read_timer_cmd * read message received on the IPC from the client * the only messages are timer commands {add, remove} * * @return CPR_SUCCESS or CPR_FAILURE */ static cprRC_t read_timer_cmd () { static const char fname[] = "read_timer_cmd"; int rcvlen; timer_ipc_t tmr_cmd ={0}; cprRC_t ret = CPR_FAILURE; rcvlen =recvfrom(serv_sock, &tmr_cmd, sizeof(timer_ipc_t), 0, NULL, NULL); if (rcvlen > 0) { //CPR_INFO("got message type=%d\n", tmr_cmd.msg_type); switch(tmr_cmd.msg_type) { case TMR_CMD_ADD: //CPR_INFO("request to add timer ptr=%x duration=%d datptr=%x\n", // tmr_cmd.u.cmd.timer_ptr, tmr_cmd.u.cmd.duration, tmr_cmd.u.cmd.user_data_ptr); ret = addTimer(tmr_cmd.u.cmd.timer_ptr,tmr_cmd.u.cmd.duration, (void *)tmr_cmd.u.cmd.user_data_ptr); break; case TMR_CMD_REMOVE: //CPR_INFO("request to remove timer ptr=%x\n", tmr_cmd.u.cmd.timer_ptr); ret = removeTimer(tmr_cmd.u.cmd.timer_ptr); break; default: CPR_ERROR("%s:invalid ipc command = %d\n", tmr_cmd.msg_type); ret = CPR_FAILURE; break; } } else { CPR_ERROR("%s:while reading serv_sock err =%s: Closing Socket..Timers not operational !!! \n", fname, strerror(errno)); (void) close(serv_sock); serv_sock = INVALID_SOCKET; ret = CPR_FAILURE; } /* send the result back */ send_api_result(ret, &tmr_client_addr, sizeof(tmr_client_addr)); return (ret); }
/** * cprCreateMutex * * Creates a mutual exclusion block * * Parameters: name - name of the mutex * * Return Value: Mutex handle or NULL if creation failed. */ cprMutex_t cprCreateMutex (const char *name) { cpr_mutex_t *cprMutexPtr; static char fname[] = "cprCreateMutex"; WCHAR* wname; /* * Malloc memory for a new mutex. CPR has its' own * set of mutexes so malloc one for the generic * CPR view and one for the CNU specific version. */ cprMutexPtr = (cpr_mutex_t *) cpr_malloc(sizeof(cpr_mutex_t)); if (cprMutexPtr != NULL) { /* Assign name if one was passed in */ if (name != NULL) { cprMutexPtr->name = name; } wname = cpr_malloc((strlen(name) + 1) * sizeof(WCHAR)); mbstowcs(wname, name, strlen(name)); cprMutexPtr->u.handlePtr = CreateMutex(NULL, FALSE, wname); cpr_free(wname); if (cprMutexPtr->u.handlePtr == NULL) { CPR_ERROR("%s - Mutex init failure: %d\n", fname, GetLastError()); cpr_free(cprMutexPtr); cprMutexPtr = NULL; } } return cprMutexPtr; }
/** * timerThread * * @brief Timer service thread * * This is the start function for the timer server thread. * * @param[in] data - The data passed in (UNUSED) * * @return This function eventually starts an infinite loop on a "select". */ void *timerThread (void *data) { static const char fname[] = "timerThread"; //CPR_INFO("timerThread:started..\n"); #ifndef HOST #ifndef PTHREAD_SET_NAME #define PTHREAD_SET_NAME(s) do { } while (0) #endif PTHREAD_SET_NAME("CPR Timertask"); #endif /* * Increase the timer thread priority from default priority. * This is required to make sure timers fire with reasonable precision. * * NOTE: always make sure the priority is higher than sip/gsm threads; * otherwise, we must use mutex around the following while loop. */ (void) cprAdjustRelativeThreadPriority(TIMER_THREAD_RELATIVE_PRIORITY); /* get ready to listen for timer commands and service them */ if (start_timer_service_loop() == CPR_FAILURE) { CPR_ERROR("%s: timer service loop failed\n", fname); } return NULL; }
/** * Removes all messages from the queue and then destroy the message queue * * @param msgQueue - message queue to destroy * * @return CPR_SUCCESS or CPR_FAILURE, errno provided */ cprRC_t cprDestroyMessageQueue (cprMsgQueue_t msgQueue) { static const char fname[] = "cprDestroyMessageQueue"; cpr_msg_queue_t *msgq; void *msg; msgq = (cpr_msg_queue_t *) msgQueue; if (msgq == NULL) { /* Bad application! */ CPR_ERROR("%s: Invalid input\n", fname); errno = EINVAL; return CPR_FAILURE; } /* Drain message queue */ msg = cprGetMessage(msgQueue, FALSE, NULL); while (msg != NULL) { cpr_free(msg); msg = cprGetMessage(msgQueue, FALSE, NULL); } /* Remove message queue from list */ pthread_mutex_lock(&msgQueueListMutex); if (msgq == msgQueueList) { msgQueueList = msgq->next; } else { cpr_msg_queue_t *msgql = msgQueueList; while ((msgql->next != NULL) && (msgql->next != msgq)) { msgql = msgql->next; } if (msgql->next == msgq) { msgql->next = msgq->next; } } pthread_mutex_unlock(&msgQueueListMutex); /* Remove message queue mutex */ if (pthread_mutex_destroy(&msgq->mutex) != 0) { CPR_ERROR("%s: Failed to destroy msg queue (%s) mutex: %d\n", fname, msgq->name, errno); } cpr_free(msgq); return CPR_SUCCESS; }
/** * addTimerToList * Send message to timer service to add the timer pointed by cprTimerPtr * to the list. This routine is just sending IPC message to timer service * but the actual addition is done by timer service using the addTimer function. * This function is only called by CPR functions and is not visible to external * applications. * @param[in] cprTimerPtr - timer pointer * @param[in] duration - timer duration in msec. * @param[in] data - opaque data * @return - CPR_SUCCESS or CPR_FAILURE */ static cprRC_t addTimerToList (cpr_timer_t *cprTimerPtr, uint32_t duration, void *data) { static const char fname[] = "addTimerToList"; timer_ipc_t tmr_cmd = {0}; timer_ipc_t tmr_rsp={0}; API_ENTER(); //CPR_INFO("%s: cprTimerptr=0x%x dur=%d user_data=%x\n", // fname, cprTimerPtr, duration, data); tmr_cmd.msg_type = TMR_CMD_ADD; tmr_cmd.u.cmd.timer_ptr = cprTimerPtr; tmr_cmd.u.cmd.user_data_ptr = data; tmr_cmd.u.cmd.duration = duration; //CPR_INFO("%s:sending messge of type=%d\n", fname, tmr_cmd.msg_type); /* simply post a request here to the timer service.*/ if (client_sock != -1) { if (sendto(client_sock, &tmr_cmd, sizeof(timer_ipc_t), 0, (struct sockaddr *)&tmr_serv_addr, sizeof(tmr_serv_addr)) < 0) { CPR_ERROR("Failed to tx IPC msg to timer service, errno = %s %s\n", strerror(errno), fname); API_RETURN(CPR_FAILURE); } } else { CPR_ERROR("can not make IPC connection, client_sock is invalid %s\n", fname); API_RETURN(CPR_FAILURE); } /* * wait for the timer service to excute the request * so that we get result of operation */ if (recvfrom(client_sock, &tmr_rsp, sizeof(timer_ipc_t),0, NULL, NULL) < 0) { //CPR_INFO("error in recving the result error=%s\n", strerror(errno)); API_RETURN(CPR_FAILURE); } else { //CPR_INFO("received response from the timer result=%d\n", tmr_rsp.u.result); API_RETURN(tmr_rsp.u.result); } }
/** * removeTimerFromList * Send message to timer service to remove the timer pointed by cprTimerPtr * from the list. This routine is just sending IPC message to timer service * and the actual removal is done by timer service using the removeTimer function.. * This function is only called by CPR functions and is not visible to external * applications. * * @param[in] cprTimerPtr - pointer to the timer to be removed from the list * @return - CPR_SUCCESS or CPR_FAILURE * */ static cprRC_t removeTimerFromList (cpr_timer_t *cprTimerPtr) { static const char fname[] = "removeTimerFromList"; timer_ipc_t tmr_cmd = {0}; timer_ipc_t tmr_rsp = {0}; API_ENTER(); //CPR_INFO("%s:remove timer from list=0x%x\n",fname, cprTimerPtr); tmr_cmd.msg_type = TMR_CMD_REMOVE; tmr_cmd.u.cmd.timer_ptr = cprTimerPtr; //CPR_INFO("sending messge of type=%d\n", tmr_cmd.msg_type); /* simply post a request here to the timer service.. */ if (client_sock != -1) { if (sendto(client_sock, &tmr_cmd, sizeof(timer_ipc_t), 0, (struct sockaddr *)&tmr_serv_addr, sizeof(tmr_serv_addr)) < 0) { CPR_ERROR("%s:failed to tx IPC Msg to timer service, errno = %s\n", fname, strerror(errno)); API_RETURN(CPR_FAILURE); } } else { CPR_ERROR("%s:client_sock invalid, no IPC connection \n", fname); API_RETURN(CPR_FAILURE); } /* * wait for the timer service to excute the request * so that we get result of operation */ if (recvfrom(client_sock, &tmr_rsp, sizeof(timer_ipc_t),0, NULL, NULL) < 0) { //CPR_INFO("error in recving the result error=%s\n", strerror(errno)); API_RETURN(CPR_FAILURE); } else { //CPR_INFO("received response from the timer result=%d\n", tmr_rsp.u.result); API_RETURN(tmr_rsp.u.result); } }
int SECSock_connect(int appType, char * srvrAddrAndPort, int blockingConnect, int connTimeout, int ipTOS) { CPR_ERROR("SECSock_connect: %d %s %d %d %d\n", appType, srvrAddrAndPort, blockingConnect, connTimeout, ipTOS); return -1; }
/** * @brief Called when the application is done with this system header * * The cprReleaseSysHeader function returns the system header buffer to the * system. * @param[in] syshdr pointer to the sysHdr to be released * * @return none */ void cprReleaseSysHeader (void *syshdr) { if (syshdr == NULL) { CPR_ERROR("cprReleaseSysHeader: Sys header pointer is NULL\n"); return; } cpr_free(syshdr); }
/** * Associate a thread with the message queue * * @param msgQueue - msg queue to set * @param thread - CPR thread to associate with queue * * @return CPR_SUCCESS or CPR_FAILURE * * @note Nothing is done to prevent overwriting the thread ID * when the value has already been set. */ cprRC_t cprSetMessageQueueThread (cprMsgQueue_t msgQueue, cprThread_t thread) { static const char fname[] = "cprSetMessageQueueThread"; cpr_msg_queue_t *msgq; if ((!msgQueue) || (!thread)) { CPR_ERROR("%s: Invalid input\n", fname); return CPR_FAILURE; } msgq = (cpr_msg_queue_t *) msgQueue; if (msgq->thread != 0) { CPR_ERROR("%s: over-writing previously msgq thread name for %s", fname, msgq->name); } msgq->thread = cprGetThreadId(thread); return CPR_SUCCESS; }
/** * send_api_result back to client via a socket sendto operation * @param[in] retVal - value of result * @param[in] addr - address to send the result to * @param[in] len - length of addr */ void send_api_result(cprRC_t retVal, struct sockaddr_un *addr, socklen_t len) { static const char fname[] = "send_api_result"; timer_ipc_t tmr_rsp = {0}; tmr_rsp.msg_type = TMR_RESULT; tmr_rsp.u.result = retVal; if (sendto(serv_sock, &tmr_rsp, sizeof(timer_ipc_t),0, (struct sockaddr *)addr, len) < 0) { CPR_ERROR("%s: error in sending on serv_sock err=%s\n", fname, strerror(errno)); } }
/** * cprCreateThread * * Create a thread * * Parameters: name - name of the thread created * startRoutine - function where thread execution begins * stackSize - size of the thread's stack (IGNORED) * priority - thread's execution priority (IGNORED) * data - parameter to pass to startRoutine * * * Return Value: Thread handle or NULL if creation failed. */ cprThread_t cprCreateThread(const char* name, cprThreadStartRoutine startRoutine, uint16_t stackSize, uint16_t priority, void* data) { cpr_thread_t* threadPtr; static char fname[] = "cprCreateThread"; unsigned long result; CEvent serialize_lock; /* Malloc memory for a new thread */ threadPtr = (cpr_thread_t *)cpr_malloc(sizeof(cpr_thread_t)); if (threadPtr != NULL) { /* Assign name to CPR and CNU if one was passed in */ if (name != NULL) { threadPtr->name = name; } threadPtr->u.handlePtr = AfxBeginThread((AFX_THREADPROC)startRoutine, data, priority, stackSize); if (threadPtr->u.handlePtr != NULL) { PostThreadMessage(((CWinThread *)(threadPtr->u.handlePtr))->m_nThreadID, MSG_ECHO_EVENT, (unsigned long)&serialize_lock, 0); result = WaitForSingleObject(serialize_lock, 1000); serialize_lock.ResetEvent(); } else { CPR_ERROR("%s - Thread creation failure: %d\n", fname, GetLastError()); cpr_free(threadPtr); threadPtr = NULL; } } else { /* Malloc failed */ CPR_ERROR("%s - Malloc for new thread failed.\n", fname); } return(threadPtr); };
/** * cprPreInit * * @brief The cprPreInit function IS called from pSIPCC @b before any components are initialized. * * This function @b SHOULD initialize those portions of the CPR that * are needed before applications can start using it. The memory subsystem * (sandbox) is initialized from this routine. * * * @return CPR_SUCCESS or CPR_FAILURE * @note pSIPCC will NOT continue and stop initialization if the return value is CPR_FAILURE. */ cprRC_t cprPreInit (void) { static const char fname[] = "cprPreInit"; int32_t returnCode; /* * Make function reentreant */ if (pre_init_called == TRUE) { return CPR_SUCCESS; } pre_init_called = TRUE; /* * Do not move memory pre init below. * This initializes the memory sandbox * and must be first thing done here to make sure * allocations succeed. */ if (cpr_memory_mgmt_pre_init(PRIVATE_SYS_MEM_SIZE) != TRUE) { return CPR_FAILURE; } /* * Create message queue list mutex */ returnCode = pthread_mutex_init(&msgQueueListMutex, NULL); if (returnCode != 0) { CPR_ERROR("%s: MsgQueue Mutex init failure %d\n", fname, returnCode); return CPR_FAILURE; } returnCode = cpr_timer_pre_init(); if (returnCode != 0) { CPR_ERROR("%s: timer pre init failed %d\n", fname, returnCode); return CPR_FAILURE; } return CPR_SUCCESS; }
/** * cprAdjustRelativeThreadPriority * * @brief The function sets the relative thread priority up or down by the given value. * * This function is used pSIPCC to set up the thread priority. The values of the * priority range from -20 (Maximum priority) to +19 (Minimum priority). * * @param[in] relPri - nice value of the thread -20 is MAX and 19 is MIN * * @return CPR_SUCCESS or CPR_FAILURE */ cprRC_t cprAdjustRelativeThreadPriority (int relPri) { const char *fname = "cprAdjustRelativeThreadPriority"; if (setpriority(PRIO_PROCESS, 0, relPri) == -1) { CPR_ERROR("%s: could not set the nice..err=%d\n", fname, errno); return CPR_FAILURE; } return CPR_SUCCESS; }
/** * cprReleaseMutex * * Release ownership of a mutex * * Parameters: mutex - Which mutex to release * * Return Value: Success or failure indication */ cprRC_t cprReleaseMutex (cprMutex_t mutex) { static const char fname[] = "cprReleaseMutex"; cpr_mutex_t *cprMutexPtr; cprMutexPtr = (cpr_mutex_t *) mutex; if (cprMutexPtr != NULL) { if (ReleaseMutex(cprMutexPtr->u.handlePtr) == 0) { CPR_ERROR("%s - Error releasing mutex: %d\n", fname, GetLastError()); return (CPR_FAILURE); } return (CPR_SUCCESS); /* Bad application! */ } else { CPR_ERROR("%s - NULL pointer passed in.\n", fname); return (CPR_FAILURE); } }
/** * cprReleaseMutex * * @brief Release ownership of a mutex * * This function unlocks the mutex referenced by the mutex parameter. * @param[in] mutex - Which mutex to release * * @return CPR_SUCCESS or CPR_FAILURE */ cprRC_t cprReleaseMutex (cprMutex_t mutex) { static const char fname[] = "cprReleaseMutex"; cpr_mutex_t *cprMutexPtr; int32_t rc; cprMutexPtr = (cpr_mutex_t *) mutex; if (cprMutexPtr != NULL) { rc = pthread_mutex_unlock((pthread_mutex_t *) cprMutexPtr->u.handlePtr); if (rc != 0) { CPR_ERROR("%s - Error releasing mutex %s: %d\n", fname, cprMutexPtr->name, rc); return CPR_FAILURE; } return CPR_SUCCESS; } /* Bad application! */ CPR_ERROR("%s - NULL pointer passed in.\n", fname); errno = EINVAL; return CPR_FAILURE; }
/** * cprCancelTimer * * @brief Cancels a running timer * * The cprCancelTimer function cancels a previously started timer referenced by * the parameter timer. * * @param[in] timer - which timer to cancel * * @return CPR_SUCCESS or CPR_FAILURE */ cprRC_t cprCancelTimer (cprTimer_t timer) { static const char fname[] = "cprCancelTimer"; timerBlk *timerPtr; cpr_timer_t *cprTimerPtr; cprRC_t rc = CPR_SUCCESS; //CPR_INFO("cprCancelTimer: timer ptr=%x\n", timer); cprTimerPtr = (cpr_timer_t *) timer; if (cprTimerPtr != NULL) { timerPtr = (timerBlk *) cprTimerPtr->u.handlePtr; if (timerPtr == NULL) { CPR_ERROR("%s - Timer %s has not been initialized.\n", fname, cprTimerPtr->name); errno = EINVAL; return CPR_FAILURE; } /* * Ensure timer is active before trying to remove it. * If already inactive then just return SUCCESS. */ if (timerPtr->timerActive) { //CPR_INFO("removing timer from the list=%x\n", timerPtr); rc = removeTimerFromList(timer); } return rc; } /* Bad application! */ CPR_ERROR("%s - NULL pointer passed in.\n", fname); errno = EINVAL; return CPR_FAILURE; }
/* * cprDestroyMutex * * Destroys the mutex passed in. * * Parameters: mutex - mutex to destroy * * Return Value: Success or failure indication */ cprRC_t cprDestroyMutex (cprMutex_t mutex) { cpr_mutex_t *cprMutexPtr; const static char fname[] = "cprDestroyMutex"; cprMutexPtr = (cpr_mutex_t *) mutex; if (cprMutexPtr != NULL) { CloseHandle(cprMutexPtr->u.handlePtr); cpr_free(cprMutexPtr); return (CPR_SUCCESS); /* Bad application! */ } else { CPR_ERROR("%s - NULL pointer passed in.\n", fname); return (CPR_FAILURE); } }
/** * cprStartTimer * * @brief Start a system timer * * The cprStartTimer function starts a previously created timer referenced by * the parameter timer. CPR timer granularity is 10ms. The "timer" input * parameter is the handle returned from a previous successful call to * cprCreateTimer. * * @param[in] timer - which timer to start * @param[in] duration - how long before timer expires in milliseconds * @param[in] data - information to be passed to callback function * * @return CPR_SUCCESS or CPR_FAILURE */ cprRC_t cprStartTimer (cprTimer_t timer, uint32_t duration, void *data) { static const char fname[] = "cprStartTimer"; cpr_timer_t *cprTimerPtr; cprTimerPtr = (cpr_timer_t *) timer; if (cprTimerPtr != NULL) { /* add timer to the list */ return addTimerToList(cprTimerPtr, duration, data); } /* Bad application! */ CPR_ERROR("%s - NULL pointer passed in.\n", fname); errno = EINVAL; return CPR_FAILURE; }
/** * cpr_timer_pre_init * * @brief Initalize timer service and client IPC * * @return CPR_SUCCESS or CPR_FAILURE */ cprRC_t cpr_timer_pre_init (void) { static const char fname[] = "cpr_timer_pre_init"; int32_t returnCode; /* start the timer service first */ returnCode = (int32_t)pthread_create(&timerThreadId, NULL, timerThread, NULL); if (returnCode == -1) { CPR_ERROR("%s: Failed to create Timer Thread : %s\n", fname, strerror(errno)); return CPR_FAILURE; } /* * wait some time so that timer service thread is up * TBD:we should really implement wait on timerthread using condvar. */ cprSleep(1000); return CPR_SUCCESS; }