Beispiel #1
0
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);
  }
}
Beispiel #2
0
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);
    }
}
Beispiel #3
0
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);
}
Beispiel #4
0
/*
 * 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);
	}
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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);
}
Beispiel #8
0
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++;
}
Beispiel #9
0
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;
}/*}}}*/
Beispiel #10
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;
	}
}
Beispiel #11
0
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;
}
Beispiel #12
0
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();
}
Beispiel #13
0
/**
 * 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");
    }
}
Beispiel #14
0
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);
}
Beispiel #15
0
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;
}
Beispiel #16
0
/**
 * 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();
}
Beispiel #17
0
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);
}
Beispiel #18
0
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;
}
Beispiel #19
0
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;
}
Beispiel #20
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
}
Beispiel #21
0
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();
}
Beispiel #22
0
/*
 * 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;
}
Beispiel #23
0
/*
 * 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;
}
Beispiel #24
0
 //
 // Scheduler timer.
 //
 bool schedule_timer( Pj_Event_Handler *handler, 
                      const Pj_Time_Val &delay, 
                      int id=-1)
 {
     return schedule_timer(th_, handler, delay, id);
 }
Beispiel #25
0
/*
 * 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();
}
Beispiel #26
0
Datei: timer.c Projekt: tcava/bx2
/*
 * 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 */
}
Beispiel #27
0
Datei: timer.c Projekt: tcava/bx2
/*
 * 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);
	}
}
Beispiel #28
0
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));

}
Beispiel #29
0
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);
}
Beispiel #30
0
Metrics::Metrics(thread::ThreadPool& pool, std::chrono::seconds period)
: period_(period)
, pool_(pool)
{
    schedule_timer();
}