Public Types | Public Member Functions | Private Attributes

ACE_Thread_Timer_Queue_Adapter< TQ, TYPE > Class Template Reference

Adapts an ACE timer queue using a separate thread for dispatching. More...

#include <Timer_Queue_Adapters.h>

Inheritance diagram for ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >:
Inheritance graph
[legend]
Collaboration diagram for ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >:
Collaboration graph
[legend]

List of all members.

Public Types

typedef TQ TIMER_QUEUE
 Trait for the underlying queue type.

Public Member Functions

 ACE_Thread_Timer_Queue_Adapter (ACE_Thread_Manager *=ACE_Thread_Manager::instance(), TQ *timer_queue=0)
virtual ~ACE_Thread_Timer_Queue_Adapter (void)
 Destructor.
long schedule (TYPE handler, const void *act, const ACE_Time_Value &future_time, const ACE_Time_Value &interval=ACE_Time_Value::zero)
int cancel (long timer_id, const void **act=0)
virtual int svc (void)
 Runs the dispatching thread.
virtual void deactivate (void)
 Inform the dispatching thread that it should terminate.
ACE_SYNCH_RECURSIVE_MUTEX & mutex (void)
 Access the locking mechanism, useful for iteration.
int timer_queue (TQ *tq)
 Set a user-specified timer queue.
TQ * timer_queue (void) const
 Return the current <TQ>.
ACE_thread_t thr_id (void) const
 Return the thread id of our active object.
virtual int activate (long flags=THR_NEW_LWP|THR_JOINABLE, int n_threads=1, int force_active=0, long priority=ACE_DEFAULT_THREAD_PRIORITY, int grp_id=-1, ACE_Task_Base *task=0, ACE_hthread_t thread_handles[]=0, void *stack[]=0, size_t stack_size[]=0, ACE_thread_t thread_ids[]=0, const char *thr_name[]=0)

Private Attributes

TQ * timer_queue_
 The underlying Timer_Queue.
bool delete_timer_queue_
ACE_SYNCH_RECURSIVE_MUTEX mutex_
ACE_SYNCH_RECURSIVE_CONDITION condition_
bool active_
ACE_thread_t thr_id_
 Thread id of our active object task.

Detailed Description

template<class TQ, class TYPE = ACE_Event_Handler*>
class ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >

Adapts an ACE timer queue using a separate thread for dispatching.

This implementation uses a separate thread to dispatch the timers. The base queue need not be thread safe; this class takes all the necessary locks.

Note:
This is a case where template parameters will be useful, but (IMHO) the effort and portability problems discourage their use.

Definition at line 123 of file Timer_Queue_Adapters.h.


Member Typedef Documentation

template<class TQ , class TYPE = ACE_Event_Handler*>
typedef TQ ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::TIMER_QUEUE

Trait for the underlying queue type.

Definition at line 127 of file Timer_Queue_Adapters.h.


Constructor & Destructor Documentation

template<class TQ , class TYPE >
ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::ACE_Thread_Timer_Queue_Adapter ( ACE_Thread_Manager tm = ACE_Thread_Manager::instance (),
TQ *  timer_queue = 0 
)

Creates the timer queue. Activation of the task is the user's responsibility. Optionally a pointer to a timer queue can be passed, when no pointer is passed, a TQ is dynamically created

Definition at line 158 of file Timer_Queue_Adapters.cpp.

  : ACE_Task_Base (tm),
    timer_queue_(timer_queue),
    delete_timer_queue_(false),
    condition_ (mutex_),
    active_ (true), // Assume that we start in active mode.
    thr_id_ (ACE_OS::NULL_thread)
{
  if (timer_queue_ == 0)
    {
      ACE_NEW (this->timer_queue_,
               TQ);
      this->delete_timer_queue_ = true;
    }
}

template<class TQ , class TYPE >
ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::~ACE_Thread_Timer_Queue_Adapter ( void   )  [virtual]

Destructor.

Definition at line 176 of file Timer_Queue_Adapters.cpp.

{
  if (this->delete_timer_queue_)
    {
      delete this->timer_queue_;
      this->timer_queue_ = 0;
      this->delete_timer_queue_ = false;
    }
}


Member Function Documentation

template<class TQ , class TYPE >
int ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::activate ( long  flags = THR_NEW_LWP | THR_JOINABLE,
int  n_threads = 1,
int  force_active = 0,
long  priority = ACE_DEFAULT_THREAD_PRIORITY,
int  grp_id = -1,
ACE_Task_Base task = 0,
ACE_hthread_t  thread_handles[] = 0,
void *  stack[] = 0,
size_t  stack_size[] = 0,
ACE_thread_t  thread_ids[] = 0,
const char *  thr_name[] = 0 
) [virtual]

We override the default activate() method so that we can ensure that only a single thread is ever spawned. Otherwise, too many weird things can happen...

Reimplemented from ACE_Task_Base.

Definition at line 294 of file Timer_Queue_Adapters.cpp.

{
  // Make sure to set this flag in case we were deactivated earlier.
  this->active_ = true;

  // Make sure that we only allow a single thread to be spawned for
  // our adapter.  Otherwise, too many weird things can happen.
  return ACE_Task_Base::activate (flags, 1, 0, priority, grp_id, task, 0,
                                  stack, stack_size, thread_ids, thr_name);
}

template<class TQ , class TYPE >
int ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::cancel ( long  timer_id,
const void **  act = 0 
)

Cancel the timer_id and return the act parameter if an address is passed in. Also wakes up the dispatching thread.

Definition at line 207 of file Timer_Queue_Adapters.cpp.

{
  ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_, -1);

  int result = this->timer_queue_->cancel (timer_id, act);
  condition_.signal ();
  return result;
}

template<class TQ , class TYPE >
void ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::deactivate ( void   )  [virtual]

Inform the dispatching thread that it should terminate.

Definition at line 218 of file Timer_Queue_Adapters.cpp.

{
  ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_);

  this->active_ = false;
  this->condition_.signal ();
}

template<class TQ , class TYPE >
ACE_SYNCH_RECURSIVE_MUTEX & ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::mutex ( void   ) 

Access the locking mechanism, useful for iteration.

Definition at line 187 of file Timer_Queue_Adapters.cpp.

{
  return this->mutex_;
}

template<class TQ , class TYPE >
long ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::schedule ( TYPE  handler,
const void *  act,
const ACE_Time_Value future_time,
const ACE_Time_Value interval = ACE_Time_Value::zero 
)

Schedule the timer according to the semantics of the <TQ>; wakes up the dispatching thread.

Definition at line 194 of file Timer_Queue_Adapters.cpp.

{
  ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_, -1);

  long result = this->timer_queue_->schedule (handler, act, future_time, interval);
  this->condition_.signal ();
  return result;
}

template<class TQ , class TYPE >
int ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::svc ( void   )  [virtual]

Runs the dispatching thread.

Reimplemented from ACE_Task_Base.

Definition at line 227 of file Timer_Queue_Adapters.cpp.

{
  ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_, -1);

  this->thr_id_ = ACE_Thread::self ();

  // Thread cancellation point, if ACE supports it.
  //
  // Note: This call generates a warning under Solaris because the header
  //       file /usr/include/pthread.h redefines the routine argument. This
  //       is a bug in the Solaris header files and has nothing to do with
  //       ACE.
# if !defined (ACE_LACKS_PTHREAD_CANCEL)
  ACE_PTHREAD_CLEANUP_PUSH (&this->condition_.mutex ().get_nesting_mutex ());
# endif /* ACE_LACKS_PTHREAD_CANCEL */

  while (this->active_)
    {
# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
      // Temporarily suspend ownership of the timer queue mutex in
      // order to dispatch deferred execution commands.  These
      // commands are to be treated as executing in a context
      // "external" to the timer queue adapter, and thus must compete
      // separately for this lock.
      mutex_.release ();
      this->dispatch_commands ();

      // Re-acquire ownership of the timer queue mutex in order to
      // restore the "internal" timer queue adapter context
      mutex_.acquire ();
# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */

      // If the queue is empty, sleep until there is a change on it.
      if (this->timer_queue_->is_empty ())
        this->condition_.wait ();
      else
        {
          // Compute the remaining time, being careful not to sleep
          // for "negative" amounts of time.
          ACE_Time_Value const tv_curr = this->timer_queue_->gettimeofday ();
          ACE_Time_Value const tv_earl = this->timer_queue_->earliest_time ();

          if (tv_earl > tv_curr)
            {
              // The earliest time on the Timer_Queue is in future, so
              // use ACE_OS::gettimeofday() to convert the tv to the
              // absolute time.
              ACE_Time_Value const tv = ACE_OS::gettimeofday () + (tv_earl - tv_curr);
              // ACE_DEBUG ((LM_DEBUG,  ACE_TEXT ("waiting until %u.%3.3u secs\n"),
              // tv.sec(), tv.msec()));
              this->condition_.wait (&tv);
            }
        }

      // Expire timers anyway, at worst this is a no-op.
      this->timer_queue_->expire ();
    }

   // Thread cancellation point, if ACE supports it.
# if !defined (ACE_LACKS_PTHREAD_CANCEL)
  ACE_PTHREAD_CLEANUP_POP (0);
# endif /* ACE_LACKS_PTHREAD_CANCEL */

  return 0;
}

template<class TQ , class TYPE >
ACE_thread_t ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::thr_id ( void   )  const

Return the thread id of our active object.

Definition at line 24 of file Timer_Queue_Adapters.inl.

{
  return this->thr_id_;
}

template<class TQ , class TYPE >
int ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::timer_queue ( TQ *  tq  ) 

Set a user-specified timer queue.

Definition at line 14 of file Timer_Queue_Adapters.inl.

{
  if (this->delete_timer_queue_)
    delete this->timer_queue_;
  this->timer_queue_ = tq;
  this->delete_timer_queue_ = false;
  return 0;
}

template<class TQ , class TYPE >
TQ * ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::timer_queue ( void   )  const

Return the current <TQ>.

Definition at line 8 of file Timer_Queue_Adapters.inl.

{
  return this->timer_queue_;
}


Member Data Documentation

template<class TQ , class TYPE = ACE_Event_Handler*>
bool ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::active_ [private]

When deactivate is called this variable turns to false and the dispatching thread is signalled, to terminate its main loop.

Definition at line 240 of file Timer_Queue_Adapters.h.

template<class TQ , class TYPE = ACE_Event_Handler*>
ACE_SYNCH_RECURSIVE_CONDITION ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::condition_ [private]

The dispatching thread sleeps on this condition while waiting to dispatch the next timer; it is used to wake it up if there is a change on the timer queue.

Definition at line 236 of file Timer_Queue_Adapters.h.

template<class TQ , class TYPE = ACE_Event_Handler*>
bool ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::delete_timer_queue_ [private]

Keeps track of whether we should delete the timer queue (if we didn't create it, then we don't delete it).

Definition at line 225 of file Timer_Queue_Adapters.h.

template<class TQ , class TYPE = ACE_Event_Handler*>
ACE_SYNCH_RECURSIVE_MUTEX ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::mutex_ [private]

The mutual exclusion mechanism that is required to use the <condition_>.

Definition at line 229 of file Timer_Queue_Adapters.h.

template<class TQ , class TYPE = ACE_Event_Handler*>
ACE_thread_t ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::thr_id_ [private]

Thread id of our active object task.

Definition at line 243 of file Timer_Queue_Adapters.h.

template<class TQ , class TYPE = ACE_Event_Handler*>
TQ* ACE_Thread_Timer_Queue_Adapter< TQ, TYPE >::timer_queue_ [private]

The underlying Timer_Queue.

Definition at line 221 of file Timer_Queue_Adapters.h.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines