00001
00007
00008
00009
00010
00011
00012
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()) {
00073 p_link->Mark();
00074 try {
00075 p_link->m_tlink.Parent()->Execute(p_arg);
00076
00077 } catch(...) {
00078 p_link->Unmark();
00079 if (p_link->Deletable()) delete p_link;
00080 throw;
00081 }
00082
00083 p_link->Unmark();
00084 p_next = p_link->m_slink.Next();
00085 if (p_link->Deletable()) delete p_link;
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);
00253 UnlinkSource();
00254 UnlinkTarget();
00255 }