diff options
-rw-r--r-- | ace/Functor.cpp | 48 | ||||
-rw-r--r-- | ace/Functor.h | 69 | ||||
-rw-r--r-- | ace/Functor.i | 28 | ||||
-rw-r--r-- | ace/Functor_T.cpp | 63 | ||||
-rw-r--r-- | ace/Functor_T.h | 81 | ||||
-rw-r--r-- | ace/Functor_T.i | 30 | ||||
-rw-r--r-- | ace/Timer_Queue_Adapters.cpp | 86 | ||||
-rw-r--r-- | ace/Timer_Queue_Adapters.h | 60 |
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 */ |