Main Page   Class Hierarchy   Compound List   File List   Compound Members  

mlinknode.cc

00001 #include "stdafx.h"
00002 #include "mlinknode.h"
00003 
00005 M_ImplementDynClass (LinkNode)
00006 
00007 LinkNode::LinkNode (IndVect sizeData) : VectLnNdCnncn (sizeData), mChgCnncn (0), mProtected (0), mNotifyConnection (N_false), mLastChanged (NULL) {
00008 }
00009 
00010 /*virtual*/ LinkNode::~LinkNode () {
00011     if (items ())
00012         disconnectAll () ;
00013 }
00014 
00015 StsLnNB LinkNode::connect (LinkNode const &other) {
00016     ASSERT (&other != this) ;
00017     addProtect () ;
00018     ((LinkNode &) other).addProtect () ;
00019     StsLnNB ret = stsLnNd (setConnected (other), ((LinkNode &) other).setConnected (*this)) ;
00020     ((LinkNode &) other).removeProtect () ;
00021     removeProtect () ;
00022     return ret ;
00023 }
00024 
00025 StsLnNd LinkNode::disconnect (LinkNode const &other, IndLnNd iOther) {
00026     LnNdCnncn const &cnn = (*this) [iOther] ;
00027     if (!(cnn.state & N_LnNdCnncnStt_Connected))
00028         return N_StsLnNd_Warning | N_StsLnNd_AlreadyDone ;
00029     addProtect () ;
00030     ((LinkNode &) other).addProtect () ;
00031     IndLnNd iThis = other.find (*this) ;
00032     if (iOther == N_IndLnNd_Invalid || iThis == N_IndLnNd_Invalid) {
00033         TRACE ("Trying disconnect %p:%s:%d and %p:%s:%d.\n", (CPtr) this, (CStr) getHost (NULL), (int) iOther, (CPtr) &other, (CStr) other.getHost (NULL), (int) iThis) ;
00034         trace (*this, 2, N_LnNdCnncnStt_) ;
00035         trace (other, 2, N_LnNdCnncnStt_) ;
00036         assert (0) ;
00037     }
00038     VERIFY_not_stsLnNdIsError (setDisconnected (iOther)) ;
00039     VERIFY_not_stsLnNdIsError (((LinkNode &) other).setDisconnected (iThis)) ;
00040     ((LinkNode &) other).removeProtect () ;
00041     removeProtect () ;
00042     return N_StsLnNd_OK ;
00043 }
00044 
00045 StsLnNd LinkNode::disconnect (LinkNode const &other) {
00046     IndVect iOther = find (other) ;
00047     if (iOther == N_IndVect_Invalid)
00048         return N_StsLnNd_Warning | N_StsLnNd_NoSuchLnNd ;
00049     return disconnect (other, iOther) ;
00050 }
00051 
00052 StsLnNd LinkNode::reserve (LinkNode const &other) {
00053     ASSERT (&other != this) ;
00054     addProtect () ;
00055     ((LinkNode &) other).addProtect () ;
00056     StsLnNd ret = setConnectedAnd (other, N_LnNdCnncnStt_Reserve, N_LnNdCnncnStt_ChgReserve) ;
00057     ((LinkNode &) other).setConnectedAnd (*this, N_LnNdCnncnStt_ReservedBy, N_LnNdCnncnStt_ChgReservedBy) ;
00058     ((LinkNode &) other).removeProtect () ;
00059     removeProtect () ;
00060     return ret ;
00061 }
00062 
00063 StsLnNd LinkNode::release (LinkNode const &other) {
00064     IndLnNd i = find (other) ;
00065     if (i == N_IndLnNd_Invalid)
00066         return N_StsLnNd_Error | N_StsLnNd_NoSuchLnNd ;
00067     return release (i) ;
00068 }
00069 
00070 StsLnNd LinkNode::release (IndLnNd iOther) {
00071     addProtect () ;
00072     LnNdCnncn &cnn = operator[] (iOther) ;
00073     if ((cnn.state & (N_LnNdCnncnStt_Reserve | N_LnNdCnncnStt_Connected)) != (N_LnNdCnncnStt_Reserve | N_LnNdCnncnStt_Connected))
00074         return N_StsLnNd_Warning | N_StsLnNd_AlreadyDone ;
00075     LinkNode *other = (LinkNode *) cnn.node ;
00076     other->addProtect () ;
00077     cnn.state &= ~N_LnNdCnncnStt_Reserve ;
00078     cnn.state |= N_LnNdCnncnStt_ChgRelease ;
00079     connectionChanged (&cnn, N_LnNdCnncnStt_ChgRelease) ;
00080     other->setReleasedBy (*this) ;
00081     other->removeProtect () ;
00082     removeProtect () ;
00083     return N_StsLnNd_OK ;
00084 }
00085 
00086 void LinkNode::disconnectAll () {
00087     addProtect () ;
00088     LnNdCnncn const *cnn ;
00089     for (IndLnNd i = 0 ; !!(cnn = iterConnection (i)) ; i++) {
00090         if (cnn->node && (cnn->state & N_LnNdCnncnStt_Connected))
00091             disconnect (*cnn->node, i) ;
00092     }
00093     removeProtect () ;
00094 }
00095 
00096 Bool LinkNode::isConnected (LinkNode const &other) const {
00097     IndLnNd i = find (other) ;
00098     if (i == N_IndLnNd_Invalid)
00099         return N_false ;
00100     return isConnected (i) ;
00101 }
00102 
00103 Bool LinkNode::isConnected (ClassName clsName) const {
00104     for (IndLnNd i = 0 ; iterConnected (i, clsName) != NULL ; i++)
00105         return N_true ;
00106     return N_false ;
00107 }
00108 
00109 Bool LinkNode::isReservedBy (LinkNode const &other) const {
00110     IndLnNd i = find (other) ;
00111     if (i == N_IndLnNd_Invalid)
00112         return N_false ;
00113     return isReservedBy (i) ;
00114 }
00115 
00116 Bool LinkNode::isConnected () const {
00117     for (IndLnNd i = 0 ; i < items () ; i++)
00118         if ((*this) [i].state & N_LnNdCnncnStt_Connected)
00119             return N_true ;
00120     return N_false ;
00121 }
00122 
00123 Bool LinkNode::isReserved () const {
00124     for (IndLnNd i = 0 ; i < items () ; i++)
00125         if ((*this) [i].state & N_LnNdCnncnStt_ReservedBy) {
00126             ASSERT ((*this) [i].state & N_LnNdCnncnStt_Connected) ;
00127             return N_true ;
00128         }
00129     return N_false ;
00130 }
00131 
00132 Bool LinkNode::hasReserved () const {
00133     for (IndLnNd i = 0 ; i < items () ; i++)
00134         if ((*this) [i].state & N_LnNdCnncnStt_Reserve) {
00135             ASSERT ((*this) [i].state & N_LnNdCnncnStt_Connected) ;
00136             return N_true ;
00137         }
00138     return N_false ;
00139 }
00140 
00141 LnNdCnncn const *LinkNode::iterChanged (IndLnNd &i) const {
00142     for (LnNdCnncn const *ret ; !!(ret = iterConnection (i)) ; i++)
00143         if (ret->state & N_LnNdCnncnStt_Chg_)
00144             return ret ;
00145     return NULL ;
00146 }
00147 
00148 LnNdCnncn const *LinkNode::iterConnected (IndLnNd &i) const {
00149     for (LnNdCnncn const *ret ; !!(ret = iterConnection (i)) ; i++)
00150         if (ret->state & N_LnNdCnncnStt_Connected)
00151             return ret ;
00152     return NULL ;
00153 }
00154 
00155 LnNdCnncn const *LinkNode::iterReserved (IndLnNd &i) const {
00156     for (LnNdCnncn const *ret ; !!(ret = iterConnection (i)) ; i++)
00157         if ((ret->state & (N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_Reserve)) == (N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_Reserve))
00158             return ret ;
00159     return NULL ;
00160 }
00161 
00162 LnNdCnncn const *LinkNode::iterReserver (IndLnNd &i) const {
00163     for (LnNdCnncn const *ret ; !!(ret = iterConnection (i)) ; i++)
00164         if ((ret->state & (N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ReservedBy)) == (N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ReservedBy))
00165             return ret ;
00166     return NULL ;
00167 }
00168 
00169 void const *LinkNode::iterConnected (IndLnNd &i, ClassName clsName) const {
00170     CPtr ret ;
00171     for (LnNdCnncn const *cnn ; !!(cnn = iterConnected (i)) ; i++)
00172         if (!!(ret = cnn->node->getHost (clsName)))
00173             return ret ;
00174     return NULL ;
00175 }
00176 
00177 StsLnNd LinkNode::setConnected (LinkNode const &other) {
00178     ASSERT (mProtected) ;   // Must be protected
00179     IndLnNd i ;
00180     LnNdCnncn *cnn ;
00181     if ((i = find (other)) != N_IndLnNd_Invalid) {  // Connection already exists?
00182         cnn = &((*this) [i]) ;
00183         if (cnn->state & N_LnNdCnncnStt_Connected)
00184             return N_StsLnNd_Warning | N_StsLnNd_AlreadyDone ;
00185         cnn->state |= (N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ChgConnected) ;
00186     } else {    // ..no, create a new connection.
00187         i = allocNewItem () ;
00188         ASSERT (i != N_IndLnNd_Invalid) ;
00189         cnn = &((*this) [i]) ;
00190         cnn->node = &((LinkNode &) other) ;
00191         cnn->state = (N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ChgConnected) ;
00192     }
00193     connectionChanged (cnn, N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ChgConnected) ;
00194     return N_StsLnNd_OK ;
00195 }
00196 
00197 StsLnNd LinkNode::setConnectedAnd (LinkNode const &other, LnNdCnncnType status, LnNdCnncnType change) {
00198     ASSERT (mProtected) ;   // Must be protected
00199     IndLnNd i ;
00200     LnNdCnncn *cnn ;
00201     LnNdCnncnType chg ;
00202     if ((i = find (other)) != N_IndLnNd_Invalid) {  // Connection already exists?
00203         cnn = &((*this) [i]) ;
00204         if ((cnn->state & status) == status) {
00205             ASSERT (cnn->state & N_LnNdCnncnStt_Connected) ;
00206             return N_StsLnNd_Warning | N_StsLnNd_AlreadyDone ;
00207         }
00208         if (!(cnn->state & N_LnNdCnncnStt_Connected)) {
00209             cnn->state |= (N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ChgConnected) ;
00210             chg = N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ChgConnected ;
00211         } else
00212             chg = 0 ;
00213     } else {    // ..no, create a new connection.
00214         i = allocNewItem () ;
00215         ASSERT (i != N_IndLnNd_Invalid) ;
00216         cnn = &((*this) [i]) ;
00217         cnn->node = &((LinkNode &) other) ;
00218         cnn->state = (N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ChgConnected) ;
00219         chg = N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ChgConnected ;
00220     }
00221     chg |= status | change ;
00222     cnn->state |= chg ;
00223     connectionChanged (cnn, chg) ;
00224     return N_StsLnNd_OK ;
00225 }
00226 
00227 StsLnNd LinkNode::setDisconnected (IndLnNd iOther) {
00228     ASSERT (mProtected) ;   // Must be protected
00229     if (iOther == N_IndLnNd_Invalid || items () < iOther)
00230         return N_StsLnNd_Error | N_StsLnNd_InvalidRef ;
00231     LnNdCnncn &cnn = operator[] (iOther) ;
00232     if (!(cnn.state & N_LnNdCnncnStt_Connected))
00233         return N_StsLnNd_Warning | N_StsLnNd_AlreadyDone ;
00234     StsLnNd ret = N_StsLnNd_OK ;
00235     LnNdCnncnType chg = 0 ;
00236     if (cnn.state & N_LnNdCnncnStt_ReservedBy) {    // Is this node reserved?
00237         chg |= N_LnNdCnncnStt_ChgReleasedBy ;
00238         ret |= N_StsLnNd_ReleasedBy ;
00239     }
00240     if (cnn.state & N_LnNdCnncnStt_Reserve) {
00241         chg |= N_LnNdCnncnStt_ChgRelease ;
00242         ret |= N_StsLnNd_Release ;
00243     }
00244     cnn.state &= ~(N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_Reserve | N_LnNdCnncnStt_ReservedBy | N_LnNdCnncnStt_FlagA | N_LnNdCnncnStt_FlagB | N_LnNdCnncnStt_FlagC | N_LnNdCnncnStt_FlagD) ;
00245     chg |= N_LnNdCnncnStt_ChgDisconnected ;
00246     cnn.state |= chg ;
00247     connectionChanged (&cnn, chg) ;
00248     return ret ;
00249 }
00250 
00251 void LinkNode::setReleasedBy (IndLnNd iOther) {
00252     ASSERT (mProtected) ;   // Must be protected
00253     ASSERT (iOther != N_IndLnNd_Invalid && iOther < items ()) ;
00254     LnNdCnncn &cnn = operator[] (iOther) ;
00255     ASSERT ((cnn.state & (N_LnNdCnncnStt_ReservedBy | N_LnNdCnncnStt_Connected)) == (N_LnNdCnncnStt_ReservedBy | N_LnNdCnncnStt_Connected)) ;   // Reserved and connected.
00256     cnn.state &= ~N_LnNdCnncnStt_ReservedBy ;
00257     cnn.state |= N_LnNdCnncnStt_ChgReleasedBy ;
00258     connectionChanged (&cnn, N_LnNdCnncnStt_ChgReleasedBy) ;
00259 }
00260 
00261 void LinkNode::removeProtect () {
00262     ASSERT (mProtected != 0) ;
00263     if (--mProtected == 0 && mChgCnncn) {
00264         notifyBeginNotify (mChgCnncn) ;
00265 
00266         // Execute loop as long as the connections of the node are
00267         // changed somehow during the notifys
00268         LnNdCnncnType changed = 0 ;
00269         while (mChgCnncn) {
00270             ASSERT (mLastChanged) ;
00271             changed |= mChgCnncn ;
00272             mProtected++ ;
00273             mChgCnncn = 0 ;
00274             sendNotifys () ;
00275             VERIFY (--mProtected == 0) ;
00276         }
00277 
00278         // If any connection has been marked as disconnected, purge
00279         // them now
00280         if (changed & N_LnNdCnncnStt_ChgDisconnected)
00281             purgeDisconnectedConnections () ;
00282 
00283         // Notify the node that disconnected links have been purged
00284         notifyNotifiedAndPurged (changed) ;
00285     }
00286 }
00287 
00288 void LinkNode::sendNotifys () {
00289     LnNdCnncn *cnn = (LnNdCnncn *) mLastChanged ;
00290     mLastChanged = NULL ;
00291     if (items ())
00292         if (mNotifyConnection) {    // Send notify about changed connections?
00293             // Is only one connection changed?
00294             if (cnn != (LnNdCnncn *) -1) {
00295                 // yes, we can do it in O(1) by using the saved
00296                 // connection reference
00297                 LnNdCnncnType state = cnn->state ;
00298                 cnn->state &= ~N_LnNdCnncnStt_Chg_ ;
00299                 notifyConnection (state, cnn) ;
00300             } else {
00301                 // no, several connections changed so iterate through
00302                 // all connections.
00303                 IndLnNd i = items () - 1 ;
00304                 do {
00305                     LnNdCnncn &cnn = (*this) [i] ;
00306                     if (cnn.node)
00307                         if (cnn.state & N_LnNdCnncnStt_Chg_) {
00308                             LnNdCnncnType state = cnn.state ;
00309                             cnn.state &= ~N_LnNdCnncnStt_Chg_ ;
00310                             notifyConnection (state, &cnn) ;
00311                         }
00312                 } while (i-- != 0) ;
00313             }
00314         } else  // No, just clear changed-flag.
00315             for (IndLnNd i = 0 ; i < items () ; i++)
00316                 (*this) [i].state &= ~N_LnNdCnncnStt_Chg_ ;
00317 }
00318 
00319 inline Bool isConnectionUsed (LnNdCnncnType state) {
00320     return (state & N_LnNdCnncnStt_Connected) ;
00321 }
00322 
00323 Bool LinkNode::purgeDisconnectedConnections () {    // Purge not used connections.
00324     if (items ()) {
00325         Bool ret = N_false ;
00326         IndVect size = items () ;
00327         Bool purge = N_false ;
00328         for (IndLnNd i = 0 ; i < items () && isConnectionUsed ((*this) [i].state) ; i++) ;  // Search connection to move.
00329         if (i < size) { // We encountered to unused connection.
00330             IndLnNd iMoveTo = i ;
00331             do {
00332                 for (i++ ; i < items () && !isConnectionUsed ((*this) [i].state) ; i++) ;   // Search a connected connection.
00333                 if (i < items ()) {
00334                     IndLnNd iMoveFrom = i ;
00335                     for (i++ ; i < items () && isConnectionUsed ((*this) [i].state) ; i++) ;
00336                     memmove (itemNT (iMoveTo), itemNT (iMoveFrom), (i - iMoveFrom) * mItemSize) ;
00337                     size = iMoveTo = iMoveTo + (i - iMoveFrom) ;
00338                 } else
00339                     size = iMoveTo ;
00340             } while (i < items ()) ;
00341             setSize (size) ;
00342             return N_true ;
00343         }
00344     }
00345     return N_false ;
00346 }
00347 
00348 void trace (LinkNode const &ob, IndVect indent, LnNdCnncnType show1) {
00349     String fill ;
00350     if (indent) {
00351         fill.set (' ', indent) ;
00352         TRACE ((CStr) fill) ;
00353     }
00354     TRACE ("%p: [%d/%d] %d %04lx %s %s ", (CPtr) &ob, (int) ob.connections ().items (), (int) ob.connections ().allocated (), (int) ob.gProtected (), (DWord) ob.gChgCnncn (), ob.clsName (), (CStr) ob.getHost (NULL)) ;
00355     char str [100] ;
00356     TRACE (ob.gLastChanged () ? (ob.gLastChanged () == (LnNdCnncn const *) -1 ? "-1" : type2Str (str, ob.connections ().index (ob.gLastChanged ()))) : "NULL") ;
00357     TRACE ("\n") ;
00358     LnNdCnncn const *cnn ;
00359     for (IndLnNd i = 0 ; (cnn = ob.iterConnection (i)) != NULL ; i++)
00360         if (show1 == N_LnNdCnncnStt_ || (cnn->state & show1)) {
00361             if (indent)
00362                 TRACE ((CStr) fill) ;
00363             TRACE ("    [%d] (%04lx %p %s %s)\n", (int) i, (DWord) cnn->state, (CPtr) cnn->node, (CStr) cnn->node->clsName (), (CStr) cnn->node->getHost (NULL)) ;
00364         }
00365 }
00366 
00367 #ifdef __STRING_H__
00368     String& links2Str (String& ret, LinkNode const &ob) {
00369         char str [100] ;
00370         sprintf (str, "%p: %d [%d/%d] %04lx %s %s ", (CPtr) &ob, (int) ob.gProtected (), (int) ob.connections ().items (), (int) ob.connections ().allocated (), (DWord) ob.gChgCnncn (), ob.clsName (), (CStr) ob.getHost (NULL)) ;
00371         ret = str ;
00372         ret += (ob.gLastChanged () ? (ob.gLastChanged () == (LnNdCnncn const *) -1 ? "-1" : type2Str (str, ob.connections ().index (ob.gLastChanged ()))) : "NULL") ;
00373         LnNdCnncn const *cnn ;
00374         for (IndLnNd i = 0 ; (cnn = ob.iterConnected (i)) != NULL ; i++) {
00375             sprintf (str, " (%4lx %p %s %s)", (DWord) cnn->state, (CPtr) cnn->node, (CStr) cnn->node->clsName (), (CStr) cnn->node->getHost (NULL)) ;
00376             ret += str ;
00377         }
00378         return ret ;
00379     }
00380 #endif  // __STRING_H__
00381 
00383 /*virtual*/IndLnNd  VectLnNdCnncn::getGrow (IndLnNd minSize) const {
00384     IndLnNd ret = max ((IndLnNd) minSize, (IndLnNd) (mItems + (mItems ? mItems : 5))) ;
00385     return ret ;
00386 }
00387 
00388 IndLnNd VectLnNdCnncn::find (LinkNode const *node) const {
00389     if (items ()) {
00390         IndLnNd i = items () - 1 ;
00391         do
00392             if (operator[] (i).node == node)
00393                 return i ;
00394         while (i-- != 0) ;
00395     }
00396     return N_IndLnNd_Invalid ;
00397 }
00398 
00399 
00400 
00402 //                                                                            //
00403 //  ----                                  | |     o       |   |   |          |       |   |          o           //
00404 // (            ____  --   ___    _       | |         _   |   |\  |          |  ___  |\  |       |     __       //
00405 //  ---  |   | (     |  ) /   ) |/ \   ---| |     | |/ \  | / | \ |  __   ---| /   ) | \ |  __  -+- | /   \   | //
00406 //     ) |   |  \__  |--  |---  |   | (   | |     | |   | |/  |  \| /  \ (   | |---  |  \| /  \  |  | +--  \  | //
00407 // ___/   \__! ____) |     \__  |   |  ---| |____ | |   | | \ |   | \__/  ---|  \__  |   | \__/   \ | |     \_/ //
00408 //                                                                                                    |    \_/  //
00410 
00411 /*virtual*/ SuspendLinkNodeNotify::~SuspendLinkNodeNotify () {
00412     releaseAll () ;
00413 }
00414 
00415 void SuspendLinkNodeNotify::notifyConnection (LnNdCnncnType chg, LnNdCnncn const *cnncn) {
00416     if ((chg & (N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ChgConnected)) == (N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ChgConnected)) {             // Linked new node?
00417         LinkNode *node = (LinkNode *) cnncn->node ;
00418         ASSERT (node) ;
00419         node->addProtect () ;
00420     } else if ((chg & (N_LnNdCnncnStt_Connected | N_LnNdCnncnStt_ChgDisconnected)) == N_LnNdCnncnStt_ChgDisconnected) { // Unlinked node?
00421         LinkNode *node = (LinkNode *) cnncn->node ;
00422         ASSERT (node) ;
00423         node->removeProtect () ;
00424     }
00425 }
00426 
00427 void SuspendLinkNodeNotify::notifyNotifiedAndPurged (LnNdCnncnType chg) {
00428 }
00429 
00430 SuspendLinkNodeNotify &operator, (SuspendLinkNodeNotify &suspend, LinkNode &connect) {
00431     VERIFY_not_stsLnNdIsError (suspend.connect (connect)) ;
00432     return suspend ;
00433 }
00434     
00435 
00436 
00438 //  |   |          |       ----                                             //
00439 //  |\  |          |  ___  |   )           ___   ___   ____  ____           //
00440 //  | \ |  __   ---| /   ) |---  |/\  __  |   \ /   ) (     (      __  |/\  //
00441 //  |  \| /  \ (   | |---  |     |   /  \ |     |---   \__   \__  /  \ |    //
00442 //  |   | \__/  ---|  \__  |     |   \__/  \__/  \__  ____) ____) \__/ |    //
00444 
00445 //M_ImplementDynClass1 (ClcnNodesPrc, LinkNode)
00446 
00447 ProcessNodes::ProcessNodes () {
00448     mCurrPrcNodes = &mNodesA ;
00449     mPendingCount = 0 ;
00450 }
00451 
00452 ProcessNodes::~ProcessNodes () {
00453 }
00454 
00455 void ProcessNodes::removeSuspend () {
00456     if (--mPendingCount == 0)
00457         process () ;
00458 }
00459 
00460 void ProcessNodes::process () {
00461     while (pcrNodesCurr ().isConnected ()) {
00462         mPendingCount++ ;
00463         LinkNode &senders = pcrNodesCurr () ;
00464         mCurrPrcNodes = &prcNodesNotCurr () ;   // Change notify-sender.
00465 
00466         senders.addProtect () ;
00467         LnNdCnncn const *cnn ;
00468         for (IndLnNd i = 0 ; !!(cnn = senders.iterConnected (i)) ; i++)
00469             process (*cnn) ;
00470         senders.disconnectAll () ;
00471         senders.removeProtect () ;
00472         mPendingCount-- ;
00473     }
00474     ASSERT (!mNodesA.isConnected ()) ;
00475     ASSERT (!mNodesB.isConnected ()) ;
00476 }
00477 
00478 SuspendProcessNodes::SuspendProcessNodes (ProcessNodes *const *processors) : mProcessors (processors) {
00479     for (char i = 0 ; mProcessors [i] ; i++)
00480         mProcessors [i]->addSuspend () ;
00481 }
00482 
00483 /*virtual*/ SuspendProcessNodes::~SuspendProcessNodes () {
00484     ASSERT (mProcessors [0]) ;
00485     char iPrc ;
00486     ProcessNodes *prc ;
00487     if (mProcessors [0]->gPendingCount () == 1) {   // This is highest level suspender?
00488         char i ;
00489         for (iPrc = 0 ; !!(prc = mProcessors [iPrc]) ; iPrc++) {
00490             ASSERT (prc->gPendingCount () == 1) ;
00491             prc->process () ;
00492             for (i = 0 ; i < iPrc ; i++)                // Check if removeSuspend caused new processes for lower level(s).
00493                 if (mProcessors [i]->hasWaitingProcesses ())
00494                     iPrc = i - i ;
00495         }
00496     }
00497     for (iPrc = 0 ; !!(prc = mProcessors [iPrc]) ; iPrc++)
00498         prc->removeSuspend () ;
00499 }
00500 
00502 // (c) Wallac Oy & Instrudev Oy & Mao 86
00503 //
00504 // Created: 1994-1997
00505 // Modifications:
00506 // ........ ... ... .........................................................
00507 // 19991122     Mao Rewritten in Wallac Oy. Based on LinkBase LINK.H & LINK.CPP

Generated at Tue Dec 4 19:53:25 2001 for MagiC++ by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001