mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 01:37:00 +00:00
1622 lines
51 KiB
C++
1622 lines
51 KiB
C++
// $Id: Select_Reactor_T.cpp 97894 2014-09-16 18:11:56Z johnnyw $
|
|
|
|
#ifndef ACE_SELECT_REACTOR_T_CPP
|
|
#define ACE_SELECT_REACTOR_T_CPP
|
|
|
|
#include "ace/Select_Reactor_T.h"
|
|
|
|
#if !defined (ACE_LACKS_PRAGMA_ONCE)
|
|
# pragma once
|
|
#endif /* ACE_LACKS_PRAGMA_ONCE */
|
|
|
|
#include "ace/ACE.h"
|
|
#include "ace/Guard_T.h"
|
|
#include "ace/Log_Category.h"
|
|
#include "ace/Signal.h"
|
|
#include "ace/Sig_Handler.h"
|
|
#include "ace/Thread.h"
|
|
#include "ace/Timer_Heap.h"
|
|
#include "ace/OS_NS_errno.h"
|
|
#include "ace/OS_NS_sys_select.h"
|
|
#include "ace/OS_NS_sys_stat.h"
|
|
|
|
// For timer_queue_
|
|
#include "ace/Recursive_Thread_Mutex.h"
|
|
|
|
/*
|
|
* ACE Reactor specialization hook.
|
|
*/
|
|
//@@ REACTOR_SPL_INCLUDE_FORWARD_DECL_ADD_HOOK
|
|
|
|
#if !defined (__ACE_INLINE__)
|
|
#include "ace/Select_Reactor_T.inl"
|
|
#endif /* __ACE_INLINE__ */
|
|
|
|
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
|
|
|
|
ACE_ALLOC_HOOK_DEFINE(ACE_Select_Reactor_T)
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::any_ready
|
|
(ACE_Select_Reactor_Handle_Set &wait_set)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::any_ready");
|
|
|
|
if (this->mask_signals_)
|
|
{
|
|
#if !defined (ACE_WIN32)
|
|
// Make this call signal safe.
|
|
ACE_Sig_Guard sb;
|
|
#endif /* ACE_WIN32 */
|
|
|
|
return this->any_ready_i (wait_set);
|
|
}
|
|
return this->any_ready_i (wait_set);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::any_ready_i
|
|
(ACE_Select_Reactor_Handle_Set &wait_set)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::any_ready_i");
|
|
|
|
int const number_ready = this->ready_set_.rd_mask_.num_set ()
|
|
+ this->ready_set_.wr_mask_.num_set ()
|
|
+ this->ready_set_.ex_mask_.num_set ();
|
|
|
|
// number_ready > 0 meaning there are handles in the ready_set
|
|
// &wait_set != &(this->ready_set_) means that we need to copy
|
|
// the handles from the ready_set to the wait set because the
|
|
// wait_set_ doesn't contain all the handles in the ready_set_
|
|
if (number_ready > 0 && &wait_set != &(this->ready_set_))
|
|
{
|
|
wait_set.rd_mask_ = this->ready_set_.rd_mask_;
|
|
wait_set.wr_mask_ = this->ready_set_.wr_mask_;
|
|
wait_set.ex_mask_ = this->ready_set_.ex_mask_;
|
|
|
|
this->ready_set_.rd_mask_.reset ();
|
|
this->ready_set_.wr_mask_.reset ();
|
|
this->ready_set_.ex_mask_.reset ();
|
|
}
|
|
|
|
return number_ready;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handler_i (int signum,
|
|
ACE_Event_Handler **eh)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::handler_i");
|
|
ACE_Event_Handler *handler = this->signal_handler_->handler (signum);
|
|
|
|
if (handler == 0)
|
|
return -1;
|
|
else if (eh != 0)
|
|
*eh = handler;
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> bool
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::initialized (void)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::initialized");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, false));
|
|
return this->initialized_;
|
|
}
|
|
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::owner (ACE_thread_t tid,
|
|
ACE_thread_t *o_id)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::owner");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
|
|
if (o_id)
|
|
{
|
|
*o_id = this->owner_;
|
|
}
|
|
|
|
this->owner_ = tid;
|
|
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::owner (ACE_thread_t *t_id)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::owner");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
*t_id = this->owner_;
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> bool
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::restart (void)
|
|
{
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, false));
|
|
return this->restart_;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> bool
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::restart (bool r)
|
|
{
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, false));
|
|
bool const current_value = this->restart_;
|
|
this->restart_ = r;
|
|
return current_value;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> void
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::requeue_position (int rp)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::requeue_position");
|
|
ACE_MT (ACE_GUARD (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_));
|
|
#if defined (ACE_WIN32)
|
|
ACE_UNUSED_ARG (rp);
|
|
// Must always requeue ourselves "next" on Win32.
|
|
this->requeue_position_ = 0;
|
|
#else
|
|
this->requeue_position_ = rp;
|
|
#endif /* ACE_WIN32 */
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::requeue_position (void)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::requeue_position");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->requeue_position_;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> void
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::max_notify_iterations (int iterations)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::max_notify_iterations");
|
|
ACE_MT (ACE_GUARD (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_));
|
|
|
|
this->notify_handler_->max_notify_iterations (iterations);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::max_notify_iterations (void)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::max_notify_iterations");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->notify_handler_->max_notify_iterations ();
|
|
}
|
|
|
|
// Enqueue ourselves into the list of waiting threads.
|
|
template <class ACE_SELECT_REACTOR_TOKEN> void
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::renew (void)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::renew");
|
|
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
|
|
if (this->supress_notify_renew () == 0)
|
|
this->token_.renew (this->requeue_position_);
|
|
#endif /* defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) */
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::notify (ACE_Event_Handler *eh,
|
|
ACE_Reactor_Mask mask,
|
|
ACE_Time_Value *timeout)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::notify");
|
|
|
|
// Pass over both the Event_Handler *and* the mask to allow the
|
|
// caller to dictate which Event_Handler method the receiver
|
|
// invokes. Note that this call can timeout.
|
|
ssize_t n = -1;
|
|
if (this->notify_handler_)
|
|
{
|
|
n = this->notify_handler_->notify (eh, mask, timeout);
|
|
}
|
|
return n == -1 ? -1 : 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::resume_handler (ACE_HANDLE handle)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::resume_handler");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->resume_i (handle);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::suspend_handler (ACE_HANDLE handle)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::suspend_handler");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->suspend_i (handle);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::suspend_handlers (void)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::suspend_handlers");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
|
|
ACE_Event_Handler *eh = 0;
|
|
|
|
for (ACE_Select_Reactor_Handler_Repository_Iterator iter (&this->handler_rep_);
|
|
iter.next (eh) != 0;
|
|
iter.advance ())
|
|
{
|
|
this->suspend_i (eh->get_handle ());
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::resume_handlers (void)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::resume_handlers");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
|
|
ACE_Event_Handler *eh = 0;
|
|
|
|
for (ACE_Select_Reactor_Handler_Repository_Iterator iter (&this->handler_rep_);
|
|
iter.next (eh) != 0;
|
|
iter.advance ())
|
|
{
|
|
this->resume_i (eh->get_handle ());
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler
|
|
(ACE_Event_Handler *handler,
|
|
ACE_Reactor_Mask mask)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->register_handler_i (handler->get_handle (), handler, mask);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler
|
|
(ACE_HANDLE handle,
|
|
ACE_Event_Handler *handler,
|
|
ACE_Reactor_Mask mask)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->register_handler_i (handle, handler, mask);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler
|
|
(const ACE_Handle_Set &handles,
|
|
ACE_Event_Handler *handler,
|
|
ACE_Reactor_Mask mask)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->register_handler_i (handles, handler, mask);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> ACE_Event_Handler *
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::find_handler
|
|
(ACE_HANDLE handle)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::find_handler");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, 0));
|
|
return this->find_handler_i (handle);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handler
|
|
(ACE_HANDLE handle,
|
|
ACE_Reactor_Mask mask,
|
|
ACE_Event_Handler **handler)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::handler");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->handler_i (handle, mask, handler);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler
|
|
(const ACE_Handle_Set &handles,
|
|
ACE_Reactor_Mask mask)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->remove_handler_i (handles, mask);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler
|
|
(ACE_Event_Handler *handler,
|
|
ACE_Reactor_Mask mask)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->remove_handler_i (handler->get_handle (), mask);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler
|
|
(ACE_HANDLE handle,
|
|
ACE_Reactor_Mask mask)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->remove_handler_i (handle, mask);
|
|
}
|
|
|
|
// Performs operations on the "ready" bits.
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::ready_ops
|
|
(ACE_HANDLE handle,
|
|
ACE_Reactor_Mask mask,
|
|
int ops)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::ready_ops");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
return this->bit_ops (handle,
|
|
mask,
|
|
this->ready_set_,
|
|
ops);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::open
|
|
(size_t size,
|
|
bool restart,
|
|
ACE_Sig_Handler *sh,
|
|
ACE_Timer_Queue *tq,
|
|
int disable_notify_pipe,
|
|
ACE_Reactor_Notify *notify)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::open");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
|
|
// Can't initialize ourselves more than once.
|
|
if (this->initialized_)
|
|
return -1;
|
|
|
|
this->owner_ = ACE_Thread::self ();
|
|
this->restart_ = restart;
|
|
this->signal_handler_ = sh;
|
|
this->timer_queue_ = tq;
|
|
this->notify_handler_ = notify;
|
|
|
|
int result = 0;
|
|
|
|
// Allows the signal handler to be overridden.
|
|
if (this->signal_handler_ == 0)
|
|
{
|
|
ACE_NEW_RETURN (this->signal_handler_,
|
|
ACE_Sig_Handler,
|
|
-1);
|
|
|
|
this->delete_signal_handler_ = true;
|
|
}
|
|
|
|
// Allows the timer queue to be overridden.
|
|
if (result != -1 && this->timer_queue_ == 0)
|
|
{
|
|
ACE_NEW_RETURN (this->timer_queue_,
|
|
ACE_Timer_Heap,
|
|
-1);
|
|
|
|
this->delete_timer_queue_ = true;
|
|
}
|
|
|
|
// Allows the Notify_Handler to be overridden.
|
|
if (result != -1 && this->notify_handler_ == 0)
|
|
{
|
|
ACE_NEW_RETURN (this->notify_handler_,
|
|
ACE_Select_Reactor_Notify,
|
|
-1);
|
|
|
|
this->delete_notify_handler_ = true;
|
|
}
|
|
|
|
if (result != -1 && this->handler_rep_.open (size) == -1)
|
|
result = -1;
|
|
else if (this->notify_handler_->open (this,
|
|
0,
|
|
disable_notify_pipe) == -1)
|
|
{
|
|
ACELIB_ERROR ((LM_ERROR,
|
|
ACE_TEXT ("%p\n"),
|
|
ACE_TEXT ("notification pipe open failed")));
|
|
result = -1;
|
|
}
|
|
|
|
if (result != -1)
|
|
// We're all set to go.
|
|
this->initialized_ = true;
|
|
else
|
|
// This will close down all the allocated resources properly.
|
|
this->close ();
|
|
|
|
return result;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::set_sig_handler
|
|
(ACE_Sig_Handler *signal_handler)
|
|
{
|
|
delete this->signal_handler_;
|
|
this->signal_handler_ = signal_handler;
|
|
this->delete_signal_handler_ = false;
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> ACE_Timer_Queue *
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::timer_queue (void) const
|
|
{
|
|
return this->timer_queue_;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::timer_queue
|
|
(ACE_Timer_Queue *tq)
|
|
{
|
|
if (this->delete_timer_queue_)
|
|
{
|
|
delete this->timer_queue_;
|
|
}
|
|
else if (this->timer_queue_)
|
|
{
|
|
this->timer_queue_->close ();
|
|
}
|
|
this->timer_queue_ = tq;
|
|
this->delete_timer_queue_ = false;
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN>
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::ACE_Select_Reactor_T
|
|
(ACE_Sig_Handler *sh,
|
|
ACE_Timer_Queue *tq,
|
|
int disable_notify_pipe,
|
|
ACE_Reactor_Notify *notify,
|
|
bool mask_signals,
|
|
int s_queue)
|
|
: ACE_Select_Reactor_Impl (mask_signals)
|
|
, token_ (s_queue)
|
|
, lock_adapter_ (token_)
|
|
, deactivated_ (0)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::ACE_Select_Reactor_T");
|
|
|
|
this->token_.reactor (*this);
|
|
// First try to open the Reactor with the hard-coded default.
|
|
if (this->open (ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::DEFAULT_SIZE,
|
|
0,
|
|
sh,
|
|
tq,
|
|
disable_notify_pipe,
|
|
notify) == -1)
|
|
{
|
|
// The hard-coded default Reactor size failed, so attempt to
|
|
// determine the size at run-time by checking the process file
|
|
// descriptor limit on platforms that support this feature.
|
|
|
|
// reset the errno so that subsequent checks are valid
|
|
errno = 0;
|
|
|
|
// There is no need to deallocate resources from previous open()
|
|
// call since the open() method deallocates any resources prior
|
|
// to exiting if an error was encountered.
|
|
|
|
// Set the default reactor size to be the current limit on the
|
|
// number of file descriptors available to the process. This
|
|
// size is not necessarily the maximum limit.
|
|
if (this->open (ACE::max_handles (),
|
|
0,
|
|
sh,
|
|
tq,
|
|
disable_notify_pipe,
|
|
notify) == -1)
|
|
ACELIB_ERROR ((LM_ERROR,
|
|
ACE_TEXT ("%p\n"),
|
|
ACE_TEXT ("ACE_Select_Reactor_T::open ")
|
|
ACE_TEXT ("failed inside ")
|
|
ACE_TEXT ("ACE_Select_Reactor_T::CTOR")));
|
|
}
|
|
}
|
|
|
|
// Initialize ACE_Select_Reactor_T.
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN>
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::ACE_Select_Reactor_T
|
|
(size_t size,
|
|
bool restart,
|
|
ACE_Sig_Handler *sh,
|
|
ACE_Timer_Queue *tq,
|
|
int disable_notify_pipe,
|
|
ACE_Reactor_Notify *notify,
|
|
bool mask_signals,
|
|
int s_queue)
|
|
: ACE_Select_Reactor_Impl (mask_signals)
|
|
, token_ (s_queue)
|
|
, lock_adapter_ (token_)
|
|
, deactivated_ (0)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::ACE_Select_Reactor_T");
|
|
|
|
this->token_.reactor (*this);
|
|
if (this->open (size,
|
|
restart,
|
|
sh,
|
|
tq,
|
|
disable_notify_pipe,
|
|
notify) == -1)
|
|
ACELIB_ERROR ((LM_ERROR,
|
|
ACE_TEXT ("%p\n"),
|
|
ACE_TEXT ("ACE_Select_Reactor_T::open ")
|
|
ACE_TEXT ("failed inside ACE_Select_Reactor_T::CTOR")));
|
|
}
|
|
|
|
// Close down the ACE_Select_Reactor_T instance, detaching any
|
|
// remaining Event_Handers. This had better be called from the main
|
|
// event loop thread...
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::close (void)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::close");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
|
|
if (this->delete_signal_handler_)
|
|
{
|
|
delete this->signal_handler_;
|
|
this->signal_handler_ = 0;
|
|
this->delete_signal_handler_ = false;
|
|
}
|
|
|
|
this->handler_rep_.close ();
|
|
|
|
if (this->delete_timer_queue_)
|
|
{
|
|
delete this->timer_queue_;
|
|
this->timer_queue_ = 0;
|
|
this->delete_timer_queue_ = false;
|
|
}
|
|
else if (this->timer_queue_)
|
|
{
|
|
this->timer_queue_->close ();
|
|
this->timer_queue_ = 0;
|
|
}
|
|
|
|
if (this->notify_handler_ != 0)
|
|
this->notify_handler_->close ();
|
|
|
|
if (this->delete_notify_handler_)
|
|
{
|
|
delete this->notify_handler_;
|
|
this->notify_handler_ = 0;
|
|
this->delete_notify_handler_ = false;
|
|
}
|
|
|
|
this->initialized_ = false;
|
|
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::current_info
|
|
(ACE_HANDLE, size_t &)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN>
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::~ACE_Select_Reactor_T (void)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::~ACE_Select_Reactor_T");
|
|
this->close ();
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler_i
|
|
(const ACE_Handle_Set &handles,
|
|
ACE_Reactor_Mask mask)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::remove_handler_i");
|
|
ACE_HANDLE h;
|
|
|
|
ACE_Handle_Set_Iterator handle_iter (handles);
|
|
|
|
while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
|
|
if (this->remove_handler_i (h, mask) == -1)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler_i
|
|
(const ACE_Handle_Set &handles,
|
|
ACE_Event_Handler *handler,
|
|
ACE_Reactor_Mask mask)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::register_handler_i");
|
|
ACE_HANDLE h;
|
|
|
|
ACE_Handle_Set_Iterator handle_iter (handles);
|
|
while ((h = handle_iter ()) != ACE_INVALID_HANDLE)
|
|
if (this->register_handler_i (h, handler, mask) == -1)
|
|
return -1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler
|
|
(const ACE_Sig_Set &sigset,
|
|
ACE_Event_Handler *new_sh,
|
|
ACE_Sig_Action *new_disp)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::register_handler");
|
|
|
|
int result = 0;
|
|
|
|
#if (ACE_NSIG > 0)
|
|
for (int s = 1; s < ACE_NSIG; ++s)
|
|
if ((sigset.is_member (s) == 1)
|
|
&& this->signal_handler_->register_handler (s,
|
|
new_sh,
|
|
new_disp) == -1)
|
|
result = -1;
|
|
#else /* ACE_NSIG <= 0 */
|
|
ACE_UNUSED_ARG (sigset);
|
|
ACE_UNUSED_ARG (new_sh);
|
|
ACE_UNUSED_ARG (new_disp);
|
|
#endif /* ACE_NSIG <= 0 */
|
|
return result;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler
|
|
(const ACE_Sig_Set &sigset)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::remove_handler");
|
|
int result = 0;
|
|
|
|
#if (ACE_NSIG > 0)
|
|
for (int s = 1; s < ACE_NSIG; ++s)
|
|
if ((sigset.is_member (s) == 1)
|
|
&& this->signal_handler_->remove_handler (s) == -1)
|
|
result = -1;
|
|
#else /* ACE_NSIG <= 0 */
|
|
ACE_UNUSED_ARG (sigset);
|
|
#endif /* ACE_NSIG <= 0 */
|
|
|
|
return result;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::cancel_timer (ACE_Event_Handler *handler,
|
|
int dont_call_handle_close)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::cancel_timer");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
|
|
if ((this->timer_queue_ != 0) && (handler != 0))
|
|
return this->timer_queue_->cancel (handler, dont_call_handle_close);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::cancel_timer (long timer_id,
|
|
const void **arg,
|
|
int dont_call_handle_close)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::cancel_timer");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
|
|
if (this->timer_queue_ != 0)
|
|
return this->timer_queue_->cancel (timer_id,
|
|
arg,
|
|
dont_call_handle_close);
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> long
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::schedule_timer
|
|
(ACE_Event_Handler *handler,
|
|
const void *arg,
|
|
const ACE_Time_Value &delay_time,
|
|
const ACE_Time_Value &interval)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::schedule_timer");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
|
|
if (0 != this->timer_queue_)
|
|
return this->timer_queue_->schedule
|
|
(handler,
|
|
arg,
|
|
timer_queue_->gettimeofday () + delay_time,
|
|
interval);
|
|
|
|
errno = ESHUTDOWN;
|
|
return -1;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::reset_timer_interval
|
|
(long timer_id,
|
|
const ACE_Time_Value &interval)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::reset_timer_interval");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
|
|
if (0 != this->timer_queue_)
|
|
{
|
|
return this->timer_queue_->reset_interval (timer_id, interval);
|
|
}
|
|
|
|
errno = ESHUTDOWN;
|
|
return -1;
|
|
}
|
|
|
|
// Main event loop driver that blocks for <max_wait_time> before
|
|
// returning (will return earlier if I/O or signal events occur).
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handle_events
|
|
(ACE_Time_Value &max_wait_time)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::handle_events");
|
|
|
|
return this->handle_events (&max_wait_time);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handle_error (void)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::handle_error");
|
|
#if defined (ACE_LINUX) && defined (ERESTARTNOHAND)
|
|
int const error = errno; // Avoid multiple TSS accesses.
|
|
if (error == EINTR || error == ERESTARTNOHAND)
|
|
return this->restart_;
|
|
#else
|
|
if (errno == EINTR)
|
|
return this->restart_;
|
|
#endif /* ACE_LINUX && ERESTARTNOHAND */
|
|
#if defined (__MVS__) || defined (ACE_WIN32) || defined (ACE_VXWORKS)
|
|
// On MVS Open Edition and Win32, there can be a number of failure
|
|
// codes on a bad socket, so check_handles on anything other than
|
|
// EINTR. VxWorks doesn't even bother to always set errno on error
|
|
// in select (specifically, it doesn't return EBADF for bad FDs).
|
|
else
|
|
return this->check_handles ();
|
|
#else
|
|
else if (errno == EBADF)
|
|
return this->check_handles ();
|
|
else
|
|
return -1;
|
|
#endif /* __MVS__ || ACE_WIN32 */
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> void
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::notify_handle
|
|
(ACE_HANDLE handle,
|
|
ACE_Reactor_Mask mask,
|
|
ACE_Handle_Set &ready_mask,
|
|
ACE_Event_Handler *event_handler,
|
|
ACE_EH_PTMF ptmf)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::notify_handle");
|
|
// Check for removed handlers.
|
|
if (event_handler == 0)
|
|
return;
|
|
|
|
bool const reference_counting_required =
|
|
event_handler->reference_counting_policy ().value () ==
|
|
ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
|
|
|
|
// Call add_reference() if needed.
|
|
if (reference_counting_required)
|
|
{
|
|
event_handler->add_reference ();
|
|
}
|
|
|
|
int const status = (event_handler->*ptmf) (handle);
|
|
|
|
if (status < 0)
|
|
this->remove_handler_i (handle, mask);
|
|
else if (status > 0)
|
|
ready_mask.set_bit (handle);
|
|
|
|
// Call remove_reference() if needed.
|
|
if (reference_counting_required)
|
|
event_handler->remove_reference ();
|
|
}
|
|
|
|
// Perform GET, CLR, SET, and ADD operations on the select()
|
|
// Handle_Sets.
|
|
//
|
|
// GET = 1, Retrieve current value
|
|
// SET = 2, Set value of bits to new mask (changes the entire mask)
|
|
// ADD = 3, Bitwise "or" the value into the mask (only changes
|
|
// enabled bits)
|
|
// CLR = 4 Bitwise "and" the negation of the value out of the mask
|
|
// (only changes enabled bits)
|
|
//
|
|
// Returns the original mask.
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::mask_ops
|
|
(ACE_HANDLE handle,
|
|
ACE_Reactor_Mask mask,
|
|
int ops)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::mask_ops");
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1));
|
|
|
|
// If the handle is not suspended, then set the ops on the
|
|
// <wait_set_>, otherwise set the <suspend_set_>.
|
|
|
|
if (this->is_suspended_i (handle))
|
|
return this->bit_ops (handle, mask, this->suspend_set_, ops);
|
|
else
|
|
return this->bit_ops (handle, mask, this->wait_set_, ops);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> ACE_Event_Handler *
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::find_handler_i
|
|
(ACE_HANDLE handle)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::find_handler_i");
|
|
|
|
ACE_Event_Handler *event_handler = this->handler_rep_.find (handle);
|
|
|
|
if (event_handler)
|
|
{
|
|
event_handler->add_reference ();
|
|
}
|
|
|
|
return event_handler;
|
|
}
|
|
|
|
// Must be called with locks held.
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handler_i
|
|
(ACE_HANDLE handle,
|
|
ACE_Reactor_Mask mask,
|
|
ACE_Event_Handler **eh)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::handler_i");
|
|
ACE_Event_Handler *event_handler = this->handler_rep_.find (handle);
|
|
|
|
if (event_handler == 0)
|
|
return -1;
|
|
else
|
|
{
|
|
if ((ACE_BIT_ENABLED (mask, ACE_Event_Handler::READ_MASK)
|
|
|| ACE_BIT_ENABLED (mask, ACE_Event_Handler::ACCEPT_MASK))
|
|
&& this->wait_set_.rd_mask_.is_set (handle) == 0)
|
|
return -1;
|
|
if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::WRITE_MASK)
|
|
&& this->wait_set_.wr_mask_.is_set (handle) == 0)
|
|
return -1;
|
|
if (ACE_BIT_ENABLED (mask, ACE_Event_Handler::EXCEPT_MASK)
|
|
&& this->wait_set_.ex_mask_.is_set (handle) == 0)
|
|
return -1;
|
|
}
|
|
|
|
if (eh != 0)
|
|
{
|
|
*eh = event_handler;
|
|
event_handler->add_reference ();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Must be called with locks held
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::resume_i (ACE_HANDLE handle)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::resume_i");
|
|
if (this->handler_rep_.find (handle) == 0)
|
|
return -1;
|
|
|
|
if (this->suspend_set_.rd_mask_.is_set (handle))
|
|
{
|
|
this->wait_set_.rd_mask_.set_bit (handle);
|
|
this->suspend_set_.rd_mask_.clr_bit (handle);
|
|
}
|
|
if (this->suspend_set_.wr_mask_.is_set (handle))
|
|
{
|
|
this->wait_set_.wr_mask_.set_bit (handle);
|
|
this->suspend_set_.wr_mask_.clr_bit (handle);
|
|
}
|
|
if (this->suspend_set_.ex_mask_.is_set (handle))
|
|
{
|
|
this->wait_set_.ex_mask_.set_bit (handle);
|
|
this->suspend_set_.ex_mask_.clr_bit (handle);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// Must be called with locks held
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::suspend_i (ACE_HANDLE handle)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::suspend_i");
|
|
if (this->handler_rep_.find (handle) == 0)
|
|
return -1;
|
|
|
|
if (this->wait_set_.rd_mask_.is_set (handle))
|
|
{
|
|
this->suspend_set_.rd_mask_.set_bit (handle);
|
|
this->wait_set_.rd_mask_.clr_bit (handle);
|
|
}
|
|
if (this->wait_set_.wr_mask_.is_set (handle))
|
|
{
|
|
this->suspend_set_.wr_mask_.set_bit (handle);
|
|
this->wait_set_.wr_mask_.clr_bit (handle);
|
|
}
|
|
if (this->wait_set_.ex_mask_.is_set (handle))
|
|
{
|
|
this->suspend_set_.ex_mask_.set_bit (handle);
|
|
this->wait_set_.ex_mask_.clr_bit (handle);
|
|
}
|
|
|
|
// Kobi: we need to remove that handle from the
|
|
// dispatch set as well. We use that function with all the relevant
|
|
// masks - rd/wr/ex - all the mask. it is completely suspended
|
|
this->clear_dispatch_mask (handle, ACE_Event_Handler::RWE_MASK);
|
|
return 0;
|
|
}
|
|
|
|
// Must be called with locks held
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::is_suspended_i (ACE_HANDLE handle)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::is_suspended_i");
|
|
if (this->handler_rep_.find (handle) == 0)
|
|
return 0;
|
|
|
|
return this->suspend_set_.rd_mask_.is_set (handle) ||
|
|
this->suspend_set_.wr_mask_.is_set (handle) ||
|
|
this->suspend_set_.ex_mask_.is_set (handle);
|
|
|
|
}
|
|
|
|
// Must be called with locks held
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::register_handler_i
|
|
(ACE_HANDLE handle,
|
|
ACE_Event_Handler *event_handler,
|
|
ACE_Reactor_Mask mask)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::register_handler_i");
|
|
|
|
// Insert the <handle, event_handle> tuple into the Handler
|
|
// Repository.
|
|
return this->handler_rep_.bind (handle, event_handler, mask);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::remove_handler_i
|
|
(ACE_HANDLE handle,
|
|
ACE_Reactor_Mask mask)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::remove_handler_i");
|
|
|
|
// Unbind this handle.
|
|
return this->handler_rep_.unbind (handle, mask);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::work_pending
|
|
(const ACE_Time_Value &max_wait_time)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::work_pending");
|
|
|
|
ACE_Time_Value mwt (max_wait_time);
|
|
ACE_MT (ACE_Countdown_Time countdown (&mwt));
|
|
|
|
ACE_MT (ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN,
|
|
ace_mon,
|
|
this->token_,
|
|
-1));
|
|
|
|
if (this->deactivated_)
|
|
return 0;
|
|
|
|
// Update the countdown to reflect time waiting for the mutex.
|
|
ACE_MT (countdown.update ());
|
|
|
|
ACE_Time_Value timer_buf (0);
|
|
ACE_Time_Value *this_timeout =
|
|
this->timer_queue_->calculate_timeout (&mwt, &timer_buf);
|
|
|
|
// Check if we have timers to fire.
|
|
bool const timers_pending =
|
|
(this_timeout != 0 && *this_timeout != mwt ? true : false);
|
|
|
|
#ifdef ACE_WIN32
|
|
// This arg is ignored on Windows and causes pointer truncation
|
|
// warnings on 64-bit compiles.
|
|
int const width = 0;
|
|
#else
|
|
int const width = this->handler_rep_.max_handlep1 ();
|
|
#endif /* ACE_WIN32 */
|
|
|
|
ACE_Select_Reactor_Handle_Set fd_set;
|
|
fd_set.rd_mask_ = this->wait_set_.rd_mask_;
|
|
fd_set.wr_mask_ = this->wait_set_.wr_mask_;
|
|
fd_set.ex_mask_ = this->wait_set_.ex_mask_;
|
|
|
|
int const nfds = ACE_OS::select (width,
|
|
fd_set.rd_mask_,
|
|
fd_set.wr_mask_,
|
|
fd_set.ex_mask_,
|
|
this_timeout);
|
|
|
|
// If timers are pending, override any timeout from the select()
|
|
// call.
|
|
return (nfds == 0 && timers_pending ? 1 : nfds);
|
|
}
|
|
|
|
// Must be called with lock held.
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::wait_for_multiple_events
|
|
(ACE_Select_Reactor_Handle_Set &dispatch_set,
|
|
ACE_Time_Value *max_wait_time)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::wait_for_multiple_events");
|
|
ACE_Time_Value timer_buf (0);
|
|
ACE_Time_Value *this_timeout = 0;
|
|
|
|
int number_of_active_handles = this->any_ready (dispatch_set);
|
|
|
|
// If there are any bits enabled in the <ready_set_> then we'll
|
|
// handle those first, otherwise we'll block in <select>.
|
|
|
|
if (number_of_active_handles == 0)
|
|
{
|
|
do
|
|
{
|
|
if (this->timer_queue_ == 0)
|
|
return 0;
|
|
|
|
this_timeout =
|
|
this->timer_queue_->calculate_timeout (max_wait_time,
|
|
&timer_buf);
|
|
#ifdef ACE_WIN32
|
|
// This arg is ignored on Windows and causes pointer
|
|
// truncation warnings on 64-bit compiles.
|
|
int const width = 0;
|
|
#else
|
|
int const width = this->handler_rep_.max_handlep1 ();
|
|
#endif /* ACE_WIN32 */
|
|
|
|
dispatch_set.rd_mask_ = this->wait_set_.rd_mask_;
|
|
dispatch_set.wr_mask_ = this->wait_set_.wr_mask_;
|
|
dispatch_set.ex_mask_ = this->wait_set_.ex_mask_;
|
|
number_of_active_handles = ACE_OS::select (width,
|
|
dispatch_set.rd_mask_,
|
|
dispatch_set.wr_mask_,
|
|
dispatch_set.ex_mask_,
|
|
this_timeout);
|
|
}
|
|
while (number_of_active_handles == -1 && this->handle_error () > 0);
|
|
|
|
if (number_of_active_handles > 0)
|
|
{
|
|
#if !defined (ACE_WIN32)
|
|
// Resynchronize the fd_sets so their "max" is set properly.
|
|
dispatch_set.rd_mask_.sync (this->handler_rep_.max_handlep1 ());
|
|
dispatch_set.wr_mask_.sync (this->handler_rep_.max_handlep1 ());
|
|
dispatch_set.ex_mask_.sync (this->handler_rep_.max_handlep1 ());
|
|
#endif /* ACE_WIN32 */
|
|
}
|
|
else if (number_of_active_handles == -1)
|
|
{
|
|
// Normally, select() will reset the bits in dispatch_set
|
|
// so that only those filed descriptors that are ready will
|
|
// have bits set. However, when an error occurs, the bit
|
|
// set remains as it was when the select call was first made.
|
|
// Thus, we now have a dispatch_set that has every file
|
|
// descriptor that was originally waited for, which is not
|
|
// correct. We must clear all the bit sets because we
|
|
// have no idea if any of the file descriptors is ready.
|
|
//
|
|
// NOTE: We dont have a test case to reproduce this
|
|
// problem. But pleae dont ignore this and remove it off.
|
|
dispatch_set.rd_mask_.reset ();
|
|
dispatch_set.wr_mask_.reset ();
|
|
dispatch_set.ex_mask_.reset ();
|
|
}
|
|
}
|
|
|
|
// Return the number of events to dispatch.
|
|
return number_of_active_handles;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch_timer_handlers
|
|
(int &number_of_handlers_dispatched)
|
|
{
|
|
number_of_handlers_dispatched += this->timer_queue_->expire ();
|
|
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch_notification_handlers
|
|
(ACE_Select_Reactor_Handle_Set &dispatch_set,
|
|
int &number_of_active_handles,
|
|
int &number_of_handlers_dispatched)
|
|
{
|
|
// Check to see if the ACE_HANDLE associated with the
|
|
// Select_Reactor's notify hook is enabled. If so, it means that
|
|
// one or more other threads are trying to update the
|
|
// ACE_Select_Reactor_T's internal tables or the notify pipe is
|
|
// enabled. We'll handle all these threads and notifications, and
|
|
// then break out to continue the event loop.
|
|
int const n =
|
|
this->notify_handler_->dispatch_notifications (number_of_active_handles,
|
|
dispatch_set.rd_mask_);
|
|
|
|
if (n == -1)
|
|
return -1;
|
|
else
|
|
{
|
|
number_of_handlers_dispatched += n;
|
|
number_of_active_handles -= n;
|
|
}
|
|
|
|
// Same as dispatch_timer_handlers
|
|
// No need to do anything with the state changed. That is because
|
|
// unbind already handles the case where someone unregister some
|
|
// kind of handle and unbind it. (::unbind calls the function
|
|
// state_changed () to reflect ant change with that)
|
|
// return this->state_changed_ ? -1 : 0;
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch_io_set
|
|
(int number_of_active_handles,
|
|
int &number_of_handlers_dispatched,
|
|
int mask,
|
|
ACE_Handle_Set &dispatch_mask,
|
|
ACE_Handle_Set &ready_mask,
|
|
ACE_EH_PTMF callback)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::dispatch_io_set");
|
|
ACE_HANDLE handle;
|
|
|
|
ACE_Handle_Set_Iterator handle_iter (dispatch_mask);
|
|
|
|
while ((handle = handle_iter ()) != ACE_INVALID_HANDLE &&
|
|
number_of_handlers_dispatched < number_of_active_handles)
|
|
{
|
|
++number_of_handlers_dispatched;
|
|
|
|
this->notify_handle (handle,
|
|
mask,
|
|
ready_mask,
|
|
this->handler_rep_.find (handle),
|
|
callback);
|
|
|
|
// clear the bit from that dispatch mask,
|
|
// so when we need to restart the iteration (rebuilding the iterator...)
|
|
// we will not dispatch the already dispatched handlers
|
|
this->clear_dispatch_mask (handle, mask);
|
|
|
|
if (this->state_changed_)
|
|
{
|
|
|
|
handle_iter.reset_state ();
|
|
this->state_changed_ = false;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch_io_handlers
|
|
(ACE_Select_Reactor_Handle_Set &dispatch_set,
|
|
int &number_of_active_handles,
|
|
int &number_of_handlers_dispatched)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::dispatch_io_handlers");
|
|
|
|
// Handle output events (this code needs to come first to handle the
|
|
// obscure case of piggy-backed data coming along with the final
|
|
// handshake message of a nonblocking connection).
|
|
|
|
if (this->dispatch_io_set (number_of_active_handles,
|
|
number_of_handlers_dispatched,
|
|
ACE_Event_Handler::WRITE_MASK,
|
|
dispatch_set.wr_mask_,
|
|
this->ready_set_.wr_mask_,
|
|
&ACE_Event_Handler::handle_output) == -1)
|
|
{
|
|
number_of_active_handles -= number_of_handlers_dispatched;
|
|
return -1;
|
|
}
|
|
|
|
// ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Select_Reactor_T::dispatch - EXCEPT\n")));
|
|
if (this->dispatch_io_set (number_of_active_handles,
|
|
number_of_handlers_dispatched,
|
|
ACE_Event_Handler::EXCEPT_MASK,
|
|
dispatch_set.ex_mask_,
|
|
this->ready_set_.ex_mask_,
|
|
&ACE_Event_Handler::handle_exception) == -1)
|
|
{
|
|
number_of_active_handles -= number_of_handlers_dispatched;
|
|
return -1;
|
|
}
|
|
|
|
// ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("ACE_Select_Reactor_T::dispatch - READ\n")));
|
|
if (this->dispatch_io_set (number_of_active_handles,
|
|
number_of_handlers_dispatched,
|
|
ACE_Event_Handler::READ_MASK,
|
|
dispatch_set.rd_mask_,
|
|
this->ready_set_.rd_mask_,
|
|
&ACE_Event_Handler::handle_input) == -1)
|
|
{
|
|
number_of_active_handles -= number_of_handlers_dispatched;
|
|
return -1;
|
|
}
|
|
|
|
number_of_active_handles -= number_of_handlers_dispatched;
|
|
return 0;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dispatch
|
|
(int active_handle_count,
|
|
ACE_Select_Reactor_Handle_Set &dispatch_set)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::dispatch");
|
|
|
|
int io_handlers_dispatched = 0;
|
|
int other_handlers_dispatched = 0;
|
|
int signal_occurred = 0;
|
|
// The following do/while loop keeps dispatching as long as there
|
|
// are still active handles. Note that the only way we should ever
|
|
// iterate more than once through this loop is if signals occur
|
|
// while we're dispatching other handlers.
|
|
|
|
do
|
|
{
|
|
// We expect that the loop will decrease the number of active
|
|
// handles in each iteration. If it does not, then something is
|
|
// inconsistent in the state of the Reactor and we should avoid
|
|
// the loop. Please read the comments on bug 2540 for more
|
|
// details.
|
|
int initial_handle_count = active_handle_count;
|
|
|
|
// Note that we keep track of changes to our state. If any of
|
|
// the dispatch_*() methods below return -1 it means that the
|
|
// <wait_set_> state has changed as the result of an
|
|
// <ACE_Event_Handler> being dispatched. This means that we
|
|
// need to bail out and rerun the select() loop since our
|
|
// existing notion of handles in <dispatch_set> may no longer be
|
|
// correct.
|
|
//
|
|
// In the beginning, our state starts out unchanged. After
|
|
// every iteration (i.e., due to signals), our state starts out
|
|
// unchanged again.
|
|
|
|
this->state_changed_ = false;
|
|
|
|
// Perform the Template Method for dispatching all the handlers.
|
|
|
|
// First check for interrupts.
|
|
if (active_handle_count == -1)
|
|
{
|
|
// Bail out -- we got here since <select> was interrupted.
|
|
if (ACE_Sig_Handler::sig_pending () != 0)
|
|
{
|
|
ACE_Sig_Handler::sig_pending (0);
|
|
|
|
// If any HANDLES in the <ready_set_> are activated as a
|
|
// result of signals they should be dispatched since
|
|
// they may be time critical...
|
|
active_handle_count = this->any_ready (dispatch_set);
|
|
|
|
// Record the fact that the Reactor has dispatched a
|
|
// handle_signal() method. We need this to return the
|
|
// appropriate count below.
|
|
signal_occurred = 1;
|
|
}
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
// Handle timers early since they may have higher latency
|
|
// constraints than I/O handlers. Ideally, the order of
|
|
// dispatching should be a strategy...
|
|
else if (this->dispatch_timer_handlers (other_handlers_dispatched) == -1)
|
|
// State has changed or timer queue has failed, exit loop.
|
|
break;
|
|
|
|
// Check to see if there are no more I/O handles left to
|
|
// dispatch AFTER we've handled the timers...
|
|
else if (active_handle_count == 0)
|
|
return io_handlers_dispatched
|
|
+ other_handlers_dispatched
|
|
+ signal_occurred;
|
|
|
|
// Next dispatch the notification handlers (if there are any to
|
|
// dispatch). These are required to handle multi-threads that
|
|
// are trying to update the <Reactor>.
|
|
|
|
else if (this->dispatch_notification_handlers
|
|
(dispatch_set,
|
|
active_handle_count,
|
|
other_handlers_dispatched) == -1)
|
|
// State has changed or a serious failure has occured, so exit
|
|
// loop.
|
|
break;
|
|
|
|
// Finally, dispatch the I/O handlers.
|
|
else if (this->dispatch_io_handlers
|
|
(dispatch_set,
|
|
active_handle_count,
|
|
io_handlers_dispatched) == -1)
|
|
// State has changed, so exit loop.
|
|
break;
|
|
|
|
// if state changed, we need to re-eval active_handle_count,
|
|
// so we will not end with an endless loop
|
|
if (initial_handle_count == active_handle_count
|
|
|| this->state_changed_)
|
|
{
|
|
active_handle_count = this->any_ready (dispatch_set);
|
|
}
|
|
}
|
|
while (active_handle_count > 0);
|
|
|
|
return io_handlers_dispatched + other_handlers_dispatched + signal_occurred;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::release_token (void)
|
|
{
|
|
#if defined (ACE_WIN32)
|
|
this->token_.release ();
|
|
return (int) EXCEPTION_CONTINUE_SEARCH;
|
|
#else
|
|
return 0;
|
|
#endif /* ACE_WIN32 */
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handle_events
|
|
(ACE_Time_Value *max_wait_time)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::handle_events");
|
|
|
|
// Stash the current time -- the destructor of this object will
|
|
// automatically compute how much time elapsed since this method was
|
|
// called.
|
|
ACE_Countdown_Time countdown (max_wait_time);
|
|
|
|
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
|
|
|
|
ACE_GUARD_RETURN (ACE_SELECT_REACTOR_TOKEN, ace_mon, this->token_, -1);
|
|
|
|
if (ACE_OS::thr_equal (ACE_Thread::self (), this->owner_) == 0)
|
|
{
|
|
errno = EACCES;
|
|
return -1;
|
|
}
|
|
if (this->deactivated_)
|
|
{
|
|
errno = ESHUTDOWN;
|
|
return -1;
|
|
}
|
|
|
|
// Update the countdown to reflect time waiting for the mutex.
|
|
countdown.update ();
|
|
#else
|
|
if (this->deactivated_)
|
|
{
|
|
errno = ESHUTDOWN;
|
|
return -1;
|
|
}
|
|
#endif /* ACE_MT_SAFE */
|
|
|
|
return this->handle_events_i (max_wait_time);
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::handle_events_i
|
|
(ACE_Time_Value *max_wait_time)
|
|
{
|
|
int result = -1;
|
|
|
|
ACE_SEH_TRY
|
|
{
|
|
// We use the data member dispatch_set_ as the current dispatch
|
|
// set.
|
|
|
|
// We need to start from a clean dispatch_set
|
|
this->dispatch_set_.rd_mask_.reset ();
|
|
this->dispatch_set_.wr_mask_.reset ();
|
|
this->dispatch_set_.ex_mask_.reset ();
|
|
|
|
int number_of_active_handles =
|
|
this->wait_for_multiple_events (this->dispatch_set_,
|
|
max_wait_time);
|
|
|
|
result =
|
|
this->dispatch (number_of_active_handles,
|
|
this->dispatch_set_);
|
|
}
|
|
ACE_SEH_EXCEPT (this->release_token ())
|
|
{
|
|
// As it stands now, we catch and then rethrow all Win32
|
|
// structured exceptions so that we can make sure to release the
|
|
// <token_> lock correctly.
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> int
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::check_handles (void)
|
|
{
|
|
ACE_TRACE ("ACE_Select_Reactor_T::check_handles");
|
|
|
|
#if defined (ACE_WIN32) || defined (__MVS__) || defined (ACE_VXWORKS)
|
|
ACE_Time_Value time_poll = ACE_Time_Value::zero;
|
|
ACE_Handle_Set rd_mask;
|
|
#endif /* ACE_WIN32 || MVS || ACE_VXWORKS */
|
|
|
|
int result = 0;
|
|
|
|
/*
|
|
* It's easier to run through the handler repository iterator, but that
|
|
* misses handles that are registered on a handler that doesn't implement
|
|
* get_handle(). So, build a handle set that's the union of the three
|
|
* wait_sets (rd, wrt, ex) and run through that. Bad handles get cleared
|
|
* out of all sets.
|
|
*/
|
|
ACE_HANDLE h;
|
|
ACE_Handle_Set check_set (this->wait_set_.rd_mask_);
|
|
ACE_Handle_Set_Iterator wr_iter (this->wait_set_.wr_mask_);
|
|
while ((h = wr_iter ()) != ACE_INVALID_HANDLE)
|
|
check_set.set_bit (h);
|
|
ACE_Handle_Set_Iterator ex_iter (this->wait_set_.ex_mask_);
|
|
while ((h = ex_iter ()) != ACE_INVALID_HANDLE)
|
|
check_set.set_bit (h);
|
|
|
|
ACE_Handle_Set_Iterator check_iter (check_set);
|
|
while ((h = check_iter ()) != ACE_INVALID_HANDLE)
|
|
{
|
|
|
|
#if defined (ACE_WIN32) || defined (__MVS__) || defined (ACE_VXWORKS)
|
|
// Win32 needs to do the check this way because fstat won't work on
|
|
// a socket handle. MVS Open Edition needs to do it this way because,
|
|
// even though the docs say to check a handle with either select or
|
|
// fstat, the fstat method always says the handle is ok.
|
|
// pSOS needs to do it this way because file handles and socket handles
|
|
// are maintained by separate pieces of the system. VxWorks needs the select
|
|
// variant since fstat always returns an error on socket FDs.
|
|
rd_mask.set_bit (h);
|
|
|
|
# if defined (ACE_WIN32)
|
|
// This arg is ignored on Windows and causes pointer truncation
|
|
// warnings on 64-bit compiles.
|
|
int select_width = 0;
|
|
# else
|
|
int select_width = int (h) + 1;
|
|
# endif /* ACE_WIN32 */
|
|
|
|
if (ACE_OS::select (select_width,
|
|
rd_mask, 0, 0,
|
|
&time_poll) < 0)
|
|
{
|
|
result = 1;
|
|
this->remove_handler_i (h, ACE_Event_Handler::ALL_EVENTS_MASK);
|
|
this->wait_set_.rd_mask_.clr_bit (h);
|
|
this->wait_set_.wr_mask_.clr_bit (h);
|
|
this->wait_set_.ex_mask_.clr_bit (h);
|
|
}
|
|
rd_mask.clr_bit (h);
|
|
#else /* !ACE_WIN32 && !MVS && !VXWORKS */
|
|
struct stat temp;
|
|
|
|
if (ACE_OS::fstat (h, &temp) == -1)
|
|
{
|
|
result = 1;
|
|
this->remove_handler_i (h, ACE_Event_Handler::ALL_EVENTS_MASK);
|
|
}
|
|
#endif /* ACE_WIN32 || MVS */
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
template <class ACE_SELECT_REACTOR_TOKEN> void
|
|
ACE_Select_Reactor_T<ACE_SELECT_REACTOR_TOKEN>::dump (void) const
|
|
{
|
|
#if defined (ACE_HAS_DUMP)
|
|
ACE_TRACE ("ACE_Select_Reactor_T::dump");
|
|
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
|
|
|
|
this->timer_queue_->dump ();
|
|
this->handler_rep_.dump ();
|
|
this->signal_handler_->dump ();
|
|
ACELIB_DEBUG ((LM_DEBUG,
|
|
ACE_TEXT ("delete_signal_handler_ = %d\n"),
|
|
this->delete_signal_handler_));
|
|
|
|
ACE_HANDLE h;
|
|
|
|
for (ACE_Handle_Set_Iterator handle_iter_wr (this->wait_set_.wr_mask_);
|
|
(h = handle_iter_wr ()) != ACE_INVALID_HANDLE;)
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("write_handle = %d\n"), h));
|
|
|
|
for (ACE_Handle_Set_Iterator handle_iter_rd (this->wait_set_.rd_mask_);
|
|
(h = handle_iter_rd ()) != ACE_INVALID_HANDLE;)
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("read_handle = %d\n"), h));
|
|
|
|
for (ACE_Handle_Set_Iterator handle_iter_ex (this->wait_set_.ex_mask_);
|
|
(h = handle_iter_ex ()) != ACE_INVALID_HANDLE;)
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("except_handle = %d\n"), h));
|
|
|
|
for (ACE_Handle_Set_Iterator handle_iter_wr_ready (this->ready_set_.wr_mask_);
|
|
(h = handle_iter_wr_ready ()) != ACE_INVALID_HANDLE;)
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("write_handle_ready = %d\n"), h));
|
|
|
|
for (ACE_Handle_Set_Iterator handle_iter_rd_ready (this->ready_set_.rd_mask_);
|
|
(h = handle_iter_rd_ready ()) != ACE_INVALID_HANDLE;)
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("read_handle_ready = %d\n"), h));
|
|
|
|
for (ACE_Handle_Set_Iterator handle_iter_ex_ready (this->ready_set_.ex_mask_);
|
|
(h = handle_iter_ex_ready ()) != ACE_INVALID_HANDLE;)
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("except_handle_ready = %d\n"), h));
|
|
|
|
for (ACE_Handle_Set_Iterator handle_iter_su_ready (this->suspend_set_.wr_mask_);
|
|
(h = handle_iter_su_ready ()) != ACE_INVALID_HANDLE;)
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("write_handle_suspend = %d\n"), h));
|
|
|
|
for (ACE_Handle_Set_Iterator handle_iter_su_ready (this->suspend_set_.rd_mask_);
|
|
(h = handle_iter_su_ready ()) != ACE_INVALID_HANDLE;)
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("read_handle_suspend = %d\n"), h));
|
|
|
|
for (ACE_Handle_Set_Iterator handle_iter_su_ready (this->suspend_set_.ex_mask_);
|
|
(h = handle_iter_su_ready ()) != ACE_INVALID_HANDLE;)
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("except_handle_suspend = %d\n"), h));
|
|
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("restart_ = %d\n"), this->restart_));
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("requeue_position_ = %d\n"), this->requeue_position_));
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("initialized_ = %d\n"), this->initialized_));
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("owner_ = %d\n"), this->owner_));
|
|
|
|
#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
|
|
this->notify_handler_->dump ();
|
|
this->token_.dump ();
|
|
#endif /* ACE_MT_SAFE */
|
|
|
|
ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
|
|
#endif /* ACE_HAS_DUMP */
|
|
}
|
|
|
|
ACE_END_VERSIONED_NAMESPACE_DECL
|
|
|
|
#endif /* ACE_SELECT_REACTOR_T_CPP */
|