Ejemplo n.º 1
0
static bool
_finalize_timer() {
    timer_read_begin();
    struct timer_info *timer = get_timer_info();
    timer_read_end();
    assert( timer != NULL );

    debug( "Deleting timer callbacks ( timer_callbacks = %p ).", timer->timer_callbacks );

    if ( timer->timer_callbacks != NULL ) {
        for ( dlist_element *e = timer->timer_callbacks->next; e; e = e->next ) {
            xfree( e->data );
        }
        delete_dlist( timer->timer_callbacks );
        timer->timer_callbacks = NULL;
    }
    else {
        error( "All timer callbacks are already deleted or not created yet." );
    }

    timer_write_begin();
    delete_timer_info( timer );
    timer_write_end();

    return true;
}
Ejemplo n.º 2
0
static bool
_delete_timer_event( timer_callback callback, void *user_data ) {
    assert( callback != NULL );
    timer_read_begin();
    struct timer_info *timer = get_timer_info();
    timer_read_end();

    debug( "Deleting a timer event ( callback = %p, user_data = %p ).", callback, user_data );

    if ( timer->timer_callbacks == NULL ) {
        debug( "All timer callbacks are already deleted or not created yet." );
        return false;
    }

    for ( dlist_element *e = timer->timer_callbacks->next; e; e = e->next ) {
        timer_callback_info *cb = e->data;
        if ( cb->function == callback && cb->user_data == user_data ) {
            debug( "Deleting a callback ( callback = %p, user_data = %p ).", callback, user_data );
            cb->function = NULL;
            cb->user_data = NULL;
            cb->expires_at.tv_sec = 0;
            cb->expires_at.tv_nsec = 0;
            cb->interval.tv_sec = 0;
            cb->interval.tv_nsec = 0;
            return true;
        }
    }

    error( "No registered timer event callback found." );

    return false;
}
Ejemplo n.º 3
0
static void
_execute_timer_events( int *next_timeout_usec ) {
    assert( next_timeout_usec != NULL );

    timer_read_begin();
    struct timer_info *timer = get_timer_info();
    timer_read_end();
    assert( timer != NULL );

    debug( "Executing timer events ( timer_callbacks = %p ).", timer->timer_callbacks );

    struct timespec now = { 0, 0 };
    assert( clock_gettime( CLOCK_MONOTONIC, &now ) == 0 );
    assert( timer->timer_callbacks != NULL );

    timer_callback_info *callback = NULL;
    dlist_element *element_next = NULL;
    for ( dlist_element *element = timer->timer_callbacks->next; element; element = element_next ) {
        element_next = element->next;
        callback = element->data;
        if ( callback->function != NULL ) {
            if ( TIMESPEC_LESS_THEN( &now, &callback->expires_at ) ) {
                break;
            }
            on_timer( callback, &now );
        }
        delete_dlist_element( element );
        if ( callback->function == NULL ) {
            xfree( callback );
        }
        else {
            insert_timer_callback( timer, callback );
        }
    }

    struct timespec max_timeout = { ( INT_MAX / 1000000 ), 0 };
    struct timespec min_timeout = { 0, 0 };
    if ( timer->timer_callbacks->next == NULL ) {
        TIMESPEC_TO_MICROSECONDS( &max_timeout, next_timeout_usec );
    }
    else {
        callback = timer->timer_callbacks->next->data;
        if ( TIMESPEC_LESS_THEN( &callback->expires_at, &now ) ) {
            TIMESPEC_TO_MICROSECONDS( &min_timeout, next_timeout_usec );
        }
        else {
            struct timespec timeout = { 0, 0 };
            SUB_TIMESPEC( &callback->expires_at, &now, &timeout );
            if ( TIMESPEC_LESS_THEN( &timeout, &max_timeout ) ) {
                TIMESPEC_TO_MICROSECONDS( &timeout, next_timeout_usec );
            }
            else {
                TIMESPEC_TO_MICROSECONDS( &max_timeout, next_timeout_usec );
            }
        }
    }
}
Ejemplo n.º 4
0
static bool
_add_timer_event_callback( struct itimerspec *interval, timer_callback callback, void *user_data ) {
  assert( interval != NULL );
  assert( callback != NULL );
  timer_read_begin();
  struct timer_info *timer = get_timer_info();
  timer_read_end();
  assert( timer != NULL );

  debug( "Adding a timer event callback ( interval = %u.%09u, initial expiration = %u.%09u, callback = %p, user_data = %p ).",
         interval->it_interval.tv_sec, interval->it_interval.tv_nsec,
         interval->it_value.tv_sec, interval->it_value.tv_nsec, callback, user_data );

  timer_callback_info *cb;
  struct timespec now;

  cb = xmalloc( sizeof( timer_callback_info ) );
  memset( cb, 0, sizeof( timer_callback_info ) );
  cb->function = callback;
  cb->user_data = user_data;

  if ( clock_gettime( CLOCK_MONOTONIC, &now ) != 0 ) {
    error( "Failed to retrieve monotonic time ( %s [%d] ).", strerror( errno ), errno );
    xfree( cb );
    return false;
  }

  cb->interval = interval->it_interval;

  if ( VALID_TIMESPEC( &interval->it_value ) ) {
    ADD_TIMESPEC( &now, &interval->it_value, &cb->expires_at );
  }
  else if ( VALID_TIMESPEC( &interval->it_interval ) ) {
    ADD_TIMESPEC( &now, &interval->it_interval, &cb->expires_at );
  }
  else {
    error( "Timer must not be zero when a timer event is added." );
    xfree( cb );
    return false;
  }

  debug( "Set an initial expiration time to %u.%09u.", now.tv_sec, now.tv_nsec );

  assert( timer->timer_callbacks != NULL );
  insert_timer_callback( timer, cb );

  return true;
}