// protected by timer heap lock static pj_status_t schedule_entry( pj_timer_heap_t *ht, pj_timer_entry *entry, const pj_time_val *future_time, const pj_time_val *delay) { unsigned i = 0; unsigned timer_slot = -1; // Find one empty slot in ht entries for (i = 0; i < MAX_ENTRY_PER_HEAP; i++) { if (ht->entries[i] == NULL) { ht->entries[i] = entry; timer_slot = i; break; } } if (timer_slot >= 0) { // Obtain the next unique sequence number. // Set the entry entry->_timer_id = timer_slot; entry->_timer_value = *future_time; pj_uint32_t ft = PJ_TIME_VAL_MSEC(*delay); PJ_LOG( 5, (THIS_FILE, "Scheduling timer %d of %d in %ld ms", entry->_timer_id, ht->heap_id, ft)); timer_schedule_wrapper((int) entry, get_entry_id(ht, entry), (int) ft); return PJ_SUCCESS; } else { return PJ_ETOOMANY; } }
static int ilo_pkt_dequeue(struct ilo_hwinfo *hw, struct ccb *ccb, int dir, int *id, int *len, void **pkt) { char *fifobar, *desc; int entry = 0, pkt_id = 0; int ret; if (dir == SENDQ) { fifobar = ccb->ccb_u1.send_fifobar; desc = ccb->ccb_u2.send_desc; } else { fifobar = ccb->ccb_u3.recv_fifobar; desc = ccb->ccb_u4.recv_desc; } ret = fifo_dequeue(hw, fifobar, &entry); if (ret) { pkt_id = get_entry_id(entry); if (id) *id = pkt_id; if (len) *len = get_entry_len(entry); if (pkt) *pkt = (void *)(desc + desc_mem_sz(pkt_id)); } return ret; }
// Protected by timer heap lock static int cancel(pj_timer_heap_t *ht, pj_timer_entry *entry, int dont_call) { PJ_CHECK_STACK(); // Check to see if the timer_id is out of range if ( (entry->_timer_id < 0) || (entry->_timer_id > MAX_ENTRY_PER_HEAP) ) { PJ_LOG( 4, (THIS_FILE, "Ask to cancel something already fired or cancelled : %d", entry->_timer_id)); return 0; } PJ_LOG(5, (THIS_FILE, "Cancel timer %d", entry->_timer_id)); // This includes case where the entry is not linked to the heap anymore if (ht->entries[entry->_timer_id] != entry) { PJ_LOG(1, (THIS_FILE, "Cancelling something not linked to this heap : %d", entry->_timer_id)); return 0; } // Note -- due to the fact we rely on android alarm manager, nothing ensure here that cancelCount is actually valid. // Previous checks should do the trick to be sure we have actually 1 cancelled timer here. int cancelCount = timer_cancel_wrapper((int) entry, get_entry_id(ht, entry)); if (cancelCount > 0) { // Free the slot of this entry in ht ht->entries[entry->_timer_id] = NULL; entry->_timer_id = -1; } if (dont_call == 0) { // Call the close hook. (*ht->callback)(ht, entry); } return cancelCount; }