Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Static Private Member Functions

ACE_XtReactor Class Reference

An object-oriented event demultiplexor and event handler dispatcher that uses the X Toolkit functions. More...

#include <XtReactor.h>

Inheritance diagram for ACE_XtReactor:
Inheritance graph
[legend]
Collaboration diagram for ACE_XtReactor:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 ACE_XtReactor (XtAppContext context=0, size_t size=DEFAULT_SIZE, bool restart=false, ACE_Sig_Handler *=0)
virtual ~ACE_XtReactor (void)
XtAppContext context (void) const
void context (XtAppContext)
virtual long schedule_timer (ACE_Event_Handler *event_handler, const void *arg, const ACE_Time_Value &delay, const ACE_Time_Value &interval)
virtual int reset_timer_interval (long timer_id, const ACE_Time_Value &interval)
virtual int cancel_timer (ACE_Event_Handler *handler, int dont_call_handle_close=1)
virtual int cancel_timer (long timer_id, const void **arg=0, int dont_call_handle_close=1)

Protected Member Functions

virtual int register_handler_i (ACE_HANDLE handle, ACE_Event_Handler *handler, ACE_Reactor_Mask mask)
 Register a single handler.
virtual int register_handler_i (const ACE_Handle_Set &handles, ACE_Event_Handler *handler, ACE_Reactor_Mask mask)
 Register a set of <handlers>.
virtual int remove_handler_i (ACE_HANDLE handle, ACE_Reactor_Mask mask)
 Remove the handler associated with this handle.
virtual int remove_handler_i (const ACE_Handle_Set &handles, ACE_Reactor_Mask)
 Remove a set of <handles>.
virtual int suspend_i (ACE_HANDLE handle)
 Suspend the <Event_Handler> associated with handle.
virtual int resume_i (ACE_HANDLE handle)
 Resume the <Event_Handler> associated with handle.
virtual void synchronize_XtInput (ACE_HANDLE handle)
 Synchronize XtInputHandler for handle.
virtual int compute_Xt_condition (ACE_HANDLE handle)
 Compute needed Xt condition by looking at base class wait set.
virtual int wait_for_multiple_events (ACE_Select_Reactor_Handle_Set &, ACE_Time_Value *)
 Wait for events to occur.
virtual int XtWaitForMultipleEvents (int, ACE_Select_Reactor_Handle_Set &, ACE_Time_Value *)
 Wait for Xt events to occur.

Protected Attributes

XtAppContext context_
ACE_XtReactorIDids_
XtIntervalId timeout_

Private Member Functions

void reset_timeout (void)
 ACE_XtReactor (const ACE_XtReactor &)
 Deny access since member-wise won't work...
ACE_XtReactoroperator= (const ACE_XtReactor &)

Static Private Member Functions

static void TimerCallbackProc (XtPointer closure, XtIntervalId *id)
static void InputCallbackProc (XtPointer closure, int *source, XtInputId *id)

Detailed Description

An object-oriented event demultiplexor and event handler dispatcher that uses the X Toolkit functions.

Definition at line 57 of file XtReactor.h.


Constructor & Destructor Documentation

ACE_XtReactor::ACE_XtReactor ( XtAppContext  context = 0,
size_t  size = DEFAULT_SIZE,
bool  restart = false,
ACE_Sig_Handler h = 0 
)

Definition at line 15 of file XtReactor.cpp.

  : ACE_Select_Reactor (size, restart, h),
    context_ (context),
    ids_ (0),
    timeout_ (0)
{
  // When the ACE_Select_Reactor is constructed it creates the notify
  // pipe and registers it with the register_handler_i() method. The
  // XtReactor overloads this method BUT because the
  // register_handler_i occurs when constructing the base class
  // ACE_Select_Reactor, the ACE_Select_Reactor register_handler_i()
  // is called not the XtReactor register_handler_i().  This means
  // that the notify pipe is registered with the ACE_Select_Reactor
  // event handling code not the XtReactor and so notfications don't
  // work.  To get around this we simply close and re-opened the
  // notification handler in the constructor of the XtReactor.

#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
  this->notify_handler_->close ();
  this->notify_handler_->open (this, 0);
#endif /* ACE_MT_SAFE */
}

ACE_XtReactor::~ACE_XtReactor ( void   )  [virtual]

Definition at line 41 of file XtReactor.cpp.

{
  // Delete the remaining items in the linked list.

  while (this->ids_)
    {
      ACE_XtReactorID *XtID = this->ids_->next_;
      delete this->ids_;
      this->ids_ = XtID;
    }
}

ACE_XtReactor::ACE_XtReactor ( const ACE_XtReactor  )  [private]

Deny access since member-wise won't work...


Member Function Documentation

int ACE_XtReactor::cancel_timer ( ACE_Event_Handler event_handler,
int  dont_call_handle_close = 1 
) [virtual]

Cancel all <event_handlers> that match the address of event_handler. If dont_call_handle_close is 0 then the <handle_close> method of event_handler will be invoked. Returns number of handler's cancelled.

Reimplemented from ACE_Select_Reactor_T< ACE_Select_Reactor_Token >.

Definition at line 437 of file XtReactor.cpp.

{
  ACE_TRACE ("ACE_XtReactor::cancel_timer");

  if (ACE_Select_Reactor::cancel_timer (handler,
                                        dont_call_handle_close) == -1)
    return -1;
  else
    {
      this->reset_timeout ();
      return 0;
    }
}

int ACE_XtReactor::cancel_timer ( long  timer_id,
const void **  arg = 0,
int  dont_call_handle_close = 1 
) [virtual]

Cancel the single ACE_Event_Handler that matches the timer_id value (which was returned from the <schedule> method). If arg is non-NULL then it will be set to point to the ``magic cookie'' argument passed in when the Event_Handler was registered. This makes it possible to free up the memory and avoid memory leaks. If dont_call_handle_close is 0 then the <handle_close> method of <event_handler> will be invoked. Returns 1 if cancellation succeeded and 0 if the timer_id wasn't found.

Reimplemented from ACE_Select_Reactor_T< ACE_Select_Reactor_Token >.

Definition at line 453 of file XtReactor.cpp.

{
  ACE_TRACE ("ACE_XtReactor::cancel_timer");

  if (ACE_Select_Reactor::cancel_timer (timer_id,
                                        arg,
                                        dont_call_handle_close) == -1)
    return -1;
  else
    {
      this->reset_timeout ();
      return 0;
    }
}

int ACE_XtReactor::compute_Xt_condition ( ACE_HANDLE  handle  )  [protected, virtual]

Compute needed Xt condition by looking at base class wait set.

Definition at line 334 of file XtReactor.cpp.

{
  ACE_TRACE ("ACE_XtReactor::compute_Xt_condition");

  // Retrieve current wait mask from base class.
  // The returned value is either a combination of READ/WRITE/EXCEPT_MASK
  // or -1.
  int mask =this->bit_ops(handle,
                          0,
                          this->wait_set_,
                          ACE_Reactor::GET_MASK);

  if (mask == -1) // No active mask.
    return 0;

 int condition = 0;

#if !defined ACE_WIN32
  if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK))
    ACE_SET_BITS (condition, XtInputReadMask);
  if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK))
    ACE_SET_BITS (condition, XtInputWriteMask);
  if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
    ACE_SET_BITS (condition, XtInputExceptMask);
#else
  if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK))
    ACE_SET_BITS (condition, XtInputReadWinsock);
  if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK))
    ACE_SET_BITS (condition, XtInputWriteWinsock);
  // EXCEPT_MASK is not supported for WIN32. As this was
  // already handled in register_handler_i, no check here. 
#endif /* !ACE_WIN32 */

  return condition;
}

XtAppContext ACE_XtReactor::context ( void   )  const

Definition at line 185 of file XtReactor.cpp.

{
  return this->context_;
}

void ACE_XtReactor::context ( XtAppContext  context  ) 

Definition at line 191 of file XtReactor.cpp.

{
  this->context_ = context;
}

void ACE_XtReactor::InputCallbackProc ( XtPointer  closure,
int *  source,
XtInputId *  id 
) [static, private]

Definition at line 105 of file XtReactor.cpp.

{
  ACE_XtReactor *self = (ACE_XtReactor *) closure;
  ACE_HANDLE handle = (ACE_HANDLE) *source;

  // my copy isn't const.
  ACE_Time_Value zero = ACE_Time_Value::zero;

  ACE_Select_Reactor_Handle_Set wait_set;

  // Deal with one file event.

  // - read which kind of event
  if (self->wait_set_.rd_mask_.is_set (handle))
    wait_set.rd_mask_.set_bit (handle);
  if (self->wait_set_.wr_mask_.is_set (handle))
    wait_set.wr_mask_.set_bit (handle);
  if (self->wait_set_.ex_mask_.is_set (handle))
    wait_set.ex_mask_.set_bit (handle);

  int result = ACE_OS::select (*source + 1,
                               wait_set.rd_mask_,
                               wait_set.wr_mask_,
                               wait_set.ex_mask_, &zero);

  ACE_Select_Reactor_Handle_Set dispatch_set;

  // - Use only that one file event (removes events for other files).
  if (result > 0)
    {
      if (wait_set.rd_mask_.is_set (handle))
        dispatch_set.rd_mask_.set_bit (handle);
      if (wait_set.wr_mask_.is_set (handle))
        dispatch_set.wr_mask_.set_bit (handle);
      if (wait_set.ex_mask_.is_set (handle))
        dispatch_set.ex_mask_.set_bit (handle);

      self->dispatch (1, dispatch_set);
    }
}

ACE_XtReactor& ACE_XtReactor::operator= ( const ACE_XtReactor  )  [private]
int ACE_XtReactor::register_handler_i ( const ACE_Handle_Set handles,
ACE_Event_Handler handler,
ACE_Reactor_Mask  mask 
) [protected, virtual]

Register a set of <handlers>.

Reimplemented from ACE_Select_Reactor_T< ACE_Select_Reactor_Token >.

Definition at line 222 of file XtReactor.cpp.

{
  return ACE_Select_Reactor::register_handler_i (handles,
                                                 handler,
                                                 mask);
}

int ACE_XtReactor::register_handler_i ( ACE_HANDLE  handle,
ACE_Event_Handler handler,
ACE_Reactor_Mask  mask 
) [protected, virtual]

Register a single handler.

Reimplemented from ACE_Select_Reactor_T< ACE_Select_Reactor_Token >.

Definition at line 197 of file XtReactor.cpp.

{
  ACE_TRACE ("ACE_XtReactor::register_handler_i");

  // Make sure we have a valid context
  ACE_ASSERT (this->context_ != 0);

#if defined ACE_WIN32
  // Let's handle this special case before we do any real work.
  if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK))
    ACE_NOTSUP_RETURN(-1);
#endif /* ACE_WIN32 */

  int result = ACE_Select_Reactor::register_handler_i (handle,
                                                       handler, mask);
  if (result == -1)
    return -1;

  synchronize_XtInput (handle);
  return 0;
}

int ACE_XtReactor::remove_handler_i ( const ACE_Handle_Set handles,
ACE_Reactor_Mask  mask 
) [protected, virtual]

Remove a set of <handles>.

Reimplemented from ACE_Select_Reactor_T< ACE_Select_Reactor_Token >.

Definition at line 247 of file XtReactor.cpp.

{
  return ACE_Select_Reactor::remove_handler_i (handles,
                                               mask);
}

int ACE_XtReactor::remove_handler_i ( ACE_HANDLE  handle,
ACE_Reactor_Mask  mask 
) [protected, virtual]

Remove the handler associated with this handle.

Reimplemented from ACE_Select_Reactor_T< ACE_Select_Reactor_Token >.

Definition at line 232 of file XtReactor.cpp.

{
  ACE_TRACE ("ACE_XtReactor::remove_handler_i");

  int result  = ACE_Select_Reactor::remove_handler_i (handle,
                                                      mask);
  if (result == -1)
    return -1;

  synchronize_XtInput (handle);
  return 0;
}

void ACE_XtReactor::reset_timeout ( void   )  [private]

This method ensures there's an Xt timeout for the first timeout in the Reactor's Timer_Queue.

Definition at line 374 of file XtReactor.cpp.

{
  // Make sure we have a valid context
  ACE_ASSERT (this->context_ != 0);

  if (timeout_)
    ::XtRemoveTimeOut (timeout_);
  timeout_ = 0;

  ACE_Time_Value *max_wait_time =
    this->timer_queue_->calculate_timeout (0);

  if (max_wait_time)
    timeout_ = ::XtAppAddTimeOut (this->context_,
                                  max_wait_time->msec (),
                                  TimerCallbackProc,
                                  (XtPointer) this);
}

int ACE_XtReactor::reset_timer_interval ( long  timer_id,
const ACE_Time_Value interval 
) [virtual]

Resets the interval of the timer represented by timer_id to interval, which is specified in relative time to the current <gettimeofday>. If interval is equal to ACE_Time_Value::zero, the timer will become a non-rescheduling timer. Returns 0 if successful, -1 if not.

Reimplemented from ACE_Select_Reactor_T< ACE_Select_Reactor_Token >.

Definition at line 395 of file XtReactor.cpp.

{
  ACE_TRACE ("ACE_XtReactor::reset_timer_interval");
  ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token, ace_mon, this->token_, -1));

  int const result = ACE_Select_Reactor::timer_queue_->reset_interval
    (timer_id,
     interval);

  if (result == -1)
    return -1;
  else
    {
      this->reset_timeout ();
      return result;
    }
}

int ACE_XtReactor::resume_i ( ACE_HANDLE  handle  )  [protected, virtual]

Resume the <Event_Handler> associated with handle.

Reimplemented from ACE_Select_Reactor_T< ACE_Select_Reactor_Token >.

Definition at line 269 of file XtReactor.cpp.

{
  ACE_TRACE ("ACE_XtReactor::resume_i");

  int result  =  ACE_Select_Reactor::resume_i (handle);

  if (result == -1)
    return -1;

  synchronize_XtInput (handle);
  return 0;
}

long ACE_XtReactor::schedule_timer ( ACE_Event_Handler event_handler,
const void *  arg,
const ACE_Time_Value delay,
const ACE_Time_Value interval 
) [virtual]

Schedule an ACE_Event_Handler that will expire after an amount of time. The return value of this method, a timer_id value, uniquely identifies the event_handler in the ACE_Reactor's internal list of timers. This timer_id value can be used to cancel the timer with the cancel_timer() call.

See also:
cancel_timer()
reset_timer_interval()
Parameters:
event_handler Event handler to schedule on reactor
arg Argument passed to the handle_timeout() method of event_handler
delay Time interval after which the timer will expire
interval Time interval after which the timer will be automatically rescheduled
Returns:
-1 on failure, a timer_id value on success

Reimplemented from ACE_Select_Reactor_T< ACE_Select_Reactor_Token >.

Definition at line 415 of file XtReactor.cpp.

{
  ACE_TRACE ("ACE_XtReactor::schedule_timer");
  ACE_MT (ACE_GUARD_RETURN (ACE_Select_Reactor_Token, ace_mon, this->token_, -1));

  long const result = ACE_Select_Reactor::schedule_timer (event_handler,
                                                          arg,
                                                          delay,
                                                          interval);
  if (result == -1)
    return -1;
  else
    {
      this->reset_timeout ();
      return result;
    }
}

int ACE_XtReactor::suspend_i ( ACE_HANDLE  handle  )  [protected, virtual]

Suspend the <Event_Handler> associated with handle.

Reimplemented from ACE_Select_Reactor_T< ACE_Select_Reactor_Token >.

Definition at line 255 of file XtReactor.cpp.

{
  ACE_TRACE ("ACE_XtReactor::suspend_i");

  int result  = ACE_Select_Reactor::suspend_i (handle);

  if (result == -1)
    return -1;

  synchronize_XtInput (handle);
  return 0;
}

void ACE_XtReactor::synchronize_XtInput ( ACE_HANDLE  handle  )  [protected, virtual]

Synchronize XtInputHandler for handle.

Definition at line 283 of file XtReactor.cpp.

{
  ACE_TRACE ("ACE_XtReactor::synchronize_XtInput");

  // The idea here is to call this function after the base class has
  // processed the register/remove/suspend/resume_handler request. The
  // resulting mask is used to find out which XtInput mask we need.

  // Find existing handler in linked list.
  ACE_XtReactorID **XtID = &(this->ids_);

  while (*XtID && (*XtID)->handle_ != handle)
    XtID = &((*XtID)->next_);

  // Remove existing input handler.
  if (*XtID)
    ::XtRemoveInput ((*XtID)->id_);

  int condition = compute_Xt_condition (handle);

  if (condition == 0) // No input handler needed.
    {
      if (*XtID)
        {
          // Remove linked list entry.
          ACE_XtReactorID *toDelete  = *XtID;
          *XtID = (*XtID)->next_;
          delete toDelete;
        }
      return;
    }

  if (*XtID == 0)
    {
      // Create new node.
      ACE_XtReactorID *tmp = new ACE_XtReactorID;
      tmp->next_ = this->ids_;
      tmp->handle_ = handle;
      this->ids_ = tmp;
      XtID = &(this->ids_);
    }

  // Finally, add input handler.
  (*XtID)->id_ = ::XtAppAddInput (this->context_,
                                  (int) handle,
                                  (XtPointer) condition,
                                  InputCallbackProc,
                                  (XtPointer) this);
}

void ACE_XtReactor::TimerCallbackProc ( XtPointer  closure,
XtIntervalId *  id 
) [static, private]

Definition at line 89 of file XtReactor.cpp.

{
  ACE_XtReactor *self = (ACE_XtReactor *) closure;
  self->timeout_ = 0;

  // Deal with any timer events
  ACE_Select_Reactor_Handle_Set handle_set;
  self->dispatch (0, handle_set);
  self->reset_timeout ();
}

int ACE_XtReactor::wait_for_multiple_events ( ACE_Select_Reactor_Handle_Set handle_set,
ACE_Time_Value max_wait_time 
) [protected, virtual]

Wait for events to occur.

Reimplemented from ACE_Select_Reactor_T< ACE_Select_Reactor_Token >.

Definition at line 57 of file XtReactor.cpp.

{
  ACE_TRACE ("ACE_XtReactor::wait_for_multiple_events");
  int nfound;

  do
    {
      max_wait_time = this->timer_queue_->calculate_timeout (max_wait_time);

      size_t width = this->handler_rep_.max_handlep1 ();
      handle_set.rd_mask_ = this->wait_set_.rd_mask_;
      handle_set.wr_mask_ = this->wait_set_.wr_mask_;
      handle_set.ex_mask_ = this->wait_set_.ex_mask_;
      nfound = XtWaitForMultipleEvents (width,
                                        handle_set,
                                        max_wait_time);

    } while (nfound == -1 && this->handle_error () > 0);

  if (nfound > 0)
    {
#if !defined (ACE_WIN32)
      handle_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ());
      handle_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ());
      handle_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ());
#endif /* ACE_WIN32 */
    }
  return nfound; // Timed out or input available
}

int ACE_XtReactor::XtWaitForMultipleEvents ( int  width,
ACE_Select_Reactor_Handle_Set wait_set,
ACE_Time_Value  
) [protected, virtual]

Wait for Xt events to occur.

Definition at line 149 of file XtReactor.cpp.

{
  // Make sure we have a valid context
  ACE_ASSERT (this->context_ != 0);

  // Check to make sure our handle's are all usable.
  ACE_Select_Reactor_Handle_Set temp_set = wait_set;

  if (ACE_OS::select (width,
                      temp_set.rd_mask_,
                      temp_set.wr_mask_,
                      temp_set.ex_mask_,
                      (ACE_Time_Value *) &ACE_Time_Value::zero) == -1)
    return -1; // Bad file arguments...

  // Instead of waiting using <select>, just use the Xt mechanism to
  // wait for a single event.

  // Wait for something to happen.
  ::XtAppProcessEvent (this->context_, XtIMAll);

  // Reset the width, in case it changed during the upcalls.
  width = this->handler_rep_.max_handlep1 ();

  // Now actually read the result needed by the <Select_Reactor> using
  // <select>.
  return ACE_OS::select (width,
                         wait_set.rd_mask_,
                         wait_set.wr_mask_,
                         wait_set.ex_mask_,
                         (ACE_Time_Value *) &ACE_Time_Value::zero);
}


Member Data Documentation

XtAppContext ACE_XtReactor::context_ [protected]

Definition at line 125 of file XtReactor.h.

Definition at line 126 of file XtReactor.h.

XtIntervalId ACE_XtReactor::timeout_ [protected]

Definition at line 127 of file XtReactor.h.


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