Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

CTBcallbackBase.cxx

Go to the documentation of this file.
00001 
00007 /*----------------------------------------------------------------------------*/
00008 /* C Tool Box: Designed and implemented by:                                   */
00009 /*    Walter F.J. Mueller   Gesellschaft fuer Schwerionenforschung (GSI)      */
00010 /*                          Planckstrasse 1, D-64291 Darmstadt, Germany       */
00011 /*                  Email:  W.F.J.Mueller@gsi.de                              */
00012 /*                  WWW:    http://www-kp3.gsi.de/www/kp3/people/mueller.html */
00013 /*------------------------------------------+---------------------------------*/
00014 
00015 #include <assert.h>
00016 
00017 #include "CTB.hxx"
00018 #include "CTB_Trace.hxx"
00019 
00020 #include "CTBcallbackBase.hxx"
00021 
00027 //------------------------------------------+-----------------------------------
00029 
00030 CTBcallbackSourceBase::~CTBcallbackSourceBase()
00031 {
00032   CTB_Trace("~CTBcallbackSourceBase()");
00033 
00034   while(m_shead) {
00035     CTBcallbackLink* p_link = m_shead.First();
00036     
00037     if (p_link->Busy()) {
00038       p_link->UnlinkSource();
00039     } else {
00040       delete p_link;
00041     }
00042   }
00043 }
00044 
00045 //------------------------------------------+-----------------------------------
00047 
00048 int CTBcallbackSourceBase::NConnect() const
00049 {
00050   CTB_Trace("CTBcallbackSourceBase::NConnect()");
00051 
00052   int i_nconnect = 0;
00053   
00054   for(CTBcallbackLink* p_link = m_shead.First(); p_link;
00055                        p_link = p_link->m_slink.Next()) {
00056     if (!p_link->Zombie()) i_nconnect++;
00057   }
00058   
00059   return i_nconnect;
00060 }
00061 
00062 //------------------------------------------+-----------------------------------
00064 
00065 void CTBcallbackSourceBase::Execute(void* p_arg) const
00066 {
00067   CTB_Trace("CTBcallbackSourceBase::Execute(void*)");
00068 
00069   for(CTBcallbackLink* p_link = m_shead.First(); p_link; ) {
00070     CTBcallbackLink* p_next = p_link->m_slink.Next();
00071 
00072     if (!p_link->Zombie()) {                // if not marked for delete
00073       p_link->Mark();                       // lock link against deletion
00074       try {
00075         p_link->m_tlink.Parent()->Execute(p_arg); // DO IT !!
00076 
00077       } catch(...) {                        // in case of exception
00078         p_link->Unmark();                   // unlock
00079         if (p_link->Deletable()) delete p_link; // burry zombie if possible
00080         throw;                              // and rethrow
00081       }
00082 
00083       p_link->Unmark();                     // unlock
00084       p_next = p_link->m_slink.Next();      // re-evaluate in case of deletions
00085       if (p_link->Deletable()) delete p_link; // burry zombie if possible
00086     }
00087 
00088     p_link = p_next;
00089   }
00090 
00091   return;
00092 }
00093 
00094 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00095 
00101 //------------------------------------------+-----------------------------------
00103 
00104 CTBcallbackTargetBase::~CTBcallbackTargetBase()
00105 {
00106   CTB_Trace("~CTBcallbackTargetBase()");
00107 
00108   Disconnect();
00109 }
00110 
00111 //------------------------------------------+-----------------------------------
00113 
00114 int CTBcallbackTargetBase::NConnect() const
00115 {
00116   CTB_Trace("CTBcallbackTargetBase::NConnect()");
00117 
00118   int i_nconnect = 0;
00119   
00120   for(CTBcallbackLink* p_link = m_thead.First(); p_link;
00121                        p_link = p_link->m_tlink.Next()) {
00122     if (!p_link->Zombie()) i_nconnect++;
00123   }
00124   
00125   return i_nconnect;
00126 }
00127 
00128 //------------------------------------------+-----------------------------------
00130 
00131 void CTBcallbackTargetBase::Disconnect()
00132 {
00133   CTB_Trace("CTBcallbackTargetBase::Disconnect()");
00134 
00135   while (m_thead) {
00136     CTBcallbackLink* p_link = m_thead.First();
00137     
00138     if (p_link->Busy()) {
00139       p_link->UnlinkTarget();
00140     } else {
00141       delete p_link;
00142     }
00143   }
00144   
00145   return;
00146 }
00147 
00148 //------------------------------------------+-----------------------------------
00150 
00151 CTBcallbackTargetBase& CTBcallbackTargetBase::operator=(
00152     const CTBcallbackTargetBase& rhs)
00153 {
00154   CTB_Trace("CTBcallbackTargetBase::operator=(const CTBcallbackTargetBase& rhs)");
00155 
00156   if (this == &rhs) return *this;
00157   
00158   Disconnect();
00159   
00160   for (CTBcallbackLink* p_link = rhs.m_thead.First(); p_link;
00161        p_link = p_link->m_tlink.Next()) {
00162     if (!p_link->Zombie()) {
00163       new CTBcallbackLink(*this,*(p_link->m_slink.Head()));
00164     }
00165   }
00166   
00167   return *this;
00168 }
00169 
00170 //------------------------------------------+-----------------------------------
00172 
00173 void CTBcallbackTargetBase::Connect(CTBcallbackSourceBase& source)
00174 {
00175   CTB_Trace("CTBcallbackTargetBase::Connect(CTBcallbackSourceBase&)");
00176 
00177   new CTBcallbackLink(*this, source);
00178   return;
00179 }
00180 
00181 //------------------------------------------+-----------------------------------
00183 
00184 void CTBcallbackTargetBase::Disconnect(CTBcallbackSourceBase& source)
00185 {
00186   CTB_Trace("CTBcallbackTargetBase::Disconnect(CTBcallbackSourceBase&)");
00187 
00188   for (CTBcallbackLink* p_link = m_thead.First(); p_link; ) {
00189     CTBcallbackLink* p_next = p_link->m_tlink.Next();
00190 
00191     if (p_link->m_slink.Head() == &source.m_shead) {
00192       if (p_link->Busy()) {
00193         p_link->UnlinkTarget();
00194       } else {
00195         delete p_link;
00196       }
00197     }
00198     p_link = p_next;
00199   }
00200   
00201   return;
00202 }
00203 
00204 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00205 
00206 #ifdef DEV_DOCS
00207 
00211 #endif
00212 
00213 //------------------------------------------+-----------------------------------
00215 
00216 CTBcallbackLink::CTBcallbackLink(CTBcallbackTargetBase& target,
00217                                  CTBcallbackSourceBase& source)
00218   : m_slink(),
00219     m_tlink(),
00220     mi_nbusy(0)
00221 {
00222   CTB_Trace("CTBcallbackLink(CTBcallbackTargetBase&, CTBcallbackSourceBase&)");
00223 
00224   m_slink.InsertTail(this, &CTBcallbackLink::m_slink, source.m_shead);
00225   m_tlink.InsertTail(this, &CTBcallbackLink::m_tlink, 
00226                      target, &CTBcallbackTargetBase::m_thead);
00227 }
00228 
00229 //------------------------------------------+-----------------------------------
00231 
00232 CTBcallbackLink::CTBcallbackLink(CTBcallbackTargetBase& target,
00233                                  CTBsimpleListHead<CTBcallbackLink>& shead)
00234   : m_slink(),
00235     m_tlink(),
00236     mi_nbusy(0)
00237 {
00238   CTB_Trace("CTBcallbackLink(CTBcallbackTargetBase&, CTBsimpleListHead<CTBcallbackLink>&)");
00239 
00240   m_slink.InsertTail(this, &CTBcallbackLink::m_slink, shead);
00241   m_tlink.InsertTail(this, &CTBcallbackLink::m_tlink, 
00242                      target, &CTBcallbackTargetBase::m_thead);
00243 }
00244 
00245 //------------------------------------------+-----------------------------------
00247 
00248 CTBcallbackLink::~CTBcallbackLink()
00249 {
00250   CTB_Trace("~CTBcallbackLink()");
00251   
00252   assert(mi_nbusy == 0);                    // !?! must not be busy
00253   UnlinkSource();
00254   UnlinkTarget();
00255 }

Generated at Fri Oct 24 18:11:27 2003 for CTBbase by doxygen1.2.9-20010812 written by Dimitri van Heesch, © 1997-2001