diff options
author | Steve Huston <shuston@riverace.com> | 2005-02-11 23:15:33 +0000 |
---|---|---|
committer | Steve Huston <shuston@riverace.com> | 2005-02-11 23:15:33 +0000 |
commit | abab2702843e3ed89c056c6d69aced34f2567ccc (patch) | |
tree | d26d335514d7f6f00414ccf7f2b48f8e7a707b91 | |
parent | 0f3488632f318d9d5cf9b1973789863f91bed72a (diff) | |
download | ATCD-abab2702843e3ed89c056c6d69aced34f2567ccc.tar.gz |
ChangeLogTag:Fri Feb 11 18:11:29 2005 Steve Huston <shuston@riverace.com>
-rw-r--r-- | ChangeLog | 46 | ||||
-rw-r--r-- | ace/Dev_Poll_Reactor.cpp | 126 | ||||
-rw-r--r-- | ace/Dev_Poll_Reactor.h | 97 | ||||
-rw-r--r-- | ace/Dev_Poll_Reactor.inl | 82 | ||||
-rw-r--r-- | ace/Reactor.cpp | 23 | ||||
-rw-r--r-- | tests/Dev_Poll_Reactor_Test.cpp | 15 | ||||
-rw-r--r-- | tests/MT_Reactor_Upcall_Test.cpp | 12 | ||||
-rw-r--r-- | tests/MT_Reference_Counted_Event_Handler_Test.cpp | 27 | ||||
-rw-r--r-- | tests/MT_Reference_Counted_Notify_Test.cpp | 82 | ||||
-rw-r--r-- | tests/Notify_Performance_Test.cpp | 19 |
10 files changed, 299 insertions, 230 deletions
diff --git a/ChangeLog b/ChangeLog index 89bafa42b19..d53bc4b0b3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,49 @@ +Fri Feb 11 18:11:29 2005 Steve Huston <shuston@riverace.com> + + * ace/Dev_Poll_Reactor.{h inl cpp}: + Comment out the check for epoll's proper Linux kernel version + based on linux/version.h. It's not always accurate. For example, + on Fedora Core 2 it says 2.4.20, yet the actual kernel is 2.6.5 + and epoll_ctl works fine (apparantly). + + Removed the original reference counting scheme based on the + handler repository and implemented the ACE_Event_Handler-based + scheme used by the other reactors. Kept the + ACE_Dev_Poll_Handler_Guard class, though, as it is very nice. + Just changed some contents and added a release() method to make it + easier to work with the notify case since the refcount is incremented + when the handler is queued for notify and decremented after the + later upcall is done. + + (wakeup_all_threads): Removed the #if 0 block around the notify() + call. This works fine (and is necessary) for epoll-capable systems. + + (handle_events_i, dispatch): Moved the signal-dispatched detection + to handle_events_i() from dispatch() and allowed a dispatched signal + to count as a dispatched event instead of always causing a + -1/EINTR return. + + (dispatch_io_events): Increment io_handlers_dispatched before + doing the upcall. Previously, it wouldn't get incremented if the + handler returned -1. + + * ace/Reactor.cpp: Added the ability to specify ACE_Dev_Poll_Reactor + as the default reactor implementation by specifying + ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL in the config file. + + * tests/Dev_Poll_Reactor_Test.cpp: Ignore SIGPIPE, else if the + receiving side closes its handle first, the sending side will crash + on SIGPIPE. Make the Client shut down its reactor if handle_output() + fails. Else, the timer will never fire again and the test will hang. + + * tests/MT_Reactor_Upcall_Test.cpp: + * tests/MT_Reference_Counted_Event_Handler_Test.cpp: + * tests/MT_Reference_Counted_Notify_Test.cpp: Added test for + ACE_Dev_Poll_Reactor using -d (defaults to 1) but only runs it + if ACE_HAS_EVENT_POLL is set. + For MT_Reference_Counted_Notify_Test, added checks to see that + the reference count actually gets incremented for the upcall. + Fri Feb 11 13:55:47 2005 J.T. Conklin <jtc@acorntoolworks.com> * configure.ac: diff --git a/ace/Dev_Poll_Reactor.cpp b/ace/Dev_Poll_Reactor.cpp index 83e5338990e..b8d8eb3530d 100644 --- a/ace/Dev_Poll_Reactor.cpp +++ b/ace/Dev_Poll_Reactor.cpp @@ -181,11 +181,13 @@ ACE_Dev_Poll_Reactor_Notify::notify (ACE_Event_Handler *eh, ACE_ASSERT (temp != 0); *temp = buffer; + ACE_Dev_Poll_Handler_Guard eh_guard (eh); + if (notify_queue_.enqueue_tail (temp) == -1) return -1; - // Let us send a notify for every message - // if (notification_required) + // Now pop the pipe to force the callback for dispatching when ready. + // @todo - this only needs to write one byte for ACE_HAS_NOTIFICATION_QUEUE. ssize_t n = ACE::send (this->notification_pipe_.write_handle (), (char *) &buffer, sizeof buffer, @@ -193,10 +195,17 @@ ACE_Dev_Poll_Reactor_Notify::notify (ACE_Event_Handler *eh, if (n == -1) return -1; + // Since the notify is queued (and maybe already delivered by now) + // we can simply release the guard. The dispatch of this notification + // will decrement the reference count. + eh_guard.release (); + return 0; #else ACE_Notification_Buffer buffer (eh, mask); + ACE_Dev_Poll_Handler_Guard eh_guard (eh); + ssize_t n = ACE::send (this->notification_pipe_.write_handle (), (char *) &buffer, sizeof buffer, @@ -204,6 +213,8 @@ ACE_Dev_Poll_Reactor_Notify::notify (ACE_Event_Handler *eh, if (n == -1) return -1; + eh_guard.release (); + return 0; #endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ } @@ -383,6 +394,7 @@ ACE_Dev_Poll_Reactor_Notify::dispatch_notify (ACE_Notification_Buffer &buffer) ACE_LIB_TEXT ("enqueue_head")), -1); } +#endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ // If eh == 0 then another thread is unblocking the // ACE_Dev_Poll_Reactor to update the ACE_Dev_Poll_Reactor's @@ -391,6 +403,10 @@ ACE_Dev_Poll_Reactor_Notify::dispatch_notify (ACE_Notification_Buffer &buffer) // pointer we've been passed. if (buffer.eh_ != 0) { + // Guard the handler's refcount. Recall that when the notify + // was queued, the refcount was incremented, so it need not be + // now. The guard insures that it is decremented properly. + ACE_Dev_Poll_Handler_Guard eh_guard (buffer.eh_, false); switch (buffer.mask_) { @@ -414,44 +430,6 @@ ACE_Dev_Poll_Reactor_Notify::dispatch_notify (ACE_Notification_Buffer &buffer) buffer.eh_->handle_close (ACE_INVALID_HANDLE, ACE_Event_Handler::EXCEPT_MASK); } -#else - // If eh == 0 then another thread is unblocking the - // ACE_Dev_Poll_Reactor to update the ACE_Dev_Poll_Reactor's - // internal structures. Otherwise, we need to dispatch the - // appropriate handle_* method on the ACE_Event_Handler - // pointer we've been passed. - if (buffer.eh_ != 0) - { - switch (buffer.mask_) - { - case ACE_Event_Handler::READ_MASK: - case ACE_Event_Handler::ACCEPT_MASK: - result = buffer.eh_->handle_input (ACE_INVALID_HANDLE); - break; - case ACE_Event_Handler::WRITE_MASK: - result = buffer.eh_->handle_output (ACE_INVALID_HANDLE); - break; - case ACE_Event_Handler::EXCEPT_MASK: - result = buffer.eh_->handle_exception (ACE_INVALID_HANDLE); - break; - case ACE_Event_Handler::QOS_MASK: - result = buffer.eh_->handle_qos (ACE_INVALID_HANDLE); - break; - case ACE_Event_Handler::GROUP_QOS_MASK: - result = buffer.eh_->handle_group_qos (ACE_INVALID_HANDLE); - break; - default: - // Should we bail out if we get an invalid mask? - ACE_ERROR ((LM_ERROR, - ACE_LIB_TEXT ("invalid mask = %d\n"), - buffer.mask_)); - } - if (result == -1) - buffer.eh_->handle_close (ACE_INVALID_HANDLE, - ACE_Event_Handler::EXCEPT_MASK); - } - -#endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */ return 1; } @@ -1189,7 +1167,21 @@ ACE_Dev_Poll_Reactor::handle_events_i (ACE_Time_Value *max_wait_time) if (result == 0 || (result == -1 && errno == ETIME)) return 0; else if (result == -1) - return -1; + { + if (errno != EINTR) + return -1; + + // Bail out -- we got here since the poll was interrupted. + // If it was due to a signal registered through our ACE_Sig_Handler, + // then it was dispatched, so we count it in the number of events + // handled rather than cause an error return. + if (ACE_Sig_Handler::sig_pending () != 0) + { + ACE_Sig_Handler::sig_pending (0); + return 1; + } + return -1; + } // Dispatch the events, if any. return this->dispatch (); @@ -1226,45 +1218,15 @@ ACE_Dev_Poll_Reactor::dispatch (void) // Perform the Template Method for dispatching all the handlers. - // First check for interrupts. - if (0 /* active_handle_count == -1 */) - { - // Bail out -- we got here since the poll (i.e. ioctl()) was - // interrupted. - if (ACE_Sig_Handler::sig_pending () != 0) - { - ACE_Sig_Handler::sig_pending (0); - -#if 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... - pfds = this->ready_set_.pfds; - active_handle_count = this->ready_set_.nfds; -#endif /* 0 */ - - // 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) + 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 (0 /* active_handle_count == 0 */) - return io_handlers_dispatched - + other_handlers_dispatched - + signal_occurred; #if 0 // Next dispatch the notification handlers (if there are any to @@ -1386,7 +1348,11 @@ ACE_Dev_Poll_Reactor::dispatch_io_events (int &io_handlers_dispatched) { // Modify the reference count in an exception-safe way. - ACE_Dev_Poll_Handler_Guard (this->handler_rep_, handle); + // Note that eh could be the notify handler. It's not strictly + // necessary to manage its refcount, but since we don't enable + // the counting policy, it won't do much. Management of the + // notified handlers themselves is done in the notify handler. + ACE_Dev_Poll_Handler_Guard eh_guard (eh); // Release the lock during the upcall. ACE_Reverse_Lock<ACE_SYNCH_MUTEX> reverse_lock (this->lock_); @@ -1402,6 +1368,8 @@ ACE_Dev_Poll_Reactor::dispatch_io_events (int &io_handlers_dispatched) if (ACE_BIT_ENABLED (revents, POLLOUT)) #endif /* ACE_HAS_EVENT_POLL */ { + ++io_handlers_dispatched; + const int status = this->upcall (eh, &ACE_Event_Handler::handle_output, handle); @@ -1412,8 +1380,6 @@ ACE_Dev_Poll_Reactor::dispatch_io_events (int &io_handlers_dispatched) return this->remove_handler (handle, ACE_Event_Handler::WRITE_MASK); } - - ++io_handlers_dispatched; } // Dispatch all "high priority" (e.g. out-of-band data) events. @@ -1423,6 +1389,8 @@ ACE_Dev_Poll_Reactor::dispatch_io_events (int &io_handlers_dispatched) if (ACE_BIT_ENABLED (revents, POLLPRI)) #endif /* ACE_HAS_EVENT_POLL */ { + ++io_handlers_dispatched; + const int status = this->upcall (eh, &ACE_Event_Handler::handle_exception, handle); @@ -1433,8 +1401,6 @@ ACE_Dev_Poll_Reactor::dispatch_io_events (int &io_handlers_dispatched) return this->remove_handler (handle, ACE_Event_Handler::EXCEPT_MASK); } - - ++io_handlers_dispatched; } // Dispatch all input events. @@ -1444,6 +1410,8 @@ ACE_Dev_Poll_Reactor::dispatch_io_events (int &io_handlers_dispatched) if (ACE_BIT_ENABLED (revents, POLLIN)) #endif /* ACE_HAS_EVENT_POLL */ { + ++io_handlers_dispatched; + const int status = this->upcall (eh, &ACE_Event_Handler::handle_input, handle); @@ -1454,8 +1422,6 @@ ACE_Dev_Poll_Reactor::dispatch_io_events (int &io_handlers_dispatched) return this->remove_handler (handle, ACE_Event_Handler::READ_MASK); } - - ++io_handlers_dispatched; } } // The reactor lock is reacquired upon leaving this scope. } @@ -2259,13 +2225,11 @@ ACE_Dev_Poll_Reactor::wakeup_all_threads (void) { ACE_TRACE ("ACE_Dev_Poll_Reactor::wakeup_all_threads"); -#if 0 // Send a notification, but don't block if there's no one to receive // it. this->notify (0, ACE_Event_Handler::NULL_MASK, (ACE_Time_Value *) &ACE_Time_Value::zero); -#endif /* 0 */ } int diff --git a/ace/Dev_Poll_Reactor.h b/ace/Dev_Poll_Reactor.h index 693a3005eb8..9d722650351 100644 --- a/ace/Dev_Poll_Reactor.h +++ b/ace/Dev_Poll_Reactor.h @@ -29,6 +29,8 @@ // The sys_epoll interface was introduced in Linux kernel 2.5.45. // Don't support backported versions since they appear to be buggy. // The obsolete ioctl()-based interface is no longer supported. +#if 0 +// linux/version.h may not be accurate. It's not for Fedora Core 2... # include /**/ <linux/version.h> # if LINUX_VERSION_CODE < KERNEL_VERSION (2,5,45) # undef ACE_HAS_EVENT_POLL @@ -36,6 +38,7 @@ # error Linux kernel 2.5.45 or better is required. # endif /* LINUX_VERSION_CODE < KERNEL_VERSION (2,5,45) */ #endif /* ACE_HAS_EVENT_POLL */ +#endif #if defined (ACE_HAS_EVENT_POLL) && defined (ACE_HAS_DEV_POLL) # error ACE_HAS_EVENT_POLL and ACE_HAS_DEV_POLL are mutually exclusive. @@ -55,7 +58,9 @@ class ACE_Sig_Handler; class ACE_Dev_Poll_Reactor; +#if defined (ACE_HAS_DEV_POLL) struct pollfd; +#endif /** * @class ACE_Dev_Poll_Event_Tuple @@ -91,23 +96,6 @@ public: /// Flag that states whether or not the event handler is suspended. char suspended; - - /// The number of outstanding upcalls occurring on the above event - /// handler. - /** - * @todo The reference count should really be maintained within the - * event handler. This approach was taken to allow for - * backward compatibility and quick implementation. One - * approach for maintaining backward compatibility while - * implementing reference counting within the event handler is - * to create an ACE_Ref_Counted_Event_Handler "mix-in" class - * that concrete ACE_Event_Handlers can inherit from - * (i.e. multiple inheritance). Thus, legacy non-reference - * counted event handlers need not pay for reference counting - * resources. - */ - unsigned long refcount; - }; // --------------------------------------------------------------------- @@ -188,10 +176,10 @@ public: /** * Called by a thread when it wants to unblock the Reactor_Impl. - * This wakeups the Reactor_Impl if currently blocked. Pass over - * both the Event_Handler *and* the mask to allow the caller to + * This wakes up the Reactor_Impl if currently blocked. Pass over + * both the Event_Handler and the mask to allow the caller to * dictate which Event_Handler method the Reactor_Impl will - * invoke. The ACE_Time_Value indicates how long to blocking + * invoke. The ACE_Time_Value indicates how long to block * trying to notify the Reactor_Impl. If timeout == 0, the * caller will block until action is possible, else will wait until * the relative time specified in *timeout elapses). @@ -215,16 +203,15 @@ public: /// the Reactor_Impl. virtual ACE_HANDLE notify_handle (void); - /// Verify whether the buffer has dispatchable info or not. + /// Verify whether the buffer has dispatchable info or not. virtual int is_dispatchable (ACE_Notification_Buffer &buffer); - /// Handle one of the notify call on the handle. This could be + /// Handle one notify call represented in @a buffer. This could be /// because of a thread trying to unblock the Reactor_Impl. virtual int dispatch_notify (ACE_Notification_Buffer &buffer); - /// Read one of the notify call on the handle into the - /// buffer. This could be because of a thread trying to unblock - /// the Reactor_Impl. + /// Read one notify call on the handle into @a buffer. + /// This could be because of a thread trying to unblock the Reactor_Impl. virtual int read_notify_pipe (ACE_HANDLE handle, ACE_Notification_Buffer &buffer); @@ -392,21 +379,6 @@ public: /// Remove all the (@c ACE_HANDLE, @c ACE_Event_Handler) tuples. int unbind_all (void); - /// Increase the reference count on the event handler corresponding - /// to the given file descriptor. - /** - * @return Returns the updated reference count. - */ - unsigned long add_ref (ACE_HANDLE handle); - - /// Decrease the reference count on the event handler corresponding - /// to the given file descriptor. - /** - * @return Returns the updated reference count. - */ - unsigned long remove_ref (ACE_HANDLE handle); - //@} - /** * @name Sanity Checking * @@ -499,7 +471,7 @@ public: ACE_Reactor_Notify *notify = 0, int mask_signals = 1); - /// Initialize ACE_Dev_Poll_Reactor with size "@a size." + /// Initialize ACE_Dev_Poll_Reactor with size @a size. /** * @note On Unix platforms, the @a size parameter should be as large * as the maximum number of file descriptors allowed for a @@ -759,9 +731,11 @@ public: * @see reset_timer_interval() * * @param event_handler event handler to schedule on reactor - * @param arg argument passed to the handle_timeout() method of event_handler - * @param delay time interval after which the timer will expire - * @param interval time interval after which the timer will be automatically rescheduled + * @param arg argument passed to the handle_timeout() method of + * event_handler. + * @param delay time interval after which the timer will expire. + * @param interval time interval for which the timer will be + * automatically rescheduled. * @return -1 on failure, a timer_id value on success */ virtual long schedule_timer (ACE_Event_Handler *event_handler, @@ -785,19 +759,19 @@ public: int dont_call_handle_close = 1); /** - * Cancel the single Event_Handler that matches the <timer_id> value - * (which was returned from the schedule method). If arg is + * Cancel the single event handler that matches the @a timer_id value + * (which was returned from the schedule method). If @a 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 + * argument passed in when the event handler was registered. This * makes it possible to free up the memory and avoid memory leaks. - * Returns 1 if cancellation succeeded and 0 if the <timer_id> + * Returns 1 if cancellation succeeded and 0 if the @a timer_id * wasn't found. */ virtual int cancel_timer (long timer_id, const void **arg = 0, int dont_call_handle_close = 1); - // = High-level Event_Handler scheduling operations + // = High-level event handler scheduling operations /// Add <masks_to_be_added> to the <event_handler>'s entry. /// <event_handler> must already have been registered. @@ -1185,12 +1159,14 @@ public: /// Constructor /** - * The constructor increments the reference count on the event - * handler corresponding to the given handle. + * The constructor checks to see if @a eh is a reference-counted handler and + * remember that for later. If @a eh is reference counted, its reference + * count is incremented unless @a do_incr is false. + * @a do_incr should be false if the reference count was incremented + * independently of this guard, for example, on a notify handler since + * the reference count is incremented when the notify is queued. */ - ACE_Dev_Poll_Handler_Guard ( - ACE_Dev_Poll_Reactor_Handler_Repository &repository, - ACE_HANDLE handle); + ACE_Dev_Poll_Handler_Guard (ACE_Event_Handler *eh, bool do_incr = true); /// Destructor /** @@ -1199,14 +1175,17 @@ public: */ ~ACE_Dev_Poll_Handler_Guard (void); + /// Release the event handler from this guard; when the destructor is + /// called, the handler's reference count will not be decremented. + void release (void); + private: - /// Reference to the handler repository containing the event handler - /// used during the upcall. - ACE_Dev_Poll_Reactor_Handler_Repository &repository_; + /// The event handler being managed. + ACE_Event_Handler *eh_; - /// Handle corresponding to the event being dispatched. - ACE_HANDLE handle_; + /// true if eh_ is a reference-counted handler. + bool refcounted_; }; diff --git a/ace/Dev_Poll_Reactor.inl b/ace/Dev_Poll_Reactor.inl index dfb3cb81707..4445b882b5a 100644 --- a/ace/Dev_Poll_Reactor.inl +++ b/ace/Dev_Poll_Reactor.inl @@ -8,8 +8,7 @@ ACE_INLINE ACE_Dev_Poll_Event_Tuple::ACE_Dev_Poll_Event_Tuple (void) : event_handler (0), mask (ACE_Event_Handler::NULL_MASK), - suspended (0), - refcount (1) + suspended (0) { } @@ -93,57 +92,29 @@ ACE_Dev_Poll_Reactor_Handler_Repository::size (void) const return this->max_size_; } -ACE_INLINE unsigned long -ACE_Dev_Poll_Reactor_Handler_Repository::add_ref (ACE_HANDLE handle) -{ - // ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::add_ref"); - - // Caller provides synchronization - - if (this->handle_in_range (handle)) - return this->handlers_[handle].refcount++; - - return 0; -} - -ACE_INLINE unsigned long -ACE_Dev_Poll_Reactor_Handler_Repository::remove_ref (ACE_HANDLE handle) -{ - // ACE_TRACE ("ACE_Dev_Poll_Reactor_Handler_Repository::remove_ref"); - - // Caller provides synchronization - - if (this->handle_in_range (handle)) - { - unsigned long & refcount = this->handlers_[handle].refcount; - - ACE_ASSERT (refcount > 0); - - refcount--; - - if (refcount != 0) - return refcount; - - // Reference count dropped to zero. Remove the event handler - // from the repository. - this->unbind (handle); - } - - return 0; -} - // ----------------------------------------------------------------- ACE_INLINE -ACE_Dev_Poll_Handler_Guard::ACE_Dev_Poll_Handler_Guard ( - ACE_Dev_Poll_Reactor_Handler_Repository &repository, - ACE_HANDLE handle) - : repository_ (repository), - handle_ (handle) +ACE_Dev_Poll_Handler_Guard::ACE_Dev_Poll_Handler_Guard + (ACE_Event_Handler *eh, + bool do_incr) + : eh_ (eh), + refcounted_ (false) { - // Caller must provide synchronization. + if (eh == 0) + return; - (void) repository.add_ref (handle); + 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 @@ -171,16 +142,25 @@ ACE_Dev_Poll_Handler_Guard::ACE_Dev_Poll_Handler_Guard ( ACE_INLINE ACE_Dev_Poll_Handler_Guard::~ACE_Dev_Poll_Handler_Guard (void) { - // Caller must provide synchronization. - - (void) this->repository_.remove_ref (this->handle_); + 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 diff --git a/ace/Reactor.cpp b/ace/Reactor.cpp index eec9855a892..c1287d30ae5 100644 --- a/ace/Reactor.cpp +++ b/ace/Reactor.cpp @@ -11,11 +11,16 @@ #if !defined (ACE_WIN32) \ || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) \ || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) \ - || defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) + || defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) \ + || defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL) # if defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) # include "ace/TP_Reactor.h" # else -# include "ace/Select_Reactor.h" +# if defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL) +# include "ace/Dev_Poll_Reactor.h" +# else +# include "ace/Select_Reactor.h" +# endif /* ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL */ # endif /* ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL */ #else /* We are on Win32 and we have winsock and ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL is not defined */ # if defined (ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL) @@ -50,14 +55,20 @@ ACE_Reactor::ACE_Reactor (ACE_Reactor_Impl *impl, #if !defined (ACE_WIN32) \ || !defined (ACE_HAS_WINSOCK2) || (ACE_HAS_WINSOCK2 == 0) \ || defined (ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL) \ - || defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) - #if defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) + || defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) \ + || defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL) +# if defined (ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL) ACE_NEW (impl, ACE_TP_Reactor); - #else +# else +# if defined (ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL) + ACE_NEW (impl, + ACE_Dev_Poll_Reactor); +# else ACE_NEW (impl, ACE_Select_Reactor); - #endif /* ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL */ +# endif /* ACE_USE_DEV_POLL_REACTOR_FOR_REACTOR_IMPL */ +# endif /* ACE_USE_TP_REACTOR_FOR_REACTOR_IMPL */ #else /* We are on Win32 and we have winsock and ACE_USE_SELECT_REACTOR_FOR_REACTOR_IMPL is not defined */ #if defined (ACE_USE_MSG_WFMO_REACTOR_FOR_REACTOR_IMPL) ACE_NEW (impl, diff --git a/tests/Dev_Poll_Reactor_Test.cpp b/tests/Dev_Poll_Reactor_Test.cpp index 99c54f07c83..7d851ca0842 100644 --- a/tests/Dev_Poll_Reactor_Test.cpp +++ b/tests/Dev_Poll_Reactor_Test.cpp @@ -29,6 +29,7 @@ ACE_RCSID (tests, #if defined (ACE_HAS_DEV_POLL) || defined (ACE_HAS_EVENT_POLL) +#include "ace/OS_NS_signal.h" #include "ace/Reactor.h" #include "ace/Dev_Poll_Reactor.h" @@ -153,13 +154,10 @@ Client::handle_timeout (const ACE_Time_Value &, const void *) ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) Expected client timeout occured at: %T\n"))); - int status = this->handle_output (this->get_handle ()); - if (status != 0) - return status; - this->call_count_++; - if (this->call_count_ > 10) + int status = this->handle_output (this->get_handle ()); + if (status == -1 || this->call_count_ > 10) { if (this->reactor ()->end_reactor_event_loop () == 0) ACE_DEBUG ((LM_INFO, @@ -503,6 +501,13 @@ run_main (int, ACE_TCHAR *[]) { ACE_START_TEST (ACE_TEXT ("Dev_Poll_Reactor_Test")); + // Make sure we ignore SIGPIPE + sigset_t sigsetNew[1]; + sigset_t sigsetOld[1]; + ACE_OS::sigemptyset (sigsetNew); + ACE_OS::sigaddset (sigsetNew, SIGPIPE); + ACE_OS::sigprocmask (SIG_BLOCK, sigsetNew, sigsetOld); + ACE_Dev_Poll_Reactor dp_reactor; ACE_Reactor reactor (&dp_reactor); diff --git a/tests/MT_Reactor_Upcall_Test.cpp b/tests/MT_Reactor_Upcall_Test.cpp index 3c965a3796f..49c203b5f2c 100644 --- a/tests/MT_Reactor_Upcall_Test.cpp +++ b/tests/MT_Reactor_Upcall_Test.cpp @@ -24,6 +24,7 @@ #include "ace/Reactor.h" #include "ace/TP_Reactor.h" #include "ace/WFMO_Reactor.h" +#include "ace/Dev_Poll_Reactor.h" #include "ace/Pipe.h" #include "ace/Task.h" #include "ace/Get_Opt.h" @@ -330,6 +331,17 @@ run_main (int argc, ACE_TCHAR *argv[]) test_reactor_upcall (tp_reactor); +#if defined (ACE_HAS_EVENT_POLL) + + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing Dev Poll Reactor\n"))); + + ACE_Dev_Poll_Reactor dev_poll_reactor_impl; + ACE_Reactor dev_poll_reactor (&dev_poll_reactor_impl); + + test_reactor_upcall (dev_poll_reactor); + +#endif /* ACE_HAS_EVENT_POLL */ + #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Testing WFMO Reactor\n"))); diff --git a/tests/MT_Reference_Counted_Event_Handler_Test.cpp b/tests/MT_Reference_Counted_Event_Handler_Test.cpp index c77d2616fea..e2f5fa5a23b 100644 --- a/tests/MT_Reference_Counted_Event_Handler_Test.cpp +++ b/tests/MT_Reference_Counted_Event_Handler_Test.cpp @@ -12,8 +12,8 @@ // // This test tries to represents what happens in the ORB wrt to // event handlers, reactors, timer queues, threads, and connection -// caches, minus the other complexities. The following three -// Reactors are tested: Select, TP, and WFMO. +// caches, minus the other complexities. The following reactors +// are tested: Select, TP, WFMO, and Dev Poll (if enabled). // // The test checks proper use and shutting down of client-side // event handlers when it is used by invocation threads and/or @@ -32,6 +32,7 @@ #include "ace/Select_Reactor.h" #include "ace/TP_Reactor.h" #include "ace/WFMO_Reactor.h" +#include "ace/Dev_Poll_Reactor.h" #include "ace/Get_Opt.h" #include "ace/Task.h" #include "ace/SOCK_Acceptor.h" @@ -51,6 +52,7 @@ static const int message_size = 26; static int test_select_reactor = 1; static int test_tp_reactor = 1; static int test_wfmo_reactor = 1; +static int test_dev_poll_reactor = 1; static int debug = 0; static int number_of_connections = 5; static int max_nested_upcall_level = 10; @@ -1217,7 +1219,7 @@ test<REACTOR_IMPL>::test (int ignore_nested_upcalls, static int parse_args (int argc, ACE_TCHAR *argv[]) { - ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("a:b:c:f:g:k:l:m:n:o:uz:")); + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("a:b:c:d:f:g:k:l:m:n:o:uz:")); int cc; while ((cc = get_opt ()) != -1) @@ -1233,6 +1235,9 @@ parse_args (int argc, ACE_TCHAR *argv[]) case 'c': test_wfmo_reactor = ACE_OS::atoi (get_opt.opt_arg ()); break; + case 'd': + test_dev_poll_reactor = ACE_OS::atoi (get_opt.opt_arg ()); + break; case 'f': number_of_connections = ACE_OS::atoi (get_opt.opt_arg ()); break; @@ -1264,6 +1269,7 @@ parse_args (int argc, ACE_TCHAR *argv[]) ACE_TEXT ("\t[-a test Select Reactor] (defaults to %d)\n") ACE_TEXT ("\t[-b test TP Reactor] (defaults to %d)\n") ACE_TEXT ("\t[-c test WFMO Reactor] (defaults to %d)\n") + ACE_TEXT ("\t[-d test Dev Poll Reactor] (defaults to %d)\n") ACE_TEXT ("\t[-f number of connections] (defaults to %d)\n") ACE_TEXT ("\t[-g close timeout] (defaults to %d)\n") ACE_TEXT ("\t[-k make invocations] (defaults to %d)\n") @@ -1277,6 +1283,7 @@ parse_args (int argc, ACE_TCHAR *argv[]) test_select_reactor, test_tp_reactor, test_wfmo_reactor, + test_dev_poll_reactor, number_of_connections, close_timeout, make_invocations, @@ -1341,6 +1348,20 @@ run_main (int argc, ACE_TCHAR *argv[]) ACE_UNUSED_ARG (test); } +#if defined (ACE_HAS_EVENT_POLL) + + if (test_dev_poll_reactor) + { + ACE_DEBUG ((LM_DEBUG, + "\n\nTesting Dev Poll Reactor....\n\n")); + + test<ACE_Dev_Poll_Reactor> test (perform_nested_upcalls, + event_loop_thread_not_required); + ACE_UNUSED_ARG (test); + } + +#endif + #if defined (ACE_WIN32) if (test_wfmo_reactor) diff --git a/tests/MT_Reference_Counted_Notify_Test.cpp b/tests/MT_Reference_Counted_Notify_Test.cpp index b861c814202..ef0a0a52b31 100644 --- a/tests/MT_Reference_Counted_Notify_Test.cpp +++ b/tests/MT_Reference_Counted_Notify_Test.cpp @@ -24,6 +24,7 @@ #include "ace/Select_Reactor.h" #include "ace/TP_Reactor.h" #include "ace/WFMO_Reactor.h" +#include "ace/Dev_Poll_Reactor.h" #include "ace/Task.h" #include "ace/Get_Opt.h" @@ -34,6 +35,7 @@ ACE_RCSID(tests, MT_Reference_Counted_Notify_Test, "$Id$") static int test_select_reactor = 1; static int test_tp_reactor = 1; static int test_wfmo_reactor = 1; +static int test_dev_poll_reactor = 1; static int test_empty_notify = 1; static int test_simple_notify = 1; static int test_reference_counted_notify = 1; @@ -62,26 +64,46 @@ Reference_Counted_Event_Handler::Reference_Counted_Event_Handler (void) (ACE_Event_Handler::Reference_Counting_Policy::ENABLED); if (debug) - ACE_DEBUG ((LM_DEBUG, - "Reference count in Reference_Counted_Event_Handler() is %d\n", - this->reference_count_.value ())); + ACE_DEBUG + ((LM_DEBUG, + ACE_TEXT ("Reference count in Reference_Counted_Event_Handler() ") + ACE_TEXT ("is %d\n"), + this->reference_count_.value ())); } Reference_Counted_Event_Handler::~Reference_Counted_Event_Handler (void) { if (debug) - ACE_DEBUG ((LM_DEBUG, - "Reference count in ~Reference_Counted_Event_Handler() is %d\n", - this->reference_count_.value ())); + ACE_DEBUG + ((LM_DEBUG, + ACE_TEXT ("Reference count in ~Reference_Counted_Event_Handler() ") + ACE_TEXT ("is %d\n"), + this->reference_count_.value ())); + + if (0 != this->reference_count_.value ()) + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("Reference count in ~Reference_Counted_Event_Handler() ") + ACE_TEXT ("should be 0 but is %d\n"), + this->reference_count_.value ())); } int Reference_Counted_Event_Handler::handle_input (ACE_HANDLE) { if (debug) - ACE_DEBUG ((LM_DEBUG, - "Reference count in Reference_Counted_Event_Handler::handle_input() is %d\n", - this->reference_count_.value ())); + ACE_DEBUG + ((LM_DEBUG, + ACE_TEXT ("Reference count in Reference_Counted_Event_Handler::") + ACE_TEXT ("handle_input() is %d\n"), + this->reference_count_.value ())); + + if (2 != this->reference_count_.value ()) + ACE_ERROR + ((LM_ERROR, + ACE_TEXT ("Reference count in Reference_Counted_Event_Handler::") + ACE_TEXT ("handle_input() should be 2 but is %d\n"), + this->reference_count_.value ())); return 0; } @@ -94,7 +116,7 @@ Reference_Counted_Event_Handler::add_reference (void) if (debug) ACE_DEBUG ((LM_DEBUG, - "Reference count after add_reference() is %d\n", + ACE_TEXT ("Reference count after add_reference() is %d\n"), this->reference_count_.value ())); return reference_count; @@ -108,7 +130,7 @@ Reference_Counted_Event_Handler::remove_reference (void) if (debug) ACE_DEBUG ((LM_DEBUG, - "Reference count after remove_reference() is %d\n", + ACE_TEXT ("Reference count after remove_reference() is %d\n"), reference_count)); return reference_count; @@ -131,15 +153,13 @@ Simple_Event_Handler::Simple_Event_Handler (int notifies) : notifies_ (notifies) { if (debug) - ACE_DEBUG ((LM_DEBUG, - "Simple_Event_Handler()\n")); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Simple_Event_Handler()\n"))); } Simple_Event_Handler::~Simple_Event_Handler (void) { if (debug) - ACE_DEBUG ((LM_DEBUG, - "~Simple_Event_Handler()\n")); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("~Simple_Event_Handler()\n"))); } int @@ -147,7 +167,7 @@ Simple_Event_Handler::handle_input (ACE_HANDLE) { if (debug) ACE_DEBUG ((LM_DEBUG, - "Simple_Event_Handler::handle_input()\n")); + ACE_TEXT ("Simple_Event_Handler::handle_input()\n"))); this->notifies_--; @@ -195,7 +215,7 @@ Event_Loop_Thread::svc (void) if (debug) ACE_DEBUG ((LM_DEBUG, - "Event Loop iteration %d....\n", + ACE_TEXT ("Event Loop iteration %d....\n"), counter)); this->reactor_.handle_events (); @@ -251,8 +271,7 @@ test<REACTOR_IMPLEMENTATION>::test (int extra_iterations_needed) { if (test_empty_notify) { - ACE_DEBUG ((LM_DEBUG, - "\n\nTesting empty notifies....\n\n")); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n\nTesting empty notifies...\n\n"))); REACTOR_IMPLEMENTATION impl; ACE_Reactor reactor (&impl, 0); @@ -265,8 +284,7 @@ test<REACTOR_IMPLEMENTATION>::test (int extra_iterations_needed) if (test_simple_notify) { - ACE_DEBUG ((LM_DEBUG, - "\n\nTesting simple notifies....\n\n")); + ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n\nTesting simple notifies...\n\n"))); REACTOR_IMPLEMENTATION impl; ACE_Reactor reactor (&impl, 0); @@ -282,7 +300,7 @@ test<REACTOR_IMPLEMENTATION>::test (int extra_iterations_needed) if (test_reference_counted_notify) { ACE_DEBUG ((LM_DEBUG, - "\n\nTesting reference counted notifies....\n\n")); + ACE_TEXT ("\n\nTesting reference counted notifies...\n\n"))); REACTOR_IMPLEMENTATION impl; ACE_Reactor reactor (&impl, 0); @@ -301,7 +319,7 @@ test<REACTOR_IMPLEMENTATION>::test (int extra_iterations_needed) static int parse_args (int argc, ACE_TCHAR *argv[]) { - ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("a:b:c:e:f:g:z:")); + ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("a:b:c:d:e:f:g:z:")); int cc; while ((cc = get_opt ()) != -1) @@ -317,6 +335,9 @@ parse_args (int argc, ACE_TCHAR *argv[]) case 'c': test_wfmo_reactor = ACE_OS::atoi (get_opt.opt_arg ()); break; + case 'd': + test_dev_poll_reactor = ACE_OS::atoi (get_opt.opt_arg ()); + break; case 'e': test_empty_notify = ACE_OS::atoi (get_opt.opt_arg ()); break; @@ -335,6 +356,7 @@ parse_args (int argc, ACE_TCHAR *argv[]) ACE_TEXT ("\t[-a test Select Reactor] (defaults to %d)\n") ACE_TEXT ("\t[-b test TP Reactor] (defaults to %d)\n") ACE_TEXT ("\t[-c test WFMO Reactor] (defaults to %d)\n") + ACE_TEXT ("\t[-d test Dev Poll Reactor] (defaults to %d)\n") ACE_TEXT ("\t[-e test empty notify] (defaults to %d)\n") ACE_TEXT ("\t[-f test simple notify] (defaults to %d)\n") ACE_TEXT ("\t[-g test reference counted notify] (defaults to %d)\n") @@ -344,6 +366,7 @@ parse_args (int argc, ACE_TCHAR *argv[]) test_select_reactor, test_tp_reactor, test_wfmo_reactor, + test_dev_poll_reactor, test_empty_notify, test_simple_notify, test_reference_counted_notify, @@ -387,6 +410,19 @@ run_main (int argc, ACE_TCHAR *argv[]) ACE_UNUSED_ARG (test); } +#if defined (ACE_HAS_EVENT_POLL) + + if (test_dev_poll_reactor) + { + ACE_DEBUG ((LM_DEBUG, + "\n\nTesting Dev Poll Reactor....\n\n")); + + test<ACE_Dev_Poll_Reactor> test (extra_iterations_not_needed); + ACE_UNUSED_ARG (test); + } + +#endif + #if defined (ACE_WIN32) if (test_wfmo_reactor) diff --git a/tests/Notify_Performance_Test.cpp b/tests/Notify_Performance_Test.cpp index 0da04d67a24..9c4bfe4ae39 100644 --- a/tests/Notify_Performance_Test.cpp +++ b/tests/Notify_Performance_Test.cpp @@ -26,6 +26,7 @@ #include "ace/Reactor.h" #include "ace/WFMO_Reactor.h" #include "ace/Select_Reactor.h" +#include "ace/Dev_Poll_Reactor.h" #include "ace/Auto_Ptr.h" #include "ace/Atomic_Op.h" @@ -45,6 +46,9 @@ static int opt_wfmo_reactor = 0; // Use the Select_Reactor static int opt_select_reactor = 0; +// Use the Dev_Poll_Reactor +static int opt_dev_poll_reactor = 0; + // Pass data through the notify call static int opt_pass_notify_data = 0; @@ -106,6 +110,12 @@ create_reactor (void) { ACE_NEW (impl, ACE_Select_Reactor); } + else if (opt_dev_poll_reactor) + { +#if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) + ACE_NEW (impl, ACE_Dev_Poll_Reactor); +#endif /* ACE_HAS_EVENT_POLL || ACE_HAS_DEV_POLL */ + } ACE_Reactor *reactor = 0; ACE_NEW (reactor, ACE_Reactor (impl)); ACE_Reactor::instance (reactor); @@ -119,6 +129,8 @@ print_results (ACE_Profile_Timer::ACE_Elapsed_Time &et) reactor_type = ACE_TEXT ("WFMO_Reactor"); else if (opt_select_reactor) reactor_type = ACE_TEXT ("Select_Reactor"); + else if (opt_dev_poll_reactor) + reactor_type = ACE_TEXT ("Dev_Poll_Reactor"); else reactor_type = ACE_TEXT ("Platform's default Reactor"); @@ -154,11 +166,14 @@ run_main (int argc, ACE_TCHAR *argv[]) { ACE_START_TEST (ACE_TEXT ("Notify_Performance_Test")); - ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("swdc:l:")); + ACE_Get_Opt getopt (argc, argv, ACE_TEXT ("pswdc:l:")); for (int c; (c = getopt ()) != -1; ) switch (c) { + case 'p': + opt_dev_poll_reactor = 1; + break; case 's': opt_select_reactor = 1; break; @@ -185,7 +200,7 @@ run_main (int argc, ACE_TCHAR *argv[]) // If we are using other that the default implementation, we must // clean up. - if (opt_select_reactor || opt_wfmo_reactor) + if (opt_select_reactor || opt_wfmo_reactor || opt_dev_poll_reactor) { auto_ptr<ACE_Reactor_Impl> auto_impl (ACE_Reactor::instance ()->implementation ()); impl = auto_impl; |