void sim_timer_set() { // Set callbacks for COMPA and COMPB timers uint32_t nextA = 0, nextB = 0; uint16_t now = sim_tick_counter(); sim_assert(timer_initialised, "timer not initialised"); //-- Calculate time in clock ticks until next timer events if (TIMSK1 & MASK(OCIE1A)) { sim_debug("Timer1 Interrupt A: Enabled"); nextA = (OCR1A - now) & 0xFFFF ; // 0 = No timer; 1-0x10000 = time until next occurrence if ( ! nextA) nextA = 0x10000; } if (TIMSK1 & MASK(OCIE1B)) { sim_debug("Timer1 Interrupt B: Enabled"); nextB = (OCR1B - now) & 0xFFFF; // 0 = No timer; 1-0x10000 = time until next occurrence if ( ! nextB) nextB = 0x10000; } //-- Find the nearest event uint32_t next = nextA; if (nextB && ( ! next || (nextB < next))) next = nextB; //-- Flag the reasons for the next event timer_reason = 0; if (next && next == nextA) timer_reason |= TIMER_OCR1A; if (next && next == nextB) timer_reason |= TIMER_OCR1B; warpTarget = next ; if (time_scale) { // FIXME: We will miss events if they occur like this: // nextA = 0x1000 // nextB = 0x1001 // timer_reason = TIMER_OCR1A // ISR is triggered and finishes at 0x1002 // => Next trigger for B will not occur until NEXT 0x1001 comes around // Need some way to notice a missed trigger. // Maybe store 32-bit tick value for next trigger time for each timer. //-- Convert ticks to microseconds long actual = ((unsigned long)next) * time_scale / (1 US); if ( next && !actual) actual++; if (next) { sim_debug("OCR1A:%04X OCR1B:%04X now=%04X", OCR1A, OCR1B, now ); sim_debug(" next=%u real=%u", next, actual); } //-- Schedule the event schedule_timer(actual); } }
static void random_timer(void *ctx, unsigned long now) { if (random_active > 0 && now == next_noise_collection) { noise_regular(); next_noise_collection = schedule_timer(NOISE_REGULAR_INTERVAL, random_timer, &pool); } }
static void ipmi_wdt_complete(struct ipmi_msg *msg) { if (msg->cmd == IPMI_CMD(IPMI_RESET_WDT) && !msg->user_data) schedule_timer(&wdt_timer, msecs_to_tb( (WDT_TIMEOUT - WDT_MARGIN)*100)); ipmi_free_msg(msg); }
/* * ExecuteTimers: checks to see if any currently pending timers have * gone off, and if so, execute them, delete them, etc, setting the * current_exec_timer, so that we can't remove the timer while its * still executing. * * changed the behavior: timers will not hook while we are waiting. */ void ExecuteTimers (void) { Timeval right_now; Timer * current, *next; int old_from_server = from_server; get_time(&right_now); while (PendingTimers && time_diff(right_now, PendingTimers->time) < 0) { int old_refnum; old_refnum = current_window->refnum; current = PendingTimers; unlink_timer(current); /* Reschedule the timer if necessary */ if (current->events < 0 || (current->events != 1)) { next = clone_timer(current); if (next->events != -1) next->events--; next->time = time_add(next->time, next->interval); schedule_timer(next); } /* * Restore from_server and current_window from when the * timer was registered */ make_window_current_by_refnum(current->window); if (is_server_open(current->server)) from_server = current->server; else if (is_server_open(current_window->server)) from_server = current_window->server; else from_server = NOSERV; /* * If a callback function was registered, then * we use it. If no callback function was registered, * then we use ''parse_line''. */ get_time(&right_now); now = right_now; if (current->callback) (*current->callback)(current->callback_data); else parse_line("TIMER", current->command, current->subargs ? current->subargs : empty_string, 0,0); from_server = old_from_server; make_window_current_by_refnum(old_refnum); delete_timer(current); } }
void hwtimer_arch_unset(short timer) { DEBUG("hwtimer_arch_unset(\033[31m%i\033[0m)\n", timer); native_hwtimer_isset[timer] = 0; schedule_timer(); return; }
void hwtimer_arch_unset(short timer) { DEBUG("hwtimer_arch_unset(%d)\n", timer); native_hwtimer_irq[timer] = 0; native_hwtimer_isset[timer] = 0; schedule_timer(); return; }
void RtxTimer::reschedule_timer(TcpSrc* who,simtime_picosec when){ //fast case only! if (_active_timers.find(who)==_active_timers.end()){ return schedule_timer(who,when); } bool ok = false; if (_timer_to_bucket.find(who)!=_timer_to_bucket.end()){ TimerBucket* bucket = _timer_to_bucket[who]; simtime_picosec now = _eventList().now(), delta = when-now; if (delta>bucket->base) //ok to reschedule here! if (bucket->timers.find(who)!=bucket->timers.end()){ t = bucket->timers[who]; t->when = when; ok = true; } } if (!ok) schedule_timer(who,when); }
void random_ref(void) { if (!random_active) { memset(&pool, 0, sizeof(pool)); /* just to start with */ noise_get_heavy(random_add_heavynoise_bitbybit); random_stir(); next_noise_collection = schedule_timer(NOISE_REGULAR_INTERVAL, random_timer, &pool); } random_active++; }
static int timer_schedule(LuaState *L)/*{{{*/ { struct luatimer *timer = ms_lua_checkclass(L, CLASS, 1); int interval = luaL_checkinteger(L, 2); if (interval <= 0) { return luaL_argerror(L, 2, "interval cannot be negative"); } schedule_timer(timer, interval); return 0; }/*}}}*/
static void pinger_schedule(Pinger pinger) { int next; if (!pinger->interval) { pinger->pending = FALSE; /* cancel any pending ping */ return; } next = schedule_timer(pinger->interval * TICKSPERSEC, pinger_timer, pinger); if (!pinger->pending || next < pinger->next) { pinger->next = next; pinger->pending = TRUE; } }
void hwtimer_arch_set_absolute(unsigned long value, short timer) { DEBUG("hwtimer_arch_set_absolute(%lu, %i)\n", value, timer); ticks2tv(value, &(native_hwtimer[timer].it_value)); DEBUG("hwtimer_arch_set_absolute(): that is at %lu s %lu us\n", (unsigned long)native_hwtimer[timer].it_value.tv_sec, (unsigned long)native_hwtimer[timer].it_value.tv_usec); native_hwtimer_isset[timer] = 1; schedule_timer(); return; }
static void timer1_isr(void) { const uint8_t tr = timer_reason; if ( ! sim_interrupts) { // Interrupts disabled. Schedule another callback in 10us. schedule_timer(10); return; } timer_reason = 0; cli(); #ifdef SIM_DEBUG uint64_t now = now_ns(); static unsigned int cc_1s = 0, prev_1s = 0; if ( ! clock_counter_1s && prev_1s) ++cc_1s; prev_1s = clock_counter_1s; //uint16_t now = sim_tick_counter(); uint64_t real = (now-begin) / 1000; uint64_t avr = cc_1s * 4 + clock_counter_1s; avr *= 250; avr += clock_counter_250ms * 10; avr += clock_counter_10ms; avr *= 1000 ; printf("test: Real: %us %u.%03ums AVR: %us %u.%03ums Real/AVR: %u\n", real / 1000000 , (real % 1000000)/1000 , real % 1000 , avr / 1000000 , (avr % 1000000)/1000 , avr % 1000 , real / (avr?avr:1) ); printf("test: 10ms=%u 250ms=%u 1s=%u total=%luns actual=%luns\n", clock_counter_10ms, clock_counter_250ms, clock_counter_1s, now - begin, now - then, sim_runtime_ns()); //printf(" timer1_isr tick_time=%04X now=%04X delta=%u total=%u\n", // TICK_TIME , now, now_us() - then, (now_us() - begin)/1000000 ) ; then = now; #endif if (tr & TIMER_OCR1A) TIMER1_COMPA_vect(); if (tr & TIMER_OCR1B) TIMER1_COMPB_vect(); sei(); // Setup next timer sim_timer_set(); }
/** * native timer signal handler * * set new system timer, call timer interrupt handler */ void hwtimer_isr_timer() { int i; DEBUG("hwtimer_isr_timer()\n"); i = next_timer; native_hwtimer_isset[next_timer] = 0; schedule_timer(); if (native_hwtimer_irq[i] == 1) { DEBUG("hwtimer_isr_timer(): calling hwtimer.int_handler(%i)\n", i); int_handler(i); } else { DEBUG("hwtimer_isr_timer(): this should not have happened"); } }
void clear_timer(struct timer_lst *tm) { sigset_t bmask, oldmask; sigemptyset(&bmask); sigaddset(&bmask, SIGALRM); sigprocmask(SIG_BLOCK, &bmask, &oldmask); tm->prev->next = tm->next; tm->next->prev = tm->prev; tm->prev = tm->next = NULL; dlog(LOG_DEBUG, 5, "calling schedule_timer from clear_timer context"); schedule_timer(); sigprocmask(SIG_SETMASK, &oldmask, NULL); }
bool TAO_Notify_SequencePushConsumer::enqueue_if_necessary ( TAO_Notify_Method_Request_Event * request) { if (DEBUG_LEVEL > 0) ORBSVCS_DEBUG ( (LM_DEBUG, "SequencePushConsumer enqueing event.\n")); this->enqueue_request (request); size_t mbs = static_cast<size_t>(this->max_batch_size_.value()); if (this->pending_events().size() >= mbs || this->pacing_.is_valid () == 0) { this->dispatch_pending (); } else { schedule_timer (false); } return true; }
/** * native timer signal handler * * set new system timer, call timer interrupt handler */ void hwtimer_isr_timer(void) { DEBUG("hwtimer_isr_timer()\n"); if (next_timer == -1) { DEBUG("hwtimer_isr_timer(): next_timer is invalid\n"); return; } if (native_hwtimer_isset[next_timer] == 1) { native_hwtimer_isset[next_timer] = 0; DEBUG("hwtimer_isr_timer(): calling hwtimer.int_handler(%i)\n", next_timer); int_handler(next_timer); } else { DEBUG("hwtimer_isr_timer(): this should not have happened\n"); } schedule_timer(); }
void set_timer(struct timer_lst *tm, double secs) { struct timeval tv; struct timer_lst *lst; sigset_t bmask, oldmask; struct timeval firein; dlog(LOG_DEBUG, 3, "setting timer: %.2f secs", secs); firein.tv_sec = (long)secs; firein.tv_usec = (long)((secs - (double)firein.tv_sec) * 1000000); dlog(LOG_DEBUG, 5, "setting timer: %ld secs %ld usecs", firein.tv_sec, firein.tv_usec); gettimeofday(&tv, NULL); timeradd(&tv, &firein, &tm->expires); sigemptyset(&bmask); sigaddset(&bmask, SIGALRM); sigprocmask(SIG_BLOCK, &bmask, &oldmask); lst = &timers_head; /* the timers are in the list in the order they expire, the soonest first */ do { lst = lst->next; } while ((tm->expires.tv_sec > lst->expires.tv_sec) || ((tm->expires.tv_sec == lst->expires.tv_sec) && (tm->expires.tv_usec > lst->expires.tv_usec))); tm->next = lst; tm->prev = lst->prev; lst->prev = tm; tm->prev->next = tm; dlog(LOG_DEBUG, 5, "calling schedule_timer from set_timer context"); schedule_timer(); sigprocmask(SIG_SETMASK, &oldmask, NULL); }
void hwtimer_arch_set(unsigned long offset, short timer) { DEBUG("hwtimer_arch_set(%lu, %i)\n", offset, timer); if (offset < HWTIMERMINOFFSET) { offset = HWTIMERMINOFFSET; DEBUG("hwtimer_arch_set: offset < MIN, set to: %lu\n", offset); } native_hwtimer_irq[timer] = 1; native_hwtimer_isset[timer] = 1; ticks2tv(offset, &(native_hwtimer[timer].it_value)); DEBUG("hwtimer_arch_set(): that is %lu s %lu us from now\n", (unsigned long)native_hwtimer[timer].it_value.tv_sec, (unsigned long)native_hwtimer[timer].it_value.tv_usec); schedule_timer(); return; }
int belle_sip_refresher_start(belle_sip_refresher_t* refresher) { if(refresher->state==started) { belle_sip_warning("Refresher [%p] already started",refresher); } else { if (refresher->target_expires>0) { belle_sip_request_t* request = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(refresher->transaction)); refresher->state=started; if (is_contact_address_acurate(refresher,request)) { schedule_timer(refresher); /*re-arm timer*/ } else { belle_sip_message("belle_sip_refresher_start(): refresher [%p] is resubmitting request because contact sent was not correct in original request.",refresher); belle_sip_refresher_refresh(refresher,refresher->target_expires); return 0; } belle_sip_message("Refresher [%p] started, next refresh in [%i] s",refresher,refresher->obtained_expires); }else{ belle_sip_message("Refresher [%p] stopped, expires=%i",refresher,refresher->target_expires); refresher->state=stopped; } } return 0; }
void random_ref(void) { if (!random_active) { #ifdef MPEXT InitializeCriticalSection(&noise_section); #endif memset(&pool, 0, sizeof(pool)); /* just to start with */ noise_get_heavy(random_add_heavynoise_bitbybit); random_stir(); next_noise_collection = schedule_timer(NOISE_REGULAR_INTERVAL, random_timer, &pool); } #ifdef MPEXT EnterCriticalSection(&noise_section); #endif random_active++; #ifdef MPEXT LeaveCriticalSection(&noise_section); #endif }
static void alarm_handler(int sig) { struct timer_lst *tm, *back; struct timeval tv; gettimeofday(&tv, NULL); tm = timers_head.next; /* * This handler is called when the alarm goes off, so at least one of * the interfaces' timers should satisfy the while condition. * * Sadly, this is not always the case, at least on Linux kernels: * see http://lkml.org/lkml/2005/4/29/163. :-(. It seems some * versions of timers are not accurate and get called up to a couple of * hundred microseconds before they expire. * * Therefore we allow some inaccuracy here; it's sufficient for us * that a timer should go off in a millisecond. */ /* unused timers are initialized to LONG_MAX so we skip them */ while (tm->expires.tv_sec != LONG_MAX && check_time_diff(tm, tv)) { tm->prev->next = tm->next; tm->next->prev = tm->prev; back = tm; tm = tm->next; back->prev = back->next = NULL; (*back->handler)(back->data); } dlog(LOG_DEBUG, 5, "calling schedule_timer from alarm_handler context"); schedule_timer(); }
/* * Send serial special codes. */ static void serial_special(Backend *be, SessionSpecialCode code, int arg) { Serial *serial = container_of(be, Serial, backend); if (serial->port && code == SS_BRK) { logevent(serial->logctx, "Starting serial break at user request"); SetCommBreak(serial->port); /* * To send a serial break on Windows, we call SetCommBreak * to begin the break, then wait a bit, and then call * ClearCommBreak to finish it. Hence, I must use timing.c * to arrange a callback when it's time to do the latter. * * SUS says that a default break length must be between 1/4 * and 1/2 second. FreeBSD apparently goes with 2/5 second, * and so will I. */ serial->clearbreak_time = schedule_timer(TICKSPERSEC * 2 / 5, serbreak_timer, serial); serial->break_in_progress = true; } return; }
/* * Send serial special codes. */ static void serial_special(void *handle, Telnet_Special code) { Serial serial = (Serial) handle; if (serial->port && code == TS_BRK) { logevent(serial->frontend, "Starting serial break at user request"); SetCommBreak(serial->port); /* * To send a serial break on Windows, we call SetCommBreak * to begin the break, then wait a bit, and then call * ClearCommBreak to finish it. Hence, I must use timing.c * to arrange a callback when it's time to do the latter. * * SUS says that a default break length must be between 1/4 * and 1/2 second. FreeBSD apparently goes with 2/5 second, * and so will I. */ serial->clearbreak_time = schedule_timer(TICKSPERSEC * 2 / 5, serbreak_timer, serial); serial->break_in_progress = TRUE; } return; }
// // Scheduler timer. // bool schedule_timer( Pj_Event_Handler *handler, const Pj_Time_Val &delay, int id=-1) { return schedule_timer(th_, handler, delay, id); }
/* * The application must provide a function that configures a peripheral to * create the FreeRTOS tick interrupt, then define configSETUP_TICK_INTERRUPT() * in FreeRTOSConfig.h to call the function. */ void handle_timer_interrupt(uint32_t unused) { schedule_timer(); FreeRTOS_Tick_Handler(); }
/* * You call this to register a timer callback. * * The arguments: * update: This should be 1 if we're updating the specified refnum * refnum_want: The refnum requested. This should only be sepcified * by the user, functions wanting callbacks should specify * the empty string, which means "dont care". * The rest of the arguments are dependant upon the value of "callback" * -- if "callback" is NULL then: * callback: NULL * what: some ircII commands to run when the timer goes off * subargs: what to use to expand $0's, etc in the 'what' variable. * * -- if "callback" is non-NULL then: * callback: function to call when timer goes off * what: argument to pass to "callback" function. Should be some * non-auto storage, perhaps a struct or a malloced char * * array. The caller is responsible for disposing of this * area when it is called, since the timer mechanism does not * know anything of the nature of the argument. * subargs: should be NULL, its ignored anyhow. */ char *add_timer (int update, const char *refnum_want, double interval, long events, int (callback) (void *), void *commands, const char *subargs, TimerDomain domain, int domref, int cancelable) { Timer *ntimer, *otimer = NULL; char * refnum_got = NULL; Timeval right_now; char * retval; /* XXX Eh, maybe it's a hack to check this here. */ if (interval < 0.01 && events == -1) { say("You can't infinitely repeat a timer that runs more " "than 100 times a second."); return NULL; } right_now = get_time(NULL); if (update) { if (!(otimer = get_timer(refnum_want))) update = 0; /* Ok so we're not updating! */ } if (update) { unlink_timer(otimer); ntimer = clone_timer(otimer); delete_timer(otimer); if (interval != -1) { ntimer->interval = double_to_timeval(interval); ntimer->time = time_add(right_now, ntimer->interval); } if (events != -2) ntimer->events = events; if (callback) { /* Delete the previous timer, if necessary */ if (ntimer->command) new_free(&ntimer->command); if (ntimer->subargs) new_free(&ntimer->subargs); ntimer->callback = callback; /* Unfortunately, command is "sometimes const". */ ntimer->callback_data = commands; ntimer->subargs = NULL; } else { if (ntimer->callback) ntimer->callback = NULL; malloc_strcpy(&ntimer->command, (const char *)commands); malloc_strcpy(&ntimer->subargs, subargs); } if (domref != -1) ntimer->domref = domref; } else { if (create_timer_ref(refnum_want, &refnum_got) == -1) { say("TIMER: Refnum '%s' already exists", refnum_want); return NULL; } ntimer = new_timer(); ntimer->ref = refnum_got; ntimer->interval = double_to_timeval(interval); ntimer->time = time_add(right_now, ntimer->interval); ntimer->events = events; ntimer->callback = callback; /* Unfortunately, command is "sometimes const". */ if (callback) ntimer->callback_data = commands; else malloc_strcpy(&ntimer->command, (const char *)commands); malloc_strcpy(&ntimer->subargs, subargs); ntimer->domain = domain; ntimer->domref = domref; ntimer->cancelable = cancelable; ntimer->fires = 0; } schedule_timer(ntimer); retval = ntimer->ref; return retval; /* Eliminates a specious warning from gcc */ }
/* * ExecuteTimers: checks to see if any currently pending timers have * gone off, and if so, execute them, delete them, etc, setting the * current_exec_timer, so that we can't remove the timer while its * still executing. * * changed the behavior: timers will not hook while we are waiting. */ void ExecuteTimers (void) { Timeval right_now; Timer * current, *next; int old_from_server = from_server; get_time(&right_now); while (PendingTimers && time_diff(right_now, PendingTimers->time) < 0) { int old_refnum; old_refnum = current_window->refnum; current = PendingTimers; unlink_timer(current); /* Reschedule the timer if necessary */ if (current->events < 0 || (current->events != 1)) { next = clone_timer(current); if (next->events != -1) next->events--; next->time = time_add(next->time, next->interval); schedule_timer(next); } if (current->domain == SERVER_TIMER) { if (!is_server_valid(current->domref)) { if (current->cancelable) goto advance; /* Otherwise, pretend you were a "GENERAL" type */ } else { from_server = current->domref; make_window_current_by_refnum( get_winref_by_servref(from_server)); } } else if (current->domain == WINDOW_TIMER) { if (!get_window_by_refnum(current->domref)) { if (current->cancelable) goto advance; /* Otherwise, pretend you were a "GENERAL" type */ } else { make_window_current_by_refnum(current->domref); from_server = current_window->server; } } else { /* General timers focus on the current window. */ if (current_window) { if (current_window->server != from_server) from_server = current_window->server; } else { if (from_server != NOSERV) make_window_current_by_refnum( get_winref_by_servref(from_server)); } } /* * If a callback function was registered, then * we use it. If no callback function was registered, * then we call the lambda function. */ get_time(&right_now); now = right_now; if (current->callback) (*current->callback)(current->callback_data); else call_lambda_command("TIMER", current->command, current->subargs); from_server = old_from_server; make_window_current_by_refnum(old_refnum); advance: delete_timer(current); } }
static void process_response_event(belle_sip_listener_t *user_ctx, const belle_sip_response_event_t *event){ belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event); belle_sip_response_t* response = belle_sip_response_event_get_response(event); belle_sip_request_t* request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)); int response_code = belle_sip_response_get_status_code(response); belle_sip_refresher_t* refresher=(belle_sip_refresher_t*)user_ctx; belle_sip_header_contact_t *contact; if (refresher && (client_transaction !=refresher->transaction)) return; /*not for me*/ set_or_update_dialog(refresher,belle_sip_response_event_get_dialog(event)); /*success case:*/ if (response_code>=200 && response_code<300){ refresher->auth_failures=0; refresher->number_of_retry=0; /*great, success*/ if (strcmp(belle_sip_request_get_method(request),"PUBLISH")==0) { /*search for etag*/ belle_sip_header_t* etag=belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"SIP-ETag"); if (etag) { belle_sip_header_t* sip_if_match = belle_sip_header_create("SIP-If-Match",belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(etag))); /*update request for next refresh*/ belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),"SIP-If-Match"); belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),sip_if_match); } else if (refresher->target_expires > 0){ belle_sip_warning("Refresher [%p] received 200ok to a publish without etag",refresher); } } /*update expire if needed*/ set_expires_from_trans(refresher); if (refresher->target_expires<=0) { belle_sip_refresher_stop(refresher); /*doesn't not make sense to refresh if expire =0;*/ } else { /*remove all contact with expire = 0 from request if any, because no need to refresh them*/ const belle_sip_list_t * contact_list= belle_sip_message_get_headers(BELLE_SIP_MESSAGE(request),BELLE_SIP_CONTACT); belle_sip_list_t *iterator, *head; if (contact_list) { for (iterator=head=belle_sip_list_copy(contact_list);iterator!=NULL;iterator=iterator->next) { belle_sip_header_contact_t *contact_for_expire = (belle_sip_header_contact_t *)(iterator->data); if (belle_sip_header_contact_get_expires(contact_for_expire) == 0) { belle_sip_message_remove_header_from_ptr(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(contact_for_expire)); } } belle_sip_list_free(head); } } if (refresher->state==started) { if (!refresher->first_acknoleged_request) belle_sip_object_ref(refresher->first_acknoleged_request = request); if (is_contact_address_acurate(refresher,request)) { schedule_timer(refresher); /*re-arm timer*/ } else { belle_sip_message("belle_sip_refresher_start(): refresher [%p] is resubmitting request because contact sent was not correct in original request.",refresher); belle_sip_refresher_refresh(refresher,refresher->target_expires); return; } } else belle_sip_message("Refresher [%p] not scheduling next refresh, because it was stopped",refresher); }else{/*special error cases*/ switch (response_code) { case 301: case 302: contact=belle_sip_message_get_header_by_type(response,belle_sip_header_contact_t); if (contact){ belle_sip_uri_t *uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact)); if (uri && belle_sip_refresher_refresh_internal(refresher,refresher->target_expires,TRUE,&refresher->auth_events,uri)==0) return; } break; case 401: case 407: refresher->auth_failures++; if (refresher->auth_failures>1){ /*avoid looping with 407 or 401 */ belle_sip_warning("Authentication is failing constantly, %s",(refresher->target_expires>0)? "will retry later":"giving up."); if (refresher->target_expires>0) retry_later(refresher); refresher->auth_failures=0; /*reset auth failure*/ break; } if (refresher->auth_events) { refresher->auth_events=belle_sip_list_free_with_data(refresher->auth_events,(void (*)(void*))belle_sip_auth_event_destroy); } if (belle_sip_refresher_refresh_internal(refresher,refresher->target_expires,TRUE,&refresher->auth_events,NULL)==0) return; /*ok, keep 401 internal*/ break; /*Else notify user of registration failure*/ case 403: /*In case of 403, we will retry later, just in case*/ if (refresher->target_expires>0) retry_later(refresher); break; case 412: if (strcmp(belle_sip_request_get_method(request),"PUBLISH")==0) { belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),"SIP-If-Match"); if (refresher->target_expires>0) { retry_later_on_io_error(refresher); return; /*do not notify this kind of error*/ } } else { if (refresher->target_expires>0) retry_later(refresher); } break; case 423:{ belle_sip_header_extension_t *min_expires=BELLE_SIP_HEADER_EXTENSION(belle_sip_message_get_header((belle_sip_message_t*)response,"Min-Expires")); if (min_expires){ const char *value=belle_sip_header_extension_get_value(min_expires); if (value){ int new_expires=atoi(value); if (new_expires>0 && refresher->state==started){ refresher->target_expires=new_expires; belle_sip_refresher_refresh(refresher,refresher->target_expires); return; } } }else belle_sip_warning("Receiving 423 but no min-expires header."); break; } case 491: { if (refresher->target_expires>0) { retry_later_on_io_error(refresher); return; /*do not notify this kind of error*/ } } case 505: case 501: /*irrecoverable errors, probably no need to retry later*/ break; default: /*for all other errors, retry later*/ if (refresher->target_expires>0) retry_later(refresher); break; } } if (refresher->listener) refresher->listener(refresher,refresher->user_data,response_code, belle_sip_response_get_reason_phrase(response)); }
timed_action_t* timed_action_schedule_periodic(timed_action_notifier* notifier, time_t sec, long nsec, void (*timed_action_handler)(void*), void* arg) { return schedule_timer(notifier, sec, nsec, sec, nsec, timed_action_handler, arg); }
Metrics::Metrics(thread::ThreadPool& pool, std::chrono::seconds period) : period_(period) , pool_(pool) { schedule_timer(); }