Module.cpp

Go to the documentation of this file.
00001 // Module.cpp,v 4.28 2005/10/28 16:14:53 ossama Exp
00002 
00003 #ifndef ACE_MODULE_CPP
00004 #define ACE_MODULE_CPP
00005 
00006 #include "ace/Module.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #include "ace/Stream_Modules.h"
00013 
00014 #if !defined (__ACE_INLINE__)
00015 #include "ace/Module.inl"
00016 #endif /* __ACE_INLINE__ */
00017 
00018 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00019 
00020 ACE_ALLOC_HOOK_DEFINE(ACE_Module)
00021 
00022 template <ACE_SYNCH_DECL> void
00023 ACE_Module<ACE_SYNCH_USE>::dump (void) const
00024 {
00025 #if defined (ACE_HAS_DUMP)
00026   ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::dump");
00027 #endif /* ACE_HAS_DUMP */
00028 }
00029 
00030 template <ACE_SYNCH_DECL> void
00031 ACE_Module<ACE_SYNCH_USE>::writer (ACE_Task<ACE_SYNCH_USE> *q,
00032                                    int flags /* = M_DELETE_WRITER */)
00033 {
00034   ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::writer");
00035 
00036   // Close and maybe delete old writer
00037   this->close_i (1, flags);
00038 
00039   this->q_pair_[1] = q;
00040 
00041   if (q != 0)
00042     {
00043       ACE_CLR_BITS (q->flags_, ACE_Task_Flags::ACE_READER);
00044       // Set the q's module pointer to point to us.
00045       q->mod_ = this;
00046     }
00047 
00048   // Don't allow the caller to change the reader status.
00049   ACE_SET_BITS (flags_, (flags & M_DELETE_WRITER));
00050 }
00051 
00052 template <ACE_SYNCH_DECL> void
00053 ACE_Module<ACE_SYNCH_USE>::reader (ACE_Task<ACE_SYNCH_USE> *q,
00054                                  int flags /* = M_DELETE_READER */)
00055 {
00056   ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::reader");
00057 
00058   // Close and maybe delete old writer
00059   this->close_i (0, flags);
00060 
00061   this->q_pair_[0] = q;
00062 
00063   if (q != 0)
00064     {
00065       ACE_SET_BITS (q->flags_, ACE_Task_Flags::ACE_READER);
00066       // Set the q's module pointer to point to us.
00067       q->mod_ = this;
00068     }
00069 
00070   // don't allow the caller to change the reader status
00071   ACE_SET_BITS (flags_, (flags & M_DELETE_READER));
00072 }
00073 
00074 // Link this ACE_Module on top of ACE_Module M.
00075 
00076 template <ACE_SYNCH_DECL> void
00077 ACE_Module<ACE_SYNCH_USE>::link (ACE_Module<ACE_SYNCH_USE> *m)
00078 {
00079   ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::link");
00080   this->next (m);
00081   this->writer ()->next (m->writer ());
00082   m->reader ()->next (this->reader ());
00083 }
00084 
00085 template <ACE_SYNCH_DECL> int
00086 ACE_Module<ACE_SYNCH_USE>::open (const ACE_TCHAR *mod_name,
00087                                  ACE_Task<ACE_SYNCH_USE> *writer_q,
00088                                  ACE_Task<ACE_SYNCH_USE> *reader_q,
00089                                  void *arg,
00090                                  int flags /* = M_DELETE */)
00091 {
00092   ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::open");
00093   this->name (mod_name);
00094   this->arg_ = arg;
00095 
00096   // We may already have readers and/or writers.
00097   if (this->reader ())
00098     this->close_i (0, M_DELETE_READER);
00099 
00100   if (this->writer ())
00101     this->close_i (1, M_DELETE_WRITER);
00102 
00103   if (writer_q == 0)
00104     {
00105       ACE_NEW_RETURN (writer_q,
00106                       ACE_Thru_Task<ACE_SYNCH_USE>,
00107                       -1);
00108       ACE_SET_BITS (flags, M_DELETE_WRITER);
00109     }
00110 
00111   if (reader_q == 0)
00112     {
00113       ACE_NEW_RETURN (reader_q,
00114                       ACE_Thru_Task<ACE_SYNCH_USE>,
00115                       -1);
00116       ACE_SET_BITS (flags, M_DELETE_READER);
00117     }
00118 
00119   this->reader (reader_q);
00120   this->writer (writer_q);
00121 
00122   // Save the flags
00123   this->flags_ = flags;
00124 
00125   // Make sure that the memory is allocated before proceding.
00126   if (writer_q == 0 || reader_q == 0)
00127     {
00128       // These calls will delete writer_q and/or reader_q, if
00129       // necessary.
00130       this->close_i (0, M_DELETE_READER);
00131       this->close_i (1, M_DELETE_WRITER);
00132 
00133       errno = ENOMEM;
00134       return -1;
00135     }
00136 
00137   // Setup back pointers (this must come last, after we've made sure
00138   // there's memory allocated here.
00139   reader_q->mod_ = this;
00140   writer_q->mod_ = this;
00141 
00142   return 0;
00143 }
00144 
00145 // Set and get pointer to sibling ACE_Task in ACE_Module.
00146 
00147 template <ACE_SYNCH_DECL> ACE_Task<ACE_SYNCH_USE> *
00148 ACE_Module<ACE_SYNCH_USE>::sibling (ACE_Task<ACE_SYNCH_USE> *orig)
00149 {
00150   ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::sibling");
00151   if (this->q_pair_[0] == orig)
00152     return this->q_pair_[1];
00153   else if (this->q_pair_[1] == orig)
00154     return this->q_pair_[0];
00155   else
00156     return 0;
00157 }
00158 
00159 template <ACE_SYNCH_DECL>
00160 ACE_Module<ACE_SYNCH_USE>::ACE_Module (void)
00161   : flags_ (0)
00162 {
00163   ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::ACE_Module");
00164   this->name (ACE_LIB_TEXT ("<unknown>"));
00165   // Do nothing...
00166   this->q_pair_[0] = 0;
00167   this->q_pair_[1] = 0;
00168 }
00169 
00170 template <ACE_SYNCH_DECL>
00171 ACE_Module<ACE_SYNCH_USE>::~ACE_Module (void)
00172 {
00173   ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::~ACE_Module");
00174 
00175   // Only close down if we haven't already done so.
00176   if (this->reader () || this->writer ())
00177     this->close ();
00178 }
00179 
00180 template <ACE_SYNCH_DECL>
00181 ACE_Module<ACE_SYNCH_USE>::ACE_Module (const ACE_TCHAR *mod_name,
00182                                        ACE_Task<ACE_SYNCH_USE> *writer_q,
00183                                        ACE_Task<ACE_SYNCH_USE> *reader_q,
00184                                        void *args,
00185                                        int flags /* = M_DELETE */)
00186   : flags_ (0)
00187 {
00188   ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::ACE_Module");
00189 
00190   this->q_pair_[0] = 0;
00191   this->q_pair_[1] = 0;
00192 
00193   if (this->open (mod_name, writer_q, reader_q, args, flags) == -1)
00194     ACE_ERROR ((LM_ERROR,
00195                 ACE_LIB_TEXT ("%p\n"),
00196                 ACE_LIB_TEXT ("ACE_Module")));
00197 }
00198 
00199 template <ACE_SYNCH_DECL> int
00200 ACE_Module<ACE_SYNCH_USE>::close (int flags /* = M_DELETE_NONE */)
00201 {
00202   ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::close");
00203 
00204   int result = 0;
00205 
00206   // Only pay attention to the flags parameter if we haven't already
00207   // set the task delete policies.
00208   if (this->flags_ == 0)
00209     ACE_SET_BITS (flags_, flags);
00210 
00211   if (this->close_i (0, flags_) == -1)
00212     result = -1;
00213 
00214   if (this->close_i (1, flags_) == -1)
00215     result = -1;
00216 
00217   return result;
00218 }
00219 
00220 template <ACE_SYNCH_DECL> int
00221 ACE_Module<ACE_SYNCH_USE>::close_i (int which,
00222                                     int flags)
00223 {
00224   ACE_TRACE ("ACE_Module<ACE_SYNCH_USE>::close_i");
00225 
00226   if (this->q_pair_[which] == 0)
00227     return 0;
00228 
00229   // Copy task pointer to prevent problems when ACE_Task::close
00230   // changes the task pointer
00231   ACE_Task<ACE_SYNCH_USE> *task = this->q_pair_[which];
00232 
00233   // Change so that close doesn't get called again from the task base.
00234 
00235   // Now close the task.
00236   int result = 0;
00237 
00238   if (task->module_closed () == -1)
00239     result = -1;
00240 
00241   task->flush ();
00242   task->next (0);
00243 
00244   // Should we also delete it ?
00245   if (flags != M_DELETE_NONE
00246       && ACE_BIT_ENABLED (flags_, which + 1))
00247     {
00248       // Only delete the Tasks if there aren't any more threads
00249       // running in them.
00250       task->wait ();
00251 
00252       // If this assert happens it is likely because the task was
00253       // activated with the THR_DETACHED flag, which means that we
00254       // can't join() with the thread.  Not using THR_DETACHED should
00255       // solve this problem.
00256       ACE_ASSERT (task->thr_count () == 0);
00257 
00258       delete task;
00259     }
00260 
00261   // Set the tasks pointer to 0 so that we don't try to close()
00262   // this object again if the destructor gets called.
00263   this->q_pair_[which] = 0;
00264 
00265   // Finally remove the delete bit.
00266   ACE_CLR_BITS (flags_, which + 1);
00267 
00268   return result;
00269 }
00270 
00271 ACE_END_VERSIONED_NAMESPACE_DECL
00272 
00273 #endif /* ACE_MODULE_CPP */

Generated on Thu Nov 9 09:41:56 2006 for ACE by doxygen 1.3.6