// -*- C++ -*- // // $Id: Dev_Poll_Reactor.inl 85615 2009-06-12 01:21:57Z shuston $ #include "ace/Log_Msg.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE ACE_Dev_Poll_Reactor::Event_Tuple::Event_Tuple (ACE_Event_Handler *eh, ACE_Reactor_Mask m, bool is_suspended, bool is_controlled) : event_handler (eh), mask (m), suspended (is_suspended), controlled (is_controlled) { } // --------------------------------------------------------------------- #if 0 ACE_INLINE ACE_Dev_Poll_Ready_Set::ACE_Dev_Poll_Ready_Set (void) : pfds (0), nfds (0) { } #endif /* 0 */ // --------------------------------------------------------------------- ACE_INLINE size_t ACE_Dev_Poll_Reactor::Handler_Repository::size (void) const { ACE_TRACE ("ACE_Dev_Poll_Reactor::Handler_Repository::size"); return this->max_size_; } // ----------------------------------------------------------------- ACE_INLINE ACE_Dev_Poll_Handler_Guard::ACE_Dev_Poll_Handler_Guard (ACE_Event_Handler *eh, bool do_incr) : eh_ (eh), refcounted_ (false) { if (eh == 0) return; this->refcounted_ = eh->reference_counting_policy ().value () == ACE_Event_Handler::Reference_Counting_Policy::ENABLED; if (do_incr && this->refcounted_) eh->add_reference (); /** * The below comments were here when I replaced the old refcount * scheme was replaced. They may still need addressing. -Steve Huston */ /** * @todo Suspend the handler so that other threads will not cause * an event that is already in an upcall from being dispatched * again. * * @note The naive approach would be to simply call * suspend_handler_i() on the reactor. However, that would * cause a system call (write()) to occur. Obviously this * can potentially have an adverse affect on performance. * Ideally, the handler would only be marked as "suspended" in * the handler repository. If an event arrives for a * suspended handler that event can be "queued" in a * "handle readiness queue." "Queued" is quoted since a real * queue need not be used since duplicate events can be * coalesced, thus avoiding unbounded queue growth. Event * coalescing is already done by Linux's event poll driver * (/dev/epoll) so Solaris' poll driver (/dev/poll) is the * main concern here. The largest the queue can be is the * same size as the number of handlers stored in the handler * repository. */ } ACE_INLINE ACE_Dev_Poll_Handler_Guard::~ACE_Dev_Poll_Handler_Guard (void) { if (this->refcounted_ && this->eh_ != 0) this->eh_->remove_reference (); /** * The below comments were here when I replaced the old refcount * scheme was replaced. They may still need addressing. -Steve Huston */ /** * @todo Resume the handler so that other threads will be allowed to * dispatch the handler. */ } ACE_INLINE void ACE_Dev_Poll_Handler_Guard::release (void) { this->eh_ = 0; } // --------------------------------------------------------------------- ACE_INLINE int ACE_Dev_Poll_Reactor::upcall (ACE_Event_Handler *event_handler, int (ACE_Event_Handler::*callback)(ACE_HANDLE), ACE_HANDLE handle) { // If the handler returns positive value (requesting a reactor // callback) just call back as many times as the handler requests // it. The handler is suspended internally and other threads are off // handling other things. int status = 0; do { status = (event_handler->*callback) (handle); } while (status > 0); return status; } /************************************************************************/ // Methods for ACE_Dev_Poll_Reactor::Token_Guard /************************************************************************/ ACE_INLINE ACE_Dev_Poll_Reactor::Token_Guard::Token_Guard (ACE_Dev_Poll_Reactor_Token &token) : token_ (token), owner_ (0) { } ACE_INLINE ACE_Dev_Poll_Reactor::Token_Guard::~Token_Guard (void) { if (this->owner_ == 1) { ACE_MT (this->token_.release ()); this->owner_ = 0; } } ACE_INLINE void ACE_Dev_Poll_Reactor::Token_Guard::release_token (void) { if (this->owner_) { ACE_MT (this->token_.release ()); // We are not the owner anymore.. this->owner_ = 0; } } ACE_INLINE int ACE_Dev_Poll_Reactor::Token_Guard::is_owner (void) { return this->owner_; } ACE_END_VERSIONED_NAMESPACE_DECL