Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

phList.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission : 
00003         Realtime Vision Processing System
00004     
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008     
00009     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 #ifdef HAVE_CONFIG_H
00027     #include <phissionconfig.h>
00028 #endif
00029 
00030 #include <phStandard.h>
00031 
00032 #include <phObject.h>
00033 #include <phMutex.h>
00034 #include <phList.h>
00035 
00036 #include <phError.h>
00037 #include <phMemory.h>
00038 #include <phPrint.h>
00039 
00040 /* ---------------------------------------------------------------------- */
00041 /* phListNode                                                             */
00042 /* ---------------------------------------------------------------------- */
00043 phListNode::phListNode() : phMutex()
00044 {
00045     phFUNCTION("phListNode::phListNode")
00046     int locked = 0;
00047 
00048     phTHIS_LOOSE_LOCK(locked);
00049 
00050     this->setName("phListNode");
00051     this->m_previous = this->m_next = NULL;
00052     
00053     phTHIS_LOOSE_UNLOCK(locked);
00054 }
00055 
00056 /* ---------------------------------------------------------------------- */
00057 phListNode::~phListNode()
00058 {
00059     phFUNCTION("phListNode::~phListNode")
00060     int locked = 0;
00061 
00062     phTHIS_LOOSE_LOCK(locked);
00063 
00064     this->m_next = this->m_previous = NULL;
00065 
00066     phTHIS_LOOSE_UNLOCK(locked);
00067 }
00068 
00069 /* ---------------------------------------------------------------------- */
00070 int phListNode::setNext ( phListNode *node )
00071 {
00072     phFUNCTION("phListNode::setNext")
00073     int locked = 0;
00074 
00075     phTHIS_LOOSE_LOCK(locked);
00076 
00077     this->m_next = node;
00078 
00079     phTHIS_LOOSE_UNLOCK(locked);
00080      
00081     return phSUCCESS;
00082 }
00083 
00084 /* ---------------------------------------------------------------------- */
00085 int phListNode::setPrevious ( phListNode *node )
00086 {
00087     phFUNCTION("phListNode::setPrevious")
00088     int locked = 0;
00089 
00090     phTHIS_LOOSE_LOCK(locked);
00091 
00092     this->m_previous = node;
00093 
00094     phTHIS_LOOSE_UNLOCK(locked);
00095      
00096     return phSUCCESS;
00097 }
00098 
00099 /* ---------------------------------------------------------------------- */
00100 phListNode *phListNode::getNext ( )
00101 {
00102     phFUNCTION("phListNode::getNext")
00103     int locked = 0;
00104     phListNode *next = NULL;
00105 
00106     phTHIS_LOOSE_LOCK(locked);
00107 
00108     next = this->m_next;
00109 
00110     phTHIS_LOOSE_UNLOCK(locked);
00111      
00112     return next;
00113 }
00114 
00115 /* ---------------------------------------------------------------------- */
00116 phListNode *phListNode::getPrevious ( )
00117 {
00118     phFUNCTION("phListNode::getPrevious")
00119     int locked = 0;
00120     phListNode *prev = NULL;
00121 
00122     phTHIS_LOOSE_LOCK(locked);
00123 
00124     prev = this->m_previous;
00125 
00126     phTHIS_LOOSE_UNLOCK(locked);
00127 
00128     return prev;
00129 }
00130 
00131 
00132 /* ---------------------------------------------------------------------- */
00133 /* phList                                                                 */
00134 /* ---------------------------------------------------------------------- */
00135 phList::phList() : phMutex()
00136 {
00137     phFUNCTION("phList::phList")
00138     int locked = 0;
00139 
00140     phTHIS_LOOSE_LOCK(locked);
00141 
00142     setName("phList");
00143     
00144     this->m_totalNodes = 0;
00145     this->m_head = this->m_tail = NULL;
00146 
00147     phTHIS_LOOSE_UNLOCK(locked);
00148 }
00149 
00150 /* ---------------------------------------------------------------------- */
00151 phList::~phList()
00152 {
00153     phFUNCTION("phList::~phList")
00154     int locked = 0;
00155 
00156     phTHIS_LOOSE_LOCK(locked);
00157 
00158     rc = this->empty();
00159     phPRINT_RC(rc,NULL,"this->empty()");
00160     
00161     phTHIS_LOOSE_UNLOCK(locked);
00162 }
00163 
00164 /* ---------------------------------------------------------------------- */
00165 uint32_t phList::length()
00166 {
00167     return this->getTotal();
00168 }
00169 
00170 /* ---------------------------------------------------------------------- */
00171 uint32_t phList::getTotal()
00172 {
00173     phFUNCTION("phList::getTotal")
00174     int locked = 0;
00175 
00176     int32_t total = 0;
00177 
00178     phTHIS_LOOSE_LOCK(locked);
00179 
00180     total = this->m_totalNodes;
00181 
00182     phTHIS_LOOSE_UNLOCK(locked);
00183 
00184     return total;
00185 }
00186 
00187 /* ---------------------------------------------------------------------- */
00188 int phList::isEmpty()
00189 {
00190     phFUNCTION("phList::isEmpty")
00191     int locked = 0;
00192 
00193     int isempty = 0;
00194 
00195     phTHIS_LOOSE_LOCK(locked);
00196 
00197     isempty = (this->m_totalNodes > 0) ? 0 : 1;
00198 
00199     phTHIS_LOOSE_UNLOCK(locked);
00200     
00201     return isempty;
00202 }
00203 
00204 /* ---------------------------------------------------------------------- */
00205 /* insert - inserts a node into the list. The node must be allocated
00206  * before being passed. */
00207 /* ---------------------------------------------------------------------- */
00208 int phList::insert( phListNode *node, uint32_t index )
00209 {
00210     phFUNCTION("phList::insert")
00211     int locked = 0;
00212 
00213     phListNode *insert_after = NULL;
00214     phListNode *insert_before = NULL;
00215     uint32_t i = 0;
00216 
00217     if (node == NULL) return phFAIL;
00218 
00219     phTHIS_LOOSE_LOCK(locked);
00220 
00221     rc = node->lock();
00222     phPRINT_RC(rc,NULL,"node->lock()");
00223     
00224     /* head and tail should be NULL only at the same time */
00225     if ((this->m_head == NULL) && (this->m_tail == NULL))
00226     {
00227         this->m_tail = this->m_head = node;
00228         
00229         /* Adjust the total count of nodes in the list */
00230         this->m_totalNodes++;
00231     }
00232     else 
00233     {   
00234         if (index <= 0)
00235         {
00236             /* this should always happen if the previous if block 
00237              * isn't satisfied */
00238             if (this->m_head != NULL)
00239             {
00240                 rc = this->m_head->lock();
00241                 phPRINT_RC(rc,NULL,"this->m_head->lock()");
00242                 
00243                 insert_before = this->m_head;
00244                 
00245                 this->m_head = node;
00246             }
00247         }
00248         else if (index >= this->m_totalNodes)
00249         {
00250             /* this should always happen if the previous if block 
00251              * isn't satisfied */
00252             if (this->m_tail != NULL)
00253             {
00254                 rc = this->m_tail->lock();
00255                 phPRINT_RC(rc,NULL,"this->m_tail->lock()");
00256                 
00257                 insert_after = this->m_tail;
00258                 
00259                 this->m_tail = node;
00260             }
00261         }
00262         else if ((index < this->m_totalNodes) && (index > 0))
00263         {
00264             uint32_t temp_half = 0;
00265             
00266             /* Even */
00267             if ((this->m_totalNodes % 2) == 0)
00268             {
00269                 temp_half = this->m_totalNodes / 2;
00270             }
00271             /* Odd */
00272             else
00273             {
00274                 temp_half = (this->m_totalNodes + 1) / 2;
00275             }
00276             
00277             if (index > temp_half)
00278             {
00279                 insert_after  = this->m_tail;
00280                 insert_before = NULL;
00281        
00282                 for ( i = this->m_totalNodes; i > index; i-- )
00283                 {
00284                     if (insert_before != NULL)
00285                     {
00286                         rc = insert_before->unlock();
00287                         phPRINT_RC(rc,NULL,"insert_before->unlock();");
00288                     }
00289                     
00290                     insert_before = insert_after;
00291                     
00292                     if (insert_before != NULL)
00293                     {
00294                         insert_after = insert_before->getPrevious();
00295                         
00296                         if (insert_after != NULL)
00297                         {
00298                             rc = insert_after->lock();
00299                             phPRINT_RC(rc,NULL,"insert_after->lock();");
00300                         }
00301                     }
00302                     else
00303                     {
00304                         insert_after = NULL;
00305                     }
00306                 }
00307             }
00308             else
00309             {
00310                 insert_after  = NULL;
00311                 insert_before = this->m_head;
00312        
00313                 for ( i = 0; i < index; i++ )
00314                 {
00315                     /* Unlock the previous "insert_after" before
00316                      * setting the current "insert_after" */
00317                     if (insert_after != NULL)
00318                     {
00319                         rc = insert_after->unlock();
00320                         phPRINT_RC(rc,NULL,"insert_after->unlock();");
00321                     }
00322                     
00323                     insert_after = insert_before;
00324                     
00325                     if (insert_after != NULL)
00326                     {
00327                         /* Set the new "insert_before" to the 'next' ptr */
00328                         /* Don't need to unlock the previous "insert_before"
00329                          * because it's now the current "insert_after" */
00330                         insert_before = insert_after->getNext();
00331                         
00332                         if (insert_before != NULL)
00333                         {
00334                             /* lock the new "insert_after", aka the previous
00335                              * "insert_before" */
00336                             rc = insert_before->lock();
00337                             phPRINT_RC(rc,NULL,"insert_before->lock();");
00338                         }
00339                     }
00340                     else
00341                     {
00342                         insert_before = NULL;
00343                     }
00344                 }
00345             }
00346         }
00347         
00348         node->setNext( insert_before );
00349         
00350         node->setPrevious( insert_after );
00351 
00352         if (insert_after != NULL)
00353         {
00354             insert_after->setNext( node );
00355         }
00356         else
00357         {
00358             this->m_head = node;
00359         }
00360 
00361         if (insert_before != NULL)
00362         {
00363             insert_before->setPrevious( node );
00364         }
00365         else
00366         {
00367             this->m_tail = node;
00368         }
00369     
00370         if (insert_before != NULL)
00371         {
00372             rc = insert_before->unlock();
00373             phPRINT_RC(rc,NULL,"insert_before->unlock();");
00374         }
00375         if (insert_after != NULL)
00376         {
00377             rc = insert_after->unlock();
00378             phPRINT_RC(rc,NULL,"insert_after->unlock();");
00379         }
00380         
00381         /* Adjust the total count of nodes in the list */
00382         this->m_totalNodes++;
00383     }
00384 
00385     rc = node->unlock();
00386     phPRINT_RC(rc,NULL,"node->unlock()");
00387     
00388     phTHIS_LOOSE_UNLOCK(locked);
00389 
00390     return phSUCCESS;
00391 }
00392     
00393 /* ---------------------------------------------------------------------- */
00394 #define DECLARE_LOCK_CHECKS() \
00395     int locked = 0; \
00396     int node_locked = 0; \
00397     int prev_locked = 0; \
00398     int next_locked = 0;
00399     
00400 #define LOCK() \
00401     if (locked == 0) { \
00402         rc = this->lock(); \
00403         phPRINT_RC(rc,NULL,"this->lock()"); \
00404         locked = 1; \
00405     } \
00406     else \
00407     { \
00408         phPROGRESS("Locked already\n"); \
00409     }
00410 #define LOCK_NODE() \
00411     if (node_locked == 0) \
00412     { \
00413         rc = node->lock(); \
00414         phPRINT_RC(rc,NULL,"node->lock()"); \
00415         node_locked = 1; \
00416     } \
00417     else \
00418     { \
00419         phPROGRESS("Node locked already\n"); \
00420     }
00421 #define LOCK_PREV() \
00422     if (prev_locked == 0) \
00423     { \
00424         if (prev != NULL) \
00425         { \
00426             rc = prev->lock(); \
00427             phPRINT_RC(rc,NULL,"prev->lock();"); \
00428         } \
00429         prev_locked = 1; \
00430     } \
00431     else \
00432     { \
00433         phPROGRESS("Previous locked already\n"); \
00434     }
00435 #define LOCK_NEXT() \
00436     if (next_locked == 0) \
00437     { \
00438         if (next != NULL) \
00439         { \
00440             rc = next->lock(); \
00441             phPRINT_RC(rc,NULL,"next->lock();"); \
00442         } \
00443         next_locked = 1; \
00444     } \
00445     else \
00446     { \
00447         phPROGRESS("Next locked already\n"); \
00448     }
00449 
00450 #define UNLOCK_PREV() \
00451     if (prev_locked == 1) \
00452     { \
00453         if (prev != NULL) \
00454         { \
00455             rc = prev->unlock(); \
00456             phPRINT_RC(rc,NULL,"prev->unlock();"); \
00457         } \
00458         prev_locked = 0; \
00459     } \
00460     else \
00461     { \
00462         phPROGRESS("Previous unlocked already\n"); \
00463     }
00464 #define UNLOCK_NEXT() \
00465     if (next_locked == 1) \
00466     { \
00467         if (next != NULL) \
00468         { \
00469             rc = next->unlock(); \
00470             phPRINT_RC(rc,NULL,"next->unlock();"); \
00471         } \
00472         next_locked = 0; \
00473     } \
00474     else \
00475     { \
00476         phPROGRESS("Next unlocked already\n"); \
00477     }
00478 #define UNLOCK_NODE() \
00479     if (node_locked == 1) \
00480     { \
00481         rc = node->unlock(); \
00482         phPRINT_RC(rc,NULL,"node->unlock()");\
00483         node_locked = 0; \
00484     } \
00485     else \
00486     { \
00487         phPROGRESS("Node unlocked already\n"); \
00488     }
00489 #define UNLOCK() \
00490     if (locked == 1) \
00491     { \
00492         rc = this->unlock(); \
00493         phPRINT_RC(rc,NULL,"this->unlock()"); \
00494         locked = 0; \
00495     } \
00496     else \
00497     { \
00498         phPROGRESS("Unlocked already\n"); \
00499     }
00500 /* ---------------------------------------------------------------------- */
00501 int phList::remove( phListNode *node )
00502 {
00503     phFUNCTION("phList::remove")
00504 
00505     if (node == NULL) return phFAIL;
00506     if (this->m_totalNodes <= 0) return phFAIL;
00507 
00508     DECLARE_LOCK_CHECKS();
00509     
00510     LOCK();
00511     LOCK_NODE();
00512     
00513     phListNode *prev = node->getPrevious();
00514     phListNode *next = node->getNext();
00515 
00516     LOCK_NEXT();
00517     LOCK_PREV();
00518 
00519     /* if there is no previous and next node, this is the only node */
00520     if ((prev == NULL) && (next == NULL) &&
00521         (this->m_head == node) && (this->m_tail == node))
00522     {
00523         /* Adjust the list's first node to this node's next node */
00524         this->m_head = this->m_tail = NULL;
00525     }
00526     /* "Dequeue"/"Pop" */
00527     /* if there is no next pointer, this is the last node... */
00528     else if ((next == NULL) && (this->m_tail == node))
00529     {
00530         /*... there must be a previous node, otherwise the first if block  *
00531          * would have executed. So, Adjust the previous node               */
00532         prev->setNext(NULL);
00533 
00534         /* Adjust the list's last node to the removed node's previous */
00535         this->m_tail = prev;
00536     }
00537     /* "Shift" */
00538     /* If there is no previous pointer, this is the first node ... */
00539     else if ((prev == NULL) && (this->m_head == node))
00540     {
00541         /*... there must be a next node, otherwise the first "if block" *
00542          * would have executed. So, Adjust the first node:              */
00543         next->setPrevious( NULL );
00544 
00545         /* Adjust the list's first node to this node's next */
00546         this->m_head = next;
00547     }
00548     /* The node is in the middle somewhere, neither first nor last */
00549     else
00550     {
00551         /* Adjust the previous's next, then the next's previous */
00552         prev->setNext( next );
00553         next->setPrevious( prev );
00554     }
00555         
00556     /* Adjust the total count of nodes in the list */
00557     this->m_totalNodes--;    
00558 
00559     /* adjust the removed node's pointers */
00560     node->setNext( NULL );
00561     node->setPrevious( NULL );
00562 
00563     UNLOCK_PREV();
00564     UNLOCK_NEXT();
00565     
00566     UNLOCK_NODE();
00567     UNLOCK();
00568 
00569     return phSUCCESS;
00570 }
00571 
00572 /* ---------------------------------------------------------------------- */
00573 /* empty: Delete all the nodes in the list */
00574 /* ---------------------------------------------------------------------- */
00575 int phList::empty()
00576 {
00577     phFUNCTION("phList::empty")
00578     int locked = 0;
00579 
00580     phListNode *node = NULL;
00581     phListNode *next = NULL;
00582 
00583     phTHIS_LOOSE_LOCK(locked);
00584 
00585     node = this->m_head;
00586 
00587     while (node != NULL)
00588     {
00589         next = node->getNext();
00590 
00591         phDelete(node);
00592 
00593         node = next;
00594     }
00595 
00596     this->m_head = this->m_tail = NULL;
00597     this->m_totalNodes = 0;
00598     
00599     phTHIS_LOOSE_UNLOCK(locked);
00600     
00601     return phSUCCESS;
00602 }
00603 
00604 /* ---------------------------------------------------------------------- */
00605 /* push: insert at the end of the list */
00606 /* ---------------------------------------------------------------------- */
00607 int phList::push( phListNode *node )
00608 {
00609     phFUNCTION("phList::push")
00610     int locked = 0;
00611 
00612     if (node == NULL) return phFAIL;
00613 
00614     phTHIS_LOCK(locked);
00615 
00616     rc = this->insert( node, this->m_totalNodes );
00617     phCHECK_RC(rc,NULL,"this->insert");
00618     
00619     phTHIS_UNLOCK(locked);
00620 
00621     return phSUCCESS;
00622 error:
00623     phTHIS_ERROR_UNLOCK(locked);
00624 
00625     return phFAIL;
00626 }
00627 
00628 /* ---------------------------------------------------------------------- */
00629 /* pop: remove from the end of the list */
00630 /* ---------------------------------------------------------------------- */
00631 phListNode *phList::pop( ) /* a.k.a. dequeue */
00632 {
00633     phFUNCTION("phList::pop")
00634     int locked = 0;
00635 
00636     phListNode  *node   = NULL;
00637 
00638     phTHIS_LOCK(locked);
00639 
00640     node = this->m_tail;
00641 
00642     rc = this->remove( node );
00643     phCHECK_RC(rc,NULL,"this->remove(this->m_head)");
00644 
00645     phTHIS_UNLOCK(locked);
00646 
00647     return node;
00648 error:
00649     phTHIS_ERROR_UNLOCK(locked);
00650 
00651     return NULL;
00652 }
00653 
00654 /* ---------------------------------------------------------------------- */
00655 /* enqueue: insert on the front of the list */
00656 /* ---------------------------------------------------------------------- */
00657 int phList::enqueue( phListNode *node ) /* a.k.a. unshift */
00658 {
00659     phFUNCTION("phList::enqueue")
00660     int locked = 0;
00661 
00662     phTHIS_LOCK(locked);
00663 
00664     rc = this->insert( node, 0 );
00665     phCHECK_RC(rc,NULL,"this->insert( node, 0 )");
00666 
00667     phTHIS_UNLOCK(locked);
00668 
00669     return phSUCCESS;
00670 error:
00671     phTHIS_ERROR_UNLOCK(locked);
00672 
00673     return phFAIL;
00674 }
00675 
00676 /* ---------------------------------------------------------------------- */
00677 /* dequeue: remove from the end of the list */
00678 /* ---------------------------------------------------------------------- */
00679 phListNode *phList::dequeue( ) /* a.k.a. pop */
00680 {
00681     phFUNCTION("phList::dequeue")
00682     int locked = 0;
00683 
00684     phListNode  *node   = NULL;
00685 
00686     phTHIS_LOCK(locked);
00687     
00688     node = this->m_tail;
00689     
00690     rc = this->remove( node );
00691     phCHECK_RC(rc,NULL,"this->remove( this->m_tail )");
00692 
00693     phTHIS_UNLOCK(locked);
00694 
00695     return node;
00696 error:
00697     phTHIS_ERROR_UNLOCK(locked);
00698 
00699     return NULL;
00700 }
00701 
00702 /* ---------------------------------------------------------------------- */
00703 /* shift: remove from the front of the list */
00704 /* ---------------------------------------------------------------------- */
00705 phListNode *phList::shift( )
00706 {
00707     phFUNCTION("phList::shift")
00708     int locked = 0;
00709     
00710     phListNode  *node   = NULL;
00711 
00712     phTHIS_LOCK(locked);
00713 
00714     node = this->m_head;
00715 
00716     rc = this->remove( node );
00717     phCHECK_RC(rc,NULL,"this->remove(this->m_head)")
00718 
00719     phTHIS_UNLOCK(locked);
00720 
00721     return node;
00722 error:
00723     phTHIS_ERROR_UNLOCK(locked);
00724 
00725     return NULL;
00726 }
00727 
00728 /* ---------------------------------------------------------------------- */
00729 /* unshift: insert on the front of the list */
00730 /* ---------------------------------------------------------------------- */
00731 int phList::unshift( phListNode *node ) /* a.k.a. enqueue */
00732 {
00733     phFUNCTION("phList::unshift")
00734     int locked = 0;
00735 
00736     phTHIS_LOCK(locked);
00737 
00738     rc = this->insert( node, 0 );
00739     phCHECK_RC(rc,NULL,"this->insert( node, 0 )");
00740 
00741     phTHIS_UNLOCK(locked);
00742 
00743     return phSUCCESS;
00744 error:
00745     phTHIS_ERROR_UNLOCK(locked);
00746 
00747     return phFAIL;
00748 }
00749 
00750 /* ---------------------------------------------------------------------- */
00751 phListNode *phList::removeTail() /* a.k.a. dequeue */
00752 {
00753     phFUNCTION("phList::removeTail")
00754     int locked = 0;
00755 
00756     phListNode  *node   = NULL;
00757 
00758     phTHIS_LOCK(locked);
00759     
00760     node = this->m_tail;
00761     
00762     rc = this->remove( node );
00763     phCHECK_RC(rc,NULL,"this->remove( this->m_tail )");
00764 
00765     phTHIS_UNLOCK(locked);
00766 
00767     return node;
00768 error:
00769     phTHIS_ERROR_UNLOCK(locked);
00770 
00771     return NULL;
00772 }
00773 
00774 /* ---------------------------------------------------------------------- */
00775 phListNode *phList::removeHead() /* a.k.a. shift */
00776 {
00777     phFUNCTION("phList::removeHead")
00778     int locked = 0;
00779     
00780     phListNode  *node   = NULL;
00781 
00782     phTHIS_LOCK(locked);
00783 
00784     node = this->m_head;
00785 
00786     rc = this->remove( node );
00787     phCHECK_RC(rc,NULL,"this->remove(this->m_head)")
00788 
00789     phTHIS_UNLOCK(locked);
00790 
00791     return node;
00792 error:
00793     phTHIS_ERROR_UNLOCK(locked);
00794 
00795     return NULL;
00796 }
00797 
00798 /* ---------------------------------------------------------------------- */
00799 const phListNode *phList::getHead()
00800 {
00801     phFUNCTION("phList::removeHead")
00802     int locked = 0;
00803     
00804     phListNode  *node   = NULL;
00805 
00806     phTHIS_LOCK(locked);
00807 
00808     node = this->m_head;
00809 
00810     phTHIS_UNLOCK(locked);
00811 
00812     return node;
00813 error:
00814     phTHIS_ERROR_UNLOCK(locked);
00815 
00816     return NULL;
00817 }
00818 
00819 /* ---------------------------------------------------------------------- */
00820 const phListNode *phList::getTail()
00821 {
00822     phFUNCTION("phList::removeHead")
00823     int locked = 0;
00824     
00825     phListNode  *node   = NULL;
00826 
00827     phTHIS_LOCK(locked);
00828 
00829     node = this->m_tail;
00830 
00831     phTHIS_UNLOCK(locked);
00832 
00833     return node;
00834 error:
00835     phTHIS_ERROR_UNLOCK(locked);
00836 
00837     return NULL;
00838 }
00839 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:02 2007 for phission by  doxygen 1.4.4