/****************************************************************************
 **                                                                        **
 ** Name:    _nas_timer_db_insert_entry()                              **
 **                                                                        **
 ** Description: Inserts the entry with the given identifier into the      **
 **      queue of active timer entries and restarts the system     **
 **      timer if the new entry is the next entry for which the    **
 **      timer should be scheduled to expire.                      **
 **                                                                        **
 ** Inputs:  id:        Identifier of the new entry                **
 **      te:        Pointer to the entry to be inserted        **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    None                                       **
 **      Others:    _nas_timer_db                              **
 **                                                                        **
 ***************************************************************************/
static void
_nas_timer_db_insert_entry (
  int id,
  nas_timer_entry_t * te)
{
  struct itimerval                        it;
  struct timespec                         ts;
  struct timeval                          current_time;
  int                                     restart;

  /*
   * Enqueue the new timer entry
   */
  _nas_timer_db.tq[id].id = id;
  _nas_timer_db.tq[id].entry = te;
  /*
   * Save its interval timer value
   */
  it.it_interval.tv_sec = it.it_interval.tv_usec = 0;
  it.it_value = te->tv;
  /*
   * Update its interval timer value
   */
  clock_gettime (CLOCK_MONOTONIC, &ts);
  current_time.tv_sec = ts.tv_sec;
  current_time.tv_usec = ts.tv_nsec / 1000;
  /*
   * tv = tv + time()
   */
  _nas_timer_add (&te->tv, &current_time, &te->tv);
  /*
   * Insert the new timer entry into the list of active entries
   */
  nas_timer_lock_db ();
  restart = _nas_timer_db_insert (&_nas_timer_db.tq[id]);
  nas_timer_unlock_db ();
#if ENABLE_ITTI == 0

  if (restart) {
    /*
     * The new entry is the first entry of the list;
     * * * * restart the system timer
     */
    setitimer (ITIMER_REAL, &it, 0);
  }
#else
  (void)(restart);
#endif
}
/****************************************************************************
 **                                                                        **
 ** Name:    _nas_timer_db_remove_entry()                              **
 **                                                                        **
 ** Description: Removes the entry with the given identifier from the      **
 **      queue of active timer entries and restarts the system     **
 **      timer if the entry was the next entry for which the timer **
 **      was scheduled to expire.                                  **
 **                                                                        **
 ** Inputs:  id:        Identifier of the entry to be removed      **
 **      Others:    None                                       **
 **                                                                        **
 ** Outputs:     None                                                      **
 **      Return:    A pointer to the removed entry             **
 **      Others:    _nas_timer_db                              **
 **                                                                        **
 ***************************************************************************/
static nas_timer_entry_t *_nas_timer_db_remove_entry(int id)
{
  int restart;

  /* The identifier of the timer is valid within the timer queue */
  assert(_nas_timer_db.tq[id].id == id);

  /* Remove the timer entry from the list of active entries */
  nas_timer_lock_db();
  restart = _nas_timer_db_remove(&_nas_timer_db.tq[id]);
  nas_timer_unlock_db();

  if (restart) {
    int rc;
    /* The entry was the first entry of the list;
     * the system timer needs to be restarted */
    struct itimerval it;
    struct timeval tv;
    struct timespec ts;

    it.it_interval.tv_sec = it.it_interval.tv_usec = 0;

    clock_gettime(CLOCK_MONOTONIC, &ts);

    tv.tv_sec = ts.tv_sec;
    tv.tv_usec = ts.tv_nsec/1000;
    /* tv = tv - time() */
    rc = _nas_timer_sub(&_nas_timer_db.head->entry->tv, &tv, &it.it_value);

#if defined(ENABLE_ITTI)
    timer_remove(_nas_timer_db.head->entry->timer_id);
    (void) (rc);
#else

    if (rc < 0) {
      /* The system timer should have already expired */
      _nas_timer_handler(SIGALRM);
    } else {
      /* Restart the system timer */
      setitimer(ITIMER_REAL, &it, 0);
    }

#endif
  }

  /* Return a pointer to the removed entry */
  return (_nas_timer_db.tq[id].entry);
}