summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Huston <shuston@riverace.com>2005-02-11 23:15:33 +0000
committerSteve Huston <shuston@riverace.com>2005-02-11 23:15:33 +0000
commitabab2702843e3ed89c056c6d69aced34f2567ccc (patch)
treed26d335514d7f6f00414ccf7f2b48f8e7a707b91
parent0f3488632f318d9d5cf9b1973789863f91bed72a (diff)
downloadATCD-abab2702843e3ed89c056c6d69aced34f2567ccc.tar.gz
ChangeLogTag:Fri Feb 11 18:11:29 2005 Steve Huston <shuston@riverace.com>
-rw-r--r--ChangeLog46
-rw-r--r--ace/Dev_Poll_Reactor.cpp126
-rw-r--r--ace/Dev_Poll_Reactor.h97
-rw-r--r--ace/Dev_Poll_Reactor.inl82
-rw-r--r--ace/Reactor.cpp23
-rw-r--r--tests/Dev_Poll_Reactor_Test.cpp15
-rw-r--r--tests/MT_Reactor_Upcall_Test.cpp12
-rw-r--r--tests/MT_Reference_Counted_Event_Handler_Test.cpp27
-rw-r--r--tests/MT_Reference_Counted_Notify_Test.cpp82
-rw-r--r--tests/Notify_Performance_Test.cpp19
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;