/***************************************************************************** PROCEDURE NAME: ncs_saf_free_saamfhealthcheckkeyt DESCRIPTION: Utility function to free "SaAmfHealthcheckKeyT" data structure, when this was malloc'ed by EDU. RETURNS: void *****************************************************************************/ void ncs_saf_free_saamfhealthcheckkeyt(SaAmfHealthcheckKeyT *p) { if (p != NULL) { m_NCS_MEM_FREE(p->key, NCS_MEM_REGION_PERSISTENT, NCS_SERVICE_ID_OS_SVCS, 0); m_MMGR_FREE_EDP_SAAMFHEALTHCHECKKEYT(p); } return; }
/**************************************************************************** * Name : pcs_rda_unreg_callback * * Description : * * * Arguments : PCS_RDA_CB_PTR - Callback function pointer * * Return Values : * * Notes : None *****************************************************************************/ static int pcs_rda_unreg_callback(void *task_cb) { uns32 rc = PCSRDA_RC_SUCCESS; RDA_CALLBACK_CB *rda_callback_cb = NULL; if (!task_cb) return rc; rda_callback_cb = (RDA_CALLBACK_CB *)task_cb; rda_callback_cb->task_terminate = TRUE; /* ** Stop task */ m_NCS_TASK_STOP(rda_callback_cb->task_handle); /* ** Disconnect */ rda_disconnect(rda_callback_cb->sockfd); /* ** Release task */ m_NCS_TASK_RELEASE(rda_callback_cb->task_handle); /* ** Free memory */ m_NCS_MEM_FREE(rda_callback_cb, 0, 0, 0); /* ** Destroy leap */ ncs_leap_shutdown(); /* ** Done */ return rc; }
bool sysfTmrDestroy(void) { SYSF_TMR *tmr; SYSF_TMR *free_tmr; SYSF_TMR_PAT_NODE *tmp = NULL; /* There is only ever one timer per instance */ m_NCS_LOCK(&gl_tcb.safe.free_lock, NCS_LOCK_WRITE); gl_tcb.safe.dmy_free.next = NULL; m_NCS_UNLOCK(&gl_tcb.safe.free_lock, NCS_LOCK_WRITE); m_NCS_LOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); /* Create selection object */ m_NCS_SEL_OBJ_CREATE(&tmr_destroy_syn_obj); tmr_destroying = true; m_NCS_SEL_OBJ_IND(&gl_tcb.sel_obj); /* Unlock the lock */ m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); /* critical region END */ /* Wait on Poll object */ osaf_poll_one_fd(m_GET_FD_FROM_SEL_OBJ(tmr_destroy_syn_obj), 20000); m_NCS_LOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); tmr = &gl_tcb.safe.dmy_keep; while (tmr->keep != NULL) { free_tmr = tmr->keep; tmr->keep = tmr->keep->keep; m_NCS_MEM_FREE(free_tmr, NCS_MEM_REGION_PERSISTENT, NCS_SERVICE_ID_LEAP_TMR, 0); } while ((tmp = (SYSF_TMR_PAT_NODE *)ncs_patricia_tree_getnext(&gl_tcb.tmr_pat_tree, (uint8_t *)0)) != NULL) { ncs_patricia_tree_del(&gl_tcb.tmr_pat_tree, (NCS_PATRICIA_NODE *)tmp); m_NCS_MEM_FREE(tmp, NCS_MEM_REGION_PERSISTENT, NCS_SERVICE_ID_LEAP_TMR, 0); } ncs_patricia_tree_destroy(&gl_tcb.tmr_pat_tree); m_NCS_SEL_OBJ_DESTROY(&gl_tcb.sel_obj); /* Stop the dedicated thread that runs out of ncs_tmr_wait() */ m_NCS_TASK_RELEASE(gl_tcb.p_tsk_hdl); tmr_destroying = false; m_NCS_SEL_OBJ_DESTROY(&tmr_destroy_syn_obj); m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE); /* critical region END */ /* don't destroy the lock (but remember that you could!). * m_NCS_LOCK_DESTROY (&l_tcb.lock); */ m_NCS_LOCK_DESTROY(&gl_tcb.safe.enter_lock); m_NCS_LOCK_DESTROY(&gl_tcb.safe.free_lock); ncs_tmr_create_done = false; return true; }
/**************************************************************************** * Function Name: sysfTmrExpiry * * Purpose: Service all timers that live in this expiry bucket * ****************************************************************************/ static bool sysfTmrExpiry(SYSF_TMR_PAT_NODE *tmp) { SYSF_TMR *now_tmr; SYSF_TMR dead_inst; SYSF_TMR *dead_tmr = &dead_inst; SYSF_TMR *start_dead = &dead_inst; /* get these guys one behind to start as well */ dead_tmr->next = NULL; /* Confirm and secure tmr service is/will persist */ if (ncslpg_take(&gl_tcb.persist) == false) return false; /* going or gone away.. Lets leave */ if (tmr_destroying == true) { /* Raise An indication */ m_NCS_SEL_OBJ_IND(&tmr_destroy_syn_obj); /*If thread canceled here, It had no effect on timer thread destroy */ ncslpg_give(&gl_tcb.persist, 0); /* returns true if thread is going to be destroyed otherwise return false(normal flow) */ return true; } TMR_DBG_TICK(gl_tcb); dead_tmr->next = tmp->tmr_list_start; TMR_SET_CNT(gl_tcb.stats); while (dead_tmr->next != NULL) { /* process old and new */ now_tmr = dead_tmr->next; TMR_INC_CNT(gl_tcb.stats); /* SMM states CREATE, EXPIRED, illegal assert */ if ((TMR_TEST_STATE(now_tmr, TMR_STATE_DORMANT)) || (TMR_TEST_STATE(now_tmr, TMR_STATE_DESTROY))) { TMR_STAT_CANCELLED(gl_tcb.stats); TMR_STAT_ADD_FREE(gl_tcb.stats); TMR_STAT_FREE_HWM(gl_tcb.stats); TMR_DBG_STAMP(now_tmr, gl_tcb.tick); dead_tmr = now_tmr; /* move on to next one */ } else { TMR_SET_STATE(now_tmr, TMR_STATE_DORMANT); /* mark it dormant */ TMR_STAT_EXPIRY(gl_tcb.stats); TMR_STAT_ADD_FREE(gl_tcb.stats); TMR_STAT_FREE_HWM(gl_tcb.stats); TMR_DBG_STAMP(now_tmr, gl_tcb.tick); /* EXPIRY HAPPENS RIGHT HERE !!.................................. */ if (now_tmr->tmrCB != ((TMR_CALLBACK)0x0ffffff)) { #if ENABLE_SYSLOG_TMR_STATS gl_tcb.stats.cnt--; if (gl_tcb.stats.cnt == 0) { syslog(LOG_INFO, "NO Timers Active in Expiry PID %u \n", getpid()); } #endif now_tmr->tmrCB(now_tmr->tmrUarg); /* OK this is it! Expire ! */ } dead_tmr = now_tmr; /* move on to next one */ } } TMR_STAT_RING_HWM(gl_tcb.stats); /* Now replenish the free pool */ if (start_dead->next != NULL) { m_NCS_LOCK(&gl_tcb.safe.free_lock, NCS_LOCK_WRITE); /* critical region START */ dead_tmr->next = gl_tcb.safe.dmy_free.next; /* append old free list to end of that */ gl_tcb.safe.dmy_free.next = start_dead->next; /* put start of collected dead in front */ m_NCS_UNLOCK(&gl_tcb.safe.free_lock, NCS_LOCK_WRITE); /* critical region END */ } ncs_patricia_tree_del(&gl_tcb.tmr_pat_tree, (NCS_PATRICIA_NODE *)tmp); m_NCS_MEM_FREE(tmp, NCS_MEM_REGION_PERSISTENT, NCS_SERVICE_ID_LEAP_TMR, 0); ncslpg_give(&gl_tcb.persist, 0); return false; }
/**************************************************************************** * Name : pcs_rda_reg_callback * * Description : * * * Arguments : PCS_RDA_CB_PTR - Callback function pointer * * Return Values : * * Notes : None *****************************************************************************/ static int pcs_rda_reg_callback(uns32 cb_handle, PCS_RDA_CB_PTR rda_cb_ptr, void **task_cb) { uns32 rc = PCSRDA_RC_SUCCESS; int sockfd = -1; NCS_BOOL is_task_spawned = FALSE; RDA_CALLBACK_CB *rda_callback_cb = NULL; if (*task_cb != NULL) return PCSRDA_RC_CALLBACK_ALREADY_REGD; *task_cb = (long)0; /* ** Connect */ rc = rda_connect(&sockfd); if (rc != PCSRDA_RC_SUCCESS) { return rc; } do { /* ** Init leap */ if (ncs_leap_startup() != NCSCC_RC_SUCCESS) { rc = PCSRDA_RC_LEAP_INIT_FAILED; break; } /* ** Send callback reg request messgae */ rc = rda_callback_req(sockfd); if (rc != PCSRDA_RC_SUCCESS) { break; } /* ** Allocate callback control block */ rda_callback_cb = m_NCS_MEM_ALLOC(sizeof(RDA_CALLBACK_CB), 0, 0, 0); if (rda_callback_cb == NULL) { rc = PCSRDA_RC_MEM_ALLOC_FAILED; break; } memset(rda_callback_cb, 0, sizeof(RDA_CALLBACK_CB)); rda_callback_cb->sockfd = sockfd; rda_callback_cb->callback_ptr = rda_cb_ptr; rda_callback_cb->callback_handle = cb_handle; rda_callback_cb->task_terminate = FALSE; /* ** Spawn task */ if (m_NCS_TASK_CREATE((NCS_OS_CB)rda_callback_task, rda_callback_cb, "RDATASK_CALLBACK", 0, NCS_STACKSIZE_HUGE, &rda_callback_cb->task_handle) != NCSCC_RC_SUCCESS) { m_NCS_MEM_FREE(rda_callback_cb, 0, 0, 0); rc = PCSRDA_RC_TASK_SPAWN_FAILED; break; } if (m_NCS_TASK_START(rda_callback_cb->task_handle) != NCSCC_RC_SUCCESS) { m_NCS_MEM_FREE(rda_callback_cb, 0, 0, 0); m_NCS_TASK_RELEASE(rda_callback_cb->task_handle); rc = PCSRDA_RC_TASK_SPAWN_FAILED; break; } is_task_spawned = TRUE; *task_cb = rda_callback_cb; } while (0); /* ** Disconnect */ if (!is_task_spawned) { ncs_leap_shutdown(); rda_disconnect(sockfd); } /* ** Done */ return rc; }