Merge pull request #2301 from sonndinh/remove-dup-reactor-functions
[ACE_TAO.git] / ACE / ace / Module.cpp
blob8136364dcb6560789a93d26958e2530cbf81b5a4
1 #ifndef ACE_MODULE_CPP
2 #define ACE_MODULE_CPP
4 #include "ace/Module.h"
6 #if !defined (ACE_LACKS_PRAGMA_ONCE)
7 # pragma once
8 #endif /* ACE_LACKS_PRAGMA_ONCE */
10 #include "ace/Stream_Modules.h"
12 #if !defined (__ACE_INLINE__)
13 #include "ace/Module.inl"
14 #endif /* __ACE_INLINE__ */
16 #if defined (ACE_HAS_ALLOC_HOOKS)
17 # include "ace/Malloc_Base.h"
18 #endif /* ACE_HAS_ALLOC_HOOKS */
20 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
22 ACE_ALLOC_HOOK_DEFINE_Tyc(ACE_Module)
24 template <ACE_SYNCH_DECL, class TIME_POLICY> void
25 ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::dump () const
27 #if defined (ACE_HAS_DUMP)
28 ACE_TRACE ("ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::dump");
29 #endif /* ACE_HAS_DUMP */
32 template <ACE_SYNCH_DECL, class TIME_POLICY> void
33 ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::writer (ACE_Task<ACE_SYNCH_USE, TIME_POLICY> *q,
34 int flags /* = M_DELETE_WRITER */)
36 ACE_TRACE ("ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::writer");
38 // Close and maybe delete old writer
39 this->close_i (1, flags);
41 this->q_pair_[1] = q;
43 if (q != 0)
45 ACE_CLR_BITS (q->flags_, ACE_Task_Flags::ACE_READER);
46 // Set the q's module pointer to point to us.
47 q->mod_ = this;
50 // Don't allow the caller to change the reader status.
51 ACE_SET_BITS (flags_, (flags & M_DELETE_WRITER));
54 template <ACE_SYNCH_DECL, class TIME_POLICY> void
55 ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::reader (ACE_Task<ACE_SYNCH_USE, TIME_POLICY> *q,
56 int flags /* = M_DELETE_READER */)
58 ACE_TRACE ("ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::reader");
60 // Close and maybe delete old writer
61 this->close_i (0, flags);
63 this->q_pair_[0] = q;
65 if (q != 0)
67 ACE_SET_BITS (q->flags_, ACE_Task_Flags::ACE_READER);
68 // Set the q's module pointer to point to us.
69 q->mod_ = this;
72 // don't allow the caller to change the reader status
73 ACE_SET_BITS (flags_, (flags & M_DELETE_READER));
76 // Link this ACE_Module on top of ACE_Module M.
78 template <ACE_SYNCH_DECL, class TIME_POLICY> void
79 ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::link (ACE_Module<ACE_SYNCH_USE, TIME_POLICY> *m)
81 ACE_TRACE ("ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::link");
82 this->next (m);
83 this->writer ()->next (m->writer ());
84 m->reader ()->next (this->reader ());
87 template <ACE_SYNCH_DECL, class TIME_POLICY> int
88 ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::open (const ACE_TCHAR *module_name,
89 ACE_Task<ACE_SYNCH_USE, TIME_POLICY> *writer_q,
90 ACE_Task<ACE_SYNCH_USE, TIME_POLICY> *reader_q,
91 void *arg,
92 int flags /* = M_DELETE */)
94 ACE_TRACE ("ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::open");
95 this->name (module_name);
96 this->arg_ = arg;
98 // We may already have readers and/or writers.
99 if (this->reader ())
100 this->close_i (0, M_DELETE_READER);
102 if (this->writer ())
103 this->close_i (1, M_DELETE_WRITER);
105 if (writer_q == 0)
107 typedef ACE_Thru_Task<ACE_SYNCH_USE, TIME_POLICY> TASK_TYPE;
108 ACE_NEW_NORETURN (writer_q,
109 TASK_TYPE);
110 ACE_SET_BITS (flags, M_DELETE_WRITER);
113 if (reader_q == 0)
115 typedef ACE_Thru_Task<ACE_SYNCH_USE, TIME_POLICY> TASK_TYPE;
116 ACE_NEW_NORETURN (reader_q,
117 TASK_TYPE);
118 ACE_SET_BITS (flags, M_DELETE_READER);
121 // Make sure that the memory is allocated before proceeding.
122 if (writer_q == 0 || reader_q == 0)
124 // These calls will delete writer_q and/or reader_q, if
125 // necessary.
126 this->close_i (0, M_DELETE_READER);
127 this->close_i (1, M_DELETE_WRITER);
129 errno = ENOMEM;
130 return -1;
133 this->reader (reader_q);
134 this->writer (writer_q);
136 // Save the flags
137 this->flags_ = flags;
139 // Setup back pointers (this must come last, after we've made sure
140 // there's memory allocated here.
141 reader_q->mod_ = this;
142 writer_q->mod_ = this;
144 return 0;
147 // Set and get pointer to sibling ACE_Task in ACE_Module.
149 template <ACE_SYNCH_DECL, class TIME_POLICY> ACE_Task<ACE_SYNCH_USE, TIME_POLICY> *
150 ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::sibling (ACE_Task<ACE_SYNCH_USE, TIME_POLICY> *orig)
152 ACE_TRACE ("ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::sibling");
153 if (this->q_pair_[0] == orig)
154 return this->q_pair_[1];
155 else if (this->q_pair_[1] == orig)
156 return this->q_pair_[0];
157 else
158 return 0;
161 template <ACE_SYNCH_DECL, class TIME_POLICY>
162 ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::ACE_Module ()
163 : next_ (0)
164 , arg_ (0)
165 , flags_ (M_FLAGS_NOT_SET)
167 ACE_TRACE ("ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::ACE_Module");
168 this->name (ACE_TEXT ("<unknown>"));
169 // Do nothing...
170 this->q_pair_[0] = 0;
171 this->q_pair_[1] = 0;
174 template <ACE_SYNCH_DECL, class TIME_POLICY>
175 ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::~ACE_Module ()
177 ACE_TRACE ("ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::~ACE_Module");
179 // Only close down if we haven't already done so.
180 if (this->reader () || this->writer ())
181 this->close ();
184 template <ACE_SYNCH_DECL, class TIME_POLICY>
185 ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::ACE_Module (const ACE_TCHAR *module_name,
186 ACE_Task<ACE_SYNCH_USE, TIME_POLICY> *writer_q,
187 ACE_Task<ACE_SYNCH_USE, TIME_POLICY> *reader_q,
188 void *args,
189 int flags /* = M_DELETE */)
190 : next_ (0),
191 flags_ (M_FLAGS_NOT_SET)
193 ACE_TRACE ("ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::ACE_Module");
195 this->q_pair_[0] = 0;
196 this->q_pair_[1] = 0;
198 if (this->open (module_name, writer_q, reader_q, args, flags) == -1)
199 ACELIB_ERROR ((LM_ERROR,
200 ACE_TEXT ("%p\n"),
201 ACE_TEXT ("ACE_Module")));
204 template <ACE_SYNCH_DECL, class TIME_POLICY> int
205 ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::close (int flags /* = M_DELETE_NONE */)
207 ACE_TRACE ("ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::close");
209 int result = 0;
211 // Only pay attention to the flags parameter if we haven't already
212 // set the task delete policies.
213 if (this->flags_ == M_FLAGS_NOT_SET)
214 ACE_SET_BITS (flags_, flags);
216 if (this->close_i (0, flags_) == -1)
217 result = -1;
219 if (this->close_i (1, flags_) == -1)
220 result = -1;
222 return result;
225 template <ACE_SYNCH_DECL, class TIME_POLICY> int
226 ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::close_i (int which,
227 int flags)
229 ACE_TRACE ("ACE_Module<ACE_SYNCH_USE, TIME_POLICY>::close_i");
231 if (this->q_pair_[which] == 0)
232 return 0;
234 // Copy task pointer to prevent problems when ACE_Task::close
235 // changes the task pointer
236 ACE_Task<ACE_SYNCH_USE, TIME_POLICY> *task = this->q_pair_[which];
238 // Change so that close doesn't get called again from the task base.
240 // Now close the task.
241 int result = 0;
243 if (task->module_closed () == -1)
244 result = -1;
246 task->flush ();
247 task->next (0);
249 // Should we also delete it ?
250 if (flags != M_DELETE_NONE
251 && ACE_BIT_ENABLED (flags_, which + 1))
253 // Only delete the Tasks if there aren't any more threads
254 // running in them.
255 task->wait ();
257 // If this assert happens it is likely because the task was
258 // activated with the THR_DETACHED flag, which means that we
259 // can't join() with the thread. Not using THR_DETACHED should
260 // solve this problem.
261 ACE_ASSERT (task->thr_count () == 0);
263 delete task;
266 // Set the tasks pointer to 0 so that we don't try to close()
267 // this object again if the destructor gets called.
268 this->q_pair_[which] = 0;
270 // Finally remove the delete bit.
271 ACE_CLR_BITS (flags_, which + 1);
273 return result;
276 ACE_END_VERSIONED_NAMESPACE_DECL
278 #endif /* ACE_MODULE_CPP */