summaryrefslogtreecommitdiff
path: root/ACE/ace/Module.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/Module.cpp')
-rw-r--r--ACE/ace/Module.cpp273
1 files changed, 273 insertions, 0 deletions
diff --git a/ACE/ace/Module.cpp b/ACE/ace/Module.cpp
new file mode 100644
index 00000000000..cded99621cf
--- /dev/null
+++ b/ACE/ace/Module.cpp
@@ -0,0 +1,273 @@
+// $Id$
+
+#ifndef ACE_MODULE_CPP
+#define ACE_MODULE_CPP
+
+#include "ace/Module.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Stream_Modules.h"
+
+#if !defined (__ACE_INLINE__)
+#include "ace/Module.inl"
+#endif /* __ACE_INLINE__ */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+ACE_ALLOC_HOOK_DEFINE(ACE_Module)
+
+template <ACE_SYNCH_DECL> void
+ACE_Module<ACE_SYNCH_USE>::dump (void) const
+{
+#if defined (ACE_HAS_DUMP)
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::dump");
+#endif /* ACE_HAS_DUMP */
+}
+
+template <ACE_SYNCH_DECL> void
+ACE_Module<ACE_SYNCH_USE>::writer (ACE_Task<ACE_SYNCH_USE> *q,
+ int flags /* = M_DELETE_WRITER */)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::writer");
+
+ // Close and maybe delete old writer
+ this->close_i (1, flags);
+
+ this->q_pair_[1] = q;
+
+ if (q != 0)
+ {
+ ACE_CLR_BITS (q->flags_, ACE_Task_Flags::ACE_READER);
+ // Set the q's module pointer to point to us.
+ q->mod_ = this;
+ }
+
+ // Don't allow the caller to change the reader status.
+ ACE_SET_BITS (flags_, (flags & M_DELETE_WRITER));
+}
+
+template <ACE_SYNCH_DECL> void
+ACE_Module<ACE_SYNCH_USE>::reader (ACE_Task<ACE_SYNCH_USE> *q,
+ int flags /* = M_DELETE_READER */)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::reader");
+
+ // Close and maybe delete old writer
+ this->close_i (0, flags);
+
+ this->q_pair_[0] = q;
+
+ if (q != 0)
+ {
+ ACE_SET_BITS (q->flags_, ACE_Task_Flags::ACE_READER);
+ // Set the q's module pointer to point to us.
+ q->mod_ = this;
+ }
+
+ // don't allow the caller to change the reader status
+ ACE_SET_BITS (flags_, (flags & M_DELETE_READER));
+}
+
+// Link this ACE_Module on top of ACE_Module M.
+
+template <ACE_SYNCH_DECL> void
+ACE_Module<ACE_SYNCH_USE>::link (ACE_Module<ACE_SYNCH_USE> *m)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::link");
+ this->next (m);
+ this->writer ()->next (m->writer ());
+ m->reader ()->next (this->reader ());
+}
+
+template <ACE_SYNCH_DECL> int
+ACE_Module<ACE_SYNCH_USE>::open (const ACE_TCHAR *module_name,
+ ACE_Task<ACE_SYNCH_USE> *writer_q,
+ ACE_Task<ACE_SYNCH_USE> *reader_q,
+ void *arg,
+ int flags /* = M_DELETE */)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::open");
+ this->name (module_name);
+ this->arg_ = arg;
+
+ // We may already have readers and/or writers.
+ if (this->reader ())
+ this->close_i (0, M_DELETE_READER);
+
+ if (this->writer ())
+ this->close_i (1, M_DELETE_WRITER);
+
+ if (writer_q == 0)
+ {
+ ACE_NEW_RETURN (writer_q,
+ ACE_Thru_Task<ACE_SYNCH_USE>,
+ -1);
+ ACE_SET_BITS (flags, M_DELETE_WRITER);
+ }
+
+ if (reader_q == 0)
+ {
+ ACE_NEW_RETURN (reader_q,
+ ACE_Thru_Task<ACE_SYNCH_USE>,
+ -1);
+ ACE_SET_BITS (flags, M_DELETE_READER);
+ }
+
+ this->reader (reader_q);
+ this->writer (writer_q);
+
+ // Save the flags
+ this->flags_ = flags;
+
+ // Make sure that the memory is allocated before proceding.
+ if (writer_q == 0 || reader_q == 0)
+ {
+ // These calls will delete writer_q and/or reader_q, if
+ // necessary.
+ this->close_i (0, M_DELETE_READER);
+ this->close_i (1, M_DELETE_WRITER);
+
+ errno = ENOMEM;
+ return -1;
+ }
+
+ // Setup back pointers (this must come last, after we've made sure
+ // there's memory allocated here.
+ reader_q->mod_ = this;
+ writer_q->mod_ = this;
+
+ return 0;
+}
+
+// Set and get pointer to sibling ACE_Task in ACE_Module.
+
+template <ACE_SYNCH_DECL> ACE_Task<ACE_SYNCH_USE> *
+ACE_Module<ACE_SYNCH_USE>::sibling (ACE_Task<ACE_SYNCH_USE> *orig)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::sibling");
+ if (this->q_pair_[0] == orig)
+ return this->q_pair_[1];
+ else if (this->q_pair_[1] == orig)
+ return this->q_pair_[0];
+ else
+ return 0;
+}
+
+template <ACE_SYNCH_DECL>
+ACE_Module<ACE_SYNCH_USE>::ACE_Module (void)
+ : flags_ (M_FLAGS_NOT_SET)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::ACE_Module");
+ this->name (ACE_TEXT ("<unknown>"));
+ // Do nothing...
+ this->q_pair_[0] = 0;
+ this->q_pair_[1] = 0;
+}
+
+template <ACE_SYNCH_DECL>
+ACE_Module<ACE_SYNCH_USE>::~ACE_Module (void)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::~ACE_Module");
+
+ // Only close down if we haven't already done so.
+ if (this->reader () || this->writer ())
+ this->close ();
+}
+
+template <ACE_SYNCH_DECL>
+ACE_Module<ACE_SYNCH_USE>::ACE_Module (const ACE_TCHAR *module_name,
+ ACE_Task<ACE_SYNCH_USE> *writer_q,
+ ACE_Task<ACE_SYNCH_USE> *reader_q,
+ void *args,
+ int flags /* = M_DELETE */)
+ : flags_ (M_FLAGS_NOT_SET)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::ACE_Module");
+
+ this->q_pair_[0] = 0;
+ this->q_pair_[1] = 0;
+
+ if (this->open (module_name, writer_q, reader_q, args, flags) == -1)
+ ACE_ERROR ((LM_ERROR,
+ ACE_TEXT ("%p\n"),
+ ACE_TEXT ("ACE_Module")));
+}
+
+template <ACE_SYNCH_DECL> int
+ACE_Module<ACE_SYNCH_USE>::close (int flags /* = M_DELETE_NONE */)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::close");
+
+ int result = 0;
+
+ // Only pay attention to the flags parameter if we haven't already
+ // set the task delete policies.
+ if (this->flags_ == M_FLAGS_NOT_SET)
+ ACE_SET_BITS (flags_, flags);
+
+ if (this->close_i (0, flags_) == -1)
+ result = -1;
+
+ if (this->close_i (1, flags_) == -1)
+ result = -1;
+
+ return result;
+}
+
+template <ACE_SYNCH_DECL> int
+ACE_Module<ACE_SYNCH_USE>::close_i (int which,
+ int flags)
+{
+ ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::close_i");
+
+ if (this->q_pair_[which] == 0)
+ return 0;
+
+ // Copy task pointer to prevent problems when ACE_Task::close
+ // changes the task pointer
+ ACE_Task<ACE_SYNCH_USE> *task = this->q_pair_[which];
+
+ // Change so that close doesn't get called again from the task base.
+
+ // Now close the task.
+ int result = 0;
+
+ if (task->module_closed () == -1)
+ result = -1;
+
+ task->flush ();
+ task->next (0);
+
+ // Should we also delete it ?
+ if (flags != M_DELETE_NONE
+ && ACE_BIT_ENABLED (flags_, which + 1))
+ {
+ // Only delete the Tasks if there aren't any more threads
+ // running in them.
+ task->wait ();
+
+ // If this assert happens it is likely because the task was
+ // activated with the THR_DETACHED flag, which means that we
+ // can't join() with the thread. Not using THR_DETACHED should
+ // solve this problem.
+ ACE_ASSERT (task->thr_count () == 0);
+
+ delete task;
+ }
+
+ // Set the tasks pointer to 0 so that we don't try to close()
+ // this object again if the destructor gets called.
+ this->q_pair_[which] = 0;
+
+ // Finally remove the delete bit.
+ ACE_CLR_BITS (flags_, which + 1);
+
+ return result;
+}
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* ACE_MODULE_CPP */