Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

mlinknode.cc

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

Generated on Thu Feb 10 20:06:42 2005 for LibMagiC by doxygen1.2.18