00001 // -*- C++ -*- 00002 00003 //========================================================================== 00004 /** 00005 * @file Module.h 00006 * 00007 * $Id: Module.h 77152 2007-02-15 13:41:25Z johnnyw $ 00008 * 00009 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00010 */ 00011 //========================================================================== 00012 00013 #ifndef ACE_MODULE_H 00014 #define ACE_MODULE_H 00015 00016 #include /**/ "ace/pre.h" 00017 00018 #include /**/ "ace/ACE_export.h" 00019 00020 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00021 # pragma once 00022 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00023 00024 #include "ace/Task_T.h" 00025 #include "ace/os_include/os_dirent.h" 00026 00027 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00028 00029 /** 00030 * @class ACE_Module_Base 00031 * 00032 * @brief Workaround HP/C++ compiler bug with enums in templates. 00033 * 00034 * Certain C++ compilers, e.g., the HP/UX 10.x and 9.x compilers, 00035 * seem to fail if enums are defined inside a template, hence we 00036 * have to move them into a base class. 00037 */ 00038 class ACE_Export ACE_Module_Base 00039 { 00040 public: 00041 enum 00042 { 00043 /// Indicates that the flags have not been set 00044 M_FLAGS_NOT_SET = 0, 00045 00046 /// Indicates that <close> should delete the writer Task. 00047 M_DELETE_READER = 1, 00048 00049 /// Indicates that <close> should delete the reader Task. 00050 M_DELETE_WRITER = 2, 00051 00052 /// Indicates that <close> deletes the Tasks. 00053 /** 00054 * Don't change this value without updating the same enum in class 00055 * ACE_Stream... 00056 * The <M_DELETE_READER> and <M_DELETE_WRITER> flags may be or'ed 00057 * together. 00058 */ 00059 M_DELETE = 3, 00060 00061 /// Indicates that <close> should not delete any Tasks. 00062 M_DELETE_NONE = 4 00063 }; 00064 }; 00065 00066 /** 00067 * @class ACE_Module 00068 * 00069 * @brief An abstraction for managing a bi-directional flow of messages. 00070 * 00071 * This is based on the Module concept in System V Streams, 00072 * which contains a pair of Tasks, one for handling upstream 00073 * processing, one for handling downstream processing. In 00074 * general, you shouldn't subclass from this class, but instead 00075 * subclass from the ACE_Task. 00076 */ 00077 template <ACE_SYNCH_DECL> 00078 class ACE_Module : public ACE_Module_Base 00079 { 00080 public: 00081 // = Initialization and termination methods. 00082 /// Create an empty Module. 00083 ACE_Module (void); 00084 00085 /// Shutdown the Module. 00086 virtual ~ACE_Module (void); 00087 00088 /// Create an initialized module with @a module_name as its identity 00089 /// and @a reader and @a writer as its tasks. 00090 ACE_Module (const ACE_TCHAR *module_name, 00091 ACE_Task<ACE_SYNCH_USE> *writer = 0, 00092 ACE_Task<ACE_SYNCH_USE> *reader = 0, 00093 void *args = 0, 00094 int flags = M_DELETE); 00095 00096 /** 00097 * Initialize the module with <module_name> as its identity 00098 * and <reader> and <writer> as its tasks. Previously register 00099 * reader or writers or closed down and deleted according to the 00100 * value of flags_. Should not be called from within 00101 * <ACE_Task::module_closed>. 00102 */ 00103 int open (const ACE_TCHAR *module_name, 00104 ACE_Task<ACE_SYNCH_USE> *writer = 0, 00105 ACE_Task<ACE_SYNCH_USE> *reader = 0, 00106 void *a = 0, 00107 int flags = M_DELETE); 00108 00109 /** 00110 * Close down the module and its tasks. The flags argument can be 00111 * used to override the default behaviour, which depends on previous 00112 * <flags> values in calls to c'tor, <open>, <reader>, and <writer>. 00113 * A previous value M_DELETE[_XXX] can not be overridden. Should 00114 * not be called from within <ACE_Task::module_closed>. 00115 */ 00116 int close (int flags = M_DELETE_NONE); 00117 00118 // = ACE_Task manipulation routines 00119 /// Get the writer task. 00120 ACE_Task<ACE_SYNCH_USE> *writer (void); 00121 00122 /** 00123 * Set the writer task. @a flags can be used to indicate that the 00124 * module should delete the writer during a call to close or to the 00125 * destructor. If a previous writer exists, it is closed. It may 00126 * also be deleted, depending on the old flags_ value. Should not 00127 * be called from within <ACE_Task::module_closed>. 00128 */ 00129 void writer (ACE_Task<ACE_SYNCH_USE> *q, int flags = M_DELETE_WRITER); 00130 00131 /// Get the reader task. 00132 ACE_Task<ACE_SYNCH_USE> *reader (void); 00133 00134 /** 00135 * Set the reader task. @a flags can be used to indicate that the 00136 * module should delete the reader during a call to close or to the 00137 * destructor. If a previous reader exists, it is closed. It may 00138 * also be deleted, depending on the old flags_ value. Should not 00139 * be called from within <ACE_Task::module_closed>. 00140 */ 00141 void reader (ACE_Task<ACE_SYNCH_USE> *q, int flags = M_DELETE_READER); 00142 00143 /// Set and get pointer to sibling ACE_Task in an ACE_Module 00144 ACE_Task<ACE_SYNCH_USE> *sibling (ACE_Task<ACE_SYNCH_USE> *orig); 00145 00146 // = Identify the module 00147 /// Get the module name. 00148 const ACE_TCHAR *name (void) const; 00149 00150 /// Set the module name. 00151 void name (const ACE_TCHAR *); 00152 00153 // = Argument to the Tasks. 00154 /// Get the argument passed to the tasks. 00155 void *arg (void) const; 00156 00157 /// Set the argument passed to the tasks. 00158 void arg (void *); 00159 00160 /// Link to other modules in the ustream stack 00161 void link (ACE_Module<ACE_SYNCH_USE> *m); 00162 00163 /// Get the next pointer to the module above in the stream. 00164 ACE_Module<ACE_SYNCH_USE> *next (void); 00165 00166 /// Set the next pointer to the module above in the stream. 00167 void next (ACE_Module<ACE_SYNCH_USE> *m); 00168 00169 /// Dump the state of an object. 00170 void dump (void) const; 00171 00172 /// Declare the dynamic allocation hooks. 00173 ACE_ALLOC_HOOK_DECLARE; 00174 00175 private: 00176 /// Implements the close operation for either the reader or the 00177 /// writer task (depending on <which>). 00178 int close_i (int which, int flags); 00179 00180 /// Pair of Tasks that form the "read-side" and "write-side" of the 00181 /// ACE_Module partitioning. 00182 ACE_Task<ACE_SYNCH_USE> *q_pair_[2]; 00183 00184 /// Name of the ACE_Module. 00185 ACE_TCHAR name_[MAXPATHLEN + 1]; 00186 00187 /// Next ACE_Module in the stack. 00188 ACE_Module<ACE_SYNCH_USE> *next_; 00189 00190 /// Argument passed through to the reader and writer task when they 00191 /// are opened. 00192 void *arg_; 00193 00194 /// Holds flags which are used to determine if the reader and writer 00195 /// task have to be deleted on exit 00196 int flags_; 00197 }; 00198 00199 ACE_END_VERSIONED_NAMESPACE_DECL 00200 00201 #if defined (__ACE_INLINE__) 00202 #include "ace/Module.inl" 00203 #endif /* __ACE_INLINE__ */ 00204 00205 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00206 #include "ace/Module.cpp" 00207 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00208 00209 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00210 #pragma implementation ("Module.cpp") 00211 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00212 00213 #include /**/ "ace/post.h" 00214 00215 #endif /* ACE_MODULE_H */