summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ace/Functor.cpp48
-rw-r--r--ace/Functor.h69
-rw-r--r--ace/Functor.i28
-rw-r--r--ace/Functor_T.cpp63
-rw-r--r--ace/Functor_T.h81
-rw-r--r--ace/Functor_T.i30
-rw-r--r--ace/Timer_Queue_Adapters.cpp86
-rw-r--r--ace/Timer_Queue_Adapters.h60
8 files changed, 444 insertions, 21 deletions
diff --git a/ace/Functor.cpp b/ace/Functor.cpp
new file mode 100644
index 00000000000..19ae2603122
--- /dev/null
+++ b/ace/Functor.cpp
@@ -0,0 +1,48 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Functor.cpp
+//
+// = DESCRIPTION
+// Non-inlinable method definitions for non-templatized classes
+// implementing the GOF Command Pattern, also known as functors
+// or function objects.
+//
+// = AUTHOR
+// Chris Gill <cdgill@cs.wustl.edu>
+//
+// Based on Command Pattern implementations originally done by
+//
+// Carlos O'Ryan <coryan@cs.wustl.edu> and
+// Douglas C. Schmidt <schmidt@cs.wustl.edu> and
+// Sergio Flores-Gaitan <sergio@cs.wustl.edu>
+//
+// ============================================================================
+
+#if !defined (ACE_FUNCTOR_C)
+#define ACE_FUNCTOR_C
+
+#define ACE_BUILD_DLL
+#include "ace/Functor_T.h"
+#include "ace/Functor.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/Functor.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(ace, Functor, "$Id$")
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
+
+#endif /* ACE_FUNCTOR_C */
+
+// EOF
+
diff --git a/ace/Functor.h b/ace/Functor.h
new file mode 100644
index 00000000000..6095dc18742
--- /dev/null
+++ b/ace/Functor.h
@@ -0,0 +1,69 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Functor.h
+//
+// = DESCRIPTION
+// Non-templatized classes for implementing the GOF Command Pattern,
+// also known as functors or function objects.
+//
+// = AUTHOR
+// Chris Gill <cdgill@cs.wustl.edu>
+//
+// Based on Command Pattern implementations originally done by
+//
+// Carlos O'Ryan <coryan@cs.wustl.edu> and
+// Douglas C. Schmidt <schmidt@cs.wustl.edu> and
+// Sergio Flores-Gaitan <sergio@cs.wustl.edu>
+//
+// ============================================================================
+
+#if !defined (ACE_FUNCTOR_H)
+#define ACE_FUNCTOR_H
+
+#include "ace/OS.h"
+
+class ACE_Command_Base
+{
+ // = TITLE
+ // Defines an abstract class that allows us to invoke commands
+ // without knowing anything about the implementation.
+ //
+ // = DESCRIPTION
+ // This class declares an interface to execute a command
+ // independent of the effect of the command, or the objects used
+ // to implement it.
+public:
+
+ ACE_Command_Base (void) {}
+ // Default constructor.
+
+ virtual ~ACE_Command_Base (void) {}
+ // Virtaul destructor.
+
+ virtual int execute (void *arg = 0) = 0;
+ // Invokes the method encapsulated by the command, passing along the
+ // passed argument (if any). Users of classes derived from this
+ // class must ensure that the resulting invocation can tolerate
+ // a null void pointer being passed, or otherwise ensure that
+ // this will never occur.
+};
+
+
+#if defined (__ACE_INLINE__)
+#include "ace/Functor.i"
+#endif /* __ACE_INLINE__ */
+
+// Include the templates here.
+#include "ace/Functor_T.h"
+
+
+#endif /* ACE_FUNCTOR_H */
+
+// EOF
diff --git a/ace/Functor.i b/ace/Functor.i
new file mode 100644
index 00000000000..e605408bb83
--- /dev/null
+++ b/ace/Functor.i
@@ -0,0 +1,28 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Functor.i
+//
+// = DESCRIPTION
+// Inlinable method definitions for non-templatized classes
+// implementing the GOF Command Pattern, also known as functors
+// or function objects.
+//
+// = AUTHOR
+// Chris Gill <cdgill@cs.wustl.edu>
+//
+// Based on Command Pattern implementations originally done by
+//
+// Carlos O'Ryan <coryan@cs.wustl.edu> and
+// Douglas C. Schmidt <schmidt@cs.wustl.edu> and
+// Sergio Flores-Gaitan <sergio@cs.wustl.edu>
+//
+// ============================================================================
+
+// EOF
diff --git a/ace/Functor_T.cpp b/ace/Functor_T.cpp
new file mode 100644
index 00000000000..98758932b5d
--- /dev/null
+++ b/ace/Functor_T.cpp
@@ -0,0 +1,63 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Functor_T.cpp
+//
+// = DESCRIPTION
+// Non-inlinable method definitions for templatized classes
+// implementing the GOF Command Pattern, also known as functors
+// or function objects.
+//
+// = AUTHOR
+// Chris Gill <cdgill@cs.wustl.edu>
+//
+// Based on Command Pattern implementations originally done by
+//
+// Carlos O'Ryan <coryan@cs.wustl.edu> and
+// Douglas C. Schmidt <schmidt@cs.wustl.edu> and
+// Sergio Flores-Gaitan <sergio@cs.wustl.edu>
+//
+// ============================================================================
+
+#if !defined (ACE_FUNCTOR_T_C)
+#define ACE_FUNCTOR_T_C
+
+#define ACE_BUILD_DLL
+#include "ace/Functor_T.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/Functor_T.i"
+#endif /* __ACE_INLINE__ */
+
+ACE_RCSID(ace, Functor_T, "$Id$")
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Command_Callback)
+
+// Constructor.
+
+template <class RECEIVER, class ACTION>
+ACE_Command_Callback<RECEIVER, ACTION>::ACE_Command_Callback (RECEIVER &recvr,
+ ACTION action)
+ : receiver_ (recvr),
+ action_ (action)
+{
+}
+
+// Invokes an operation.
+
+template <class RECEIVER, class ACTION> int
+ACE_Command_Callback<RECEIVER, ACTION>::execute (void *arg)
+{
+ return (receiver_.*action_) (arg);
+}
+
+
+#endif /* ACE_FUNCTOR_T_C */
+
+// EOF
diff --git a/ace/Functor_T.h b/ace/Functor_T.h
new file mode 100644
index 00000000000..9b879e5ab75
--- /dev/null
+++ b/ace/Functor_T.h
@@ -0,0 +1,81 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Functor_T.h
+//
+// = DESCRIPTION
+// Templatized classes for implementing the GOF Command Pattern,
+// also known as functors or function objects.
+//
+// = AUTHOR
+// Chris Gill <cdgill@cs.wustl.edu>
+//
+// Based on Command Pattern implementations originally done by
+//
+// Carlos O'Ryan <coryan@cs.wustl.edu> and
+// Douglas C. Schmidt <schmidt@cs.wustl.edu> and
+// Sergio Flores-Gaitan <sergio@cs.wustl.edu>
+//
+// ============================================================================
+
+#if !defined (ACE_FUNCTOR_T_H)
+#define ACE_FUNCTOR_T_H
+
+#include "ace/Functor.h"
+
+template <class RECEIVER, class ACTION>
+class ACE_Command_Callback : public ACE_Command_Base
+{
+ // = TITLE
+ // Defines a class template that allows us to invoke a callback to an
+ // object without knowing anything about the object except its type.
+ //
+ // = DESCRIPTION
+ // This class declares an interface to execute operations,
+ // binding a RECEIVER object with an ACTION. The RECEIVER knows
+ // how to implement the operation. A class can invoke operations
+ // without knowing anything about it, or how it was implemented.
+public:
+
+ ACE_Command_Callback (RECEIVER &recvr, ACTION action);
+ // Constructor: sets the <receiver_> of the Command to recvr, and the
+ // <action_> of the Command to <action>.
+
+ virtual ~ACE_Command_Callback (void) {}
+ // Virtual destructor.
+
+ virtual int execute (void *arg = 0);
+ // Invokes the method <action_> from the object <receiver_>.
+
+private:
+
+ RECEIVER &receiver_;
+ // Object where the method resides.
+
+ ACTION action_;
+ // Method that is going to be invoked.
+};
+
+
+#if defined (__ACE_INLINE__)
+#include "ace/Functor_T.i"
+#endif /* __ACE_INLINE__ */
+
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ace/Functor_T.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Functor_T.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#endif /* ACE_FUNCTOR_T_H */
+
+// EOF
diff --git a/ace/Functor_T.i b/ace/Functor_T.i
new file mode 100644
index 00000000000..6bb3fdeccce
--- /dev/null
+++ b/ace/Functor_T.i
@@ -0,0 +1,30 @@
+/* -*- C++ -*- */
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// ace
+//
+// = FILENAME
+// Functor_T.i
+//
+// = DESCRIPTION
+// Inlinable method definitions for templatized classes
+// implementing the GOF Command Pattern, also known as functors
+// or function objects.
+//
+// = AUTHOR
+// Chris Gill <cdgill@cs.wustl.edu>
+//
+// Based on Command Pattern implementations originally done by
+//
+// Carlos O'Ryan <coryan@cs.wustl.edu> and
+// Douglas C. Schmidt <schmidt@cs.wustl.edu> and
+// Sergio Flores-Gaitan <sergio@cs.wustl.edu>
+//
+// ============================================================================
+
+
+
+// EOF
diff --git a/ace/Timer_Queue_Adapters.cpp b/ace/Timer_Queue_Adapters.cpp
index 7c0a959967a..5fcd4ee175b 100644
--- a/ace/Timer_Queue_Adapters.cpp
+++ b/ace/Timer_Queue_Adapters.cpp
@@ -4,13 +4,13 @@
#include "ace/Timer_Queue_Adapters.h"
#if !defined (ACE_TIMER_QUEUE_ADAPTERS_C)
-#define ACE_TIMER_QUEUE_ADAPTERS_C
+# define ACE_TIMER_QUEUE_ADAPTERS_C
ACE_RCSID(ace, Timer_Queue_Adapters, "$Id$")
-#if !defined (__ACE_INLINE__)
-#include "ace/Timer_Queue_Adapters.i"
-#endif /* __ACE_INLINE__ */
+# if !defined (__ACE_INLINE__)
+# include "ace/Timer_Queue_Adapters.i"
+# endif /* __ACE_INLINE__ */
template <class TQ> TQ &
ACE_Async_Timer_Queue_Adapter<TQ>::timer_queue (void)
@@ -205,15 +205,33 @@ ACE_Thread_Timer_Queue_Adapter<TQ>::svc (void)
this->thr_id_ = ACE_Thread::self ();
// Thread cancellation point, if ACE supports it.
-#if !defined (ACE_LACKS_PTHREAD_CANCEL)
+# if !defined (ACE_LACKS_PTHREAD_CANCEL)
ACE_PTHREAD_CLEANUP_PUSH (&this->condition_.mutex ());
-#endif /* ACE_LACKS_PTHREAD_CANCEL */
+# endif /* ACE_LACKS_PTHREAD_CANCEL */
while (this->active_)
{
+# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
+
+ // Temporarily suspend ownership of the timer queue mutex in
+ // order to dispatch deferred execution commands. These commands
+ // are to be treated as executing in a context "external" to the
+ // timer queue adapter, and thus must compete separately for this lock.
+ mutex_.release ();
+ this->dispatch_commands ();
+
+ // Re-acquire ownership of the timer queue mutex in order
+ // to restore the "internal" timer queue adapter context
+ mutex_.acquire ();
+
+
+# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
+
// If the queue is empty, sleep until there is a change on it.
if (this->timer_queue_.is_empty ())
- this->condition_.wait ();
+ {
+ this->condition_.wait ();
+ }
else
{
// Compute the remaining time, being careful not to sleep
@@ -230,12 +248,62 @@ ACE_Thread_Timer_Queue_Adapter<TQ>::svc (void)
}
// Thread cancellation point, if ACE supports it.
-#if !defined (ACE_LACKS_PTHREAD_CANCEL)
+# if !defined (ACE_LACKS_PTHREAD_CANCEL)
ACE_PTHREAD_CLEANUP_POP (0);
-#endif /* ACE_LACKS_PTHREAD_CANCEL */
+# endif /* ACE_LACKS_PTHREAD_CANCEL */
ACE_DEBUG ((LM_DEBUG, ASYS_TEXT ("terminating dispatching thread\n")));
return 0;
}
+
+# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
+
+// Enqueues a command object for execution just before waiting on the next
+// timer event. This allows deferred execution of commands that cannot
+// be performed in the timer event handler context, such as registering
+// or cancelling timers on platforms where the timer queue mutex is not
+// recursive.
+
+template<class TQ> int
+ACE_Thread_Timer_Queue_Adapter<TQ>::enqueue_command (ACE_Command_Base *cmd,
+ COMMAND_ENQUEUE_POSITION pos)
+{
+ // Serialize access to the command queue.
+ ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon,
+ this->command_mutex_, -1);
+
+ if (pos == ACE_Thread_Timer_Queue_Adapter<TQ>::TAIL)
+ {
+ return command_queue_.enqueue_tail (cmd);
+ }
+ else
+ {
+ return command_queue_.enqueue_head (cmd);
+ }
+}
+
+
+// Dispatches all command objects enqueued in the most
+// recent event handler context.
+
+template<class TQ> int
+ACE_Thread_Timer_Queue_Adapter<TQ>::dispatch_commands (void)
+{
+ // Serialize access to the command queue.
+ ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon,
+ this->command_mutex_, -1);
+
+ // loop through the enqueued commands
+ ACE_Command_Base *cmd = 0;
+ while (command_queue_.dequeue_head (cmd) == 0)
+ if (cmd)
+ {
+ cmd->execute ();
+ delete cmd;
+ }
+}
+
+# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
+
#endif /* ACE_TIMER_QUEUE_ADAPTERS_C*/
diff --git a/ace/Timer_Queue_Adapters.h b/ace/Timer_Queue_Adapters.h
index 9720b9e1c66..9bae72c1471 100644
--- a/ace/Timer_Queue_Adapters.h
+++ b/ace/Timer_Queue_Adapters.h
@@ -15,10 +15,10 @@
// ============================================================================
#if !defined (ACE_TIMER_QUEUE_ADAPTERS_H)
-#define ACE_TIMER_QUEUE_ADAPTERS_H
+# define ACE_TIMER_QUEUE_ADAPTERS_H
-#include "ace/Task.h"
-#include "ace/Signal.h"
+# include "ace/Task.h"
+# include "ace/Signal.h"
template <class TQ>
class ACE_Export ACE_Async_Timer_Queue_Adapter : public ACE_Event_Handler
@@ -91,7 +91,16 @@ class ACE_Export ACE_Thread_Timer_Queue_Adapter : public ACE_Task_Base
// (IMHO) the effort and portability problems discourage their
// use.
public:
+
typedef TQ TIMER_QUEUE;
+ // Trait for the underlying queue type.
+
+# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
+
+ enum COMMAND_ENQUEUE_POSITION {HEAD, TAIL};
+ // Typedef for the position at which to enqueue a deferred execution command.
+
+# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
ACE_Thread_Timer_Queue_Adapter (ACE_Thread_Manager * = ACE_Thread_Manager::instance ());
// Creates the timer queue. Activation of the task is the user's
@@ -137,7 +146,34 @@ public:
// that only a single thread is ever spawned. Otherwise, too many
// weird things can happen...
+# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
+
+ int enqueue_command (ACE_Command_Base *command_,
+ COMMAND_ENQUEUE_POSITION pos = TAIL);
+ // Enqueues a command object for execution just before waiting on the next
+ // timer event. This allows deferred execution of commands that cannot
+ // be performed in the timer event handler context, such as registering
+ // or cancelling timers on platforms where the timer queue mutex is not
+ // recursive.
+
+# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
+
private:
+
+# if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
+
+ int dispatch_commands (void);
+ // Dispatches all command objects enqueued in the most
+ // recent event handler context.
+
+ ACE_Unbounded_Queue<ACE_Command_Base *> command_queue_;
+ // Queue of commands for deferred execution.
+
+ ACE_SYNCH_MUTEX command_mutex_;
+ // The mutual exclusion mechanism for the command queue.
+
+# endif /* ACE_HAS_DEFERRED_TIMER_COMMANDS */
+
TQ timer_queue_;
// The underlying Timer_Queue.
@@ -158,16 +194,16 @@ private:
// Thread id of our active object task.
};
-#if defined (__ACE_INLINE__)
-#include "ace/Timer_Queue_Adapters.i"
-#endif /* __ACE_INLINE__ */
+# if defined (__ACE_INLINE__)
+# include "ace/Timer_Queue_Adapters.i"
+# endif /* __ACE_INLINE__ */
-#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
-#include "ace/Timer_Queue_Adapters.cpp"
-#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+# if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+# include "ace/Timer_Queue_Adapters.cpp"
+# endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
-#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
-#pragma implementation ("Timer_Queue_Adapters.cpp")
-#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+# if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+# pragma implementation ("Timer_Queue_Adapters.cpp")
+# endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
#endif /* ACE_TIMER_QUEUE_ADAPTERS_H */