Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members | Related Pages

LOW_objectSynchronizer.h

Go to the documentation of this file.
00001 /***************************************************************************
00002                           LOW_objectSynchronizer.h  -  description
00003                              -------------------
00004     begin                : Sat Oct 4 2003
00005     copyright            : (C) 2003 by Harald Roelle
00006     email                : roelle@informatik.uni-muenchen.de
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU 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  ***************************************************************************/
00017 
00018 #ifndef LOW_OBJECTSYNCHRONIZER_H
00019 #define LOW_OBJECTSYNCHRONIZER_H
00020 
00021 
00022 #include "LOW_platformMisc.h"
00023 #include "LOW_platformMiscFactory.h"
00024 #include "LOW_helper_msglog.h"
00025 #include "LOW_thread_Factory.h"
00026 #include "LOW_thread_rwlock.h"
00027 
00028 
00029 
00030 #ifdef DEBUG_LOCKING
00031 #include <string>
00032 #endif
00033 
00034 
00035 #include "LOW_objectSynchronizerMacros.h"
00036 
00037 
00038 /** Mix-in class to synchronize access to methods on object basis.
00039 
00040     A class which needs synchronization to be thread-save can subclass
00041     this class. To serialize the access to a method, simply insert one
00042     of the following macros at the beginning of the method:
00043 
00044       - <b>__LOW_SYNCHRONIZE_METHOD_READ__</b>: Obtains a read lock.
00045       - <b>__LOW_SYNCHRONIZE_METHOD_WRITE__</b>: Obtains a write lock.
00046       - <b>__LOW_SYNCHRONIZE_METHOD_READ_WEAK__</b>: Obtains a weak read lock.
00047       - <b>__LOW_SYNCHRONIZE_METHOD_WRITE_WEAK__</b>: Obtains a weak write lock.
00048 
00049     Note that synchronization is done on object basis.
00050 
00051     The implemtation follows the "locking is creation" design pattern and
00052     uses a read-write lock. Therefore reentrant calls or successive locking
00053     in sub-called methods does no harm.
00054 
00055     For locking in static methods some preprocessor macros are provided:
00056       - <b>__LOW_SYNCHRONIZE_DEFINE_PROTECTED_LOCK__</b>: Insert in protected part to declare mutex.
00057       - <b>__LOW_SYNCHRONIZE_INIT_PROTECTED_LOCK__</b>: Insert in implementation file to initialize mutex.
00058       - <b>__LOW_SYNCHRONIZE_STATIC_READ__</b>: Obtains a read lock.
00059       - <b>__LOW_SYNCHRONIZE_STATIC_WRITE__</b>: Obtains a write lock.
00060       - <b>__LOW_SYNCHRONIZE_STATIC_READ_WEAK__</b>: Obtains a weak read lock.
00061       - <b>__LOW_SYNCHRONIZE_STATIC_WRITE_WEAK__</b>: Obtains a weak write lock.
00062 
00063     This class is thread-safe.
00064 
00065     @author Harald Roelle
00066  */
00067 class LOW_objectSynchronizer {
00068 
00069 //=======================================================================================
00070 public:
00071 
00072 
00073   //=====================================================================================
00074   //
00075   // operators
00076   //
00077 
00078 
00079   LOW_objectSynchronizer& operator= ( const LOW_objectSynchronizer &inRightSide);
00080 
00081 
00082   //=====================================================================================
00083   //
00084   // static locks
00085   //
00086 
00087   /** Read locking class to ensure exclusive access.
00088 
00089       The class is intended to be used in a "locking is creation" design pattern.
00090       On creation a read lock on a rwlock is optained, and on destruction
00091       the rwlock is released.
00092    */
00093   class __synchronizeStaticRead {
00094     public:
00095 
00096       /** Obtain the read lock.
00097           Inlined for performance reasons.
00098           @param inObjectSynchronizer  Reference to the object to synchronize on.
00099        */
00100 #ifdef DEBUG_LOCKING
00101       inline __synchronizeStaticRead( LOW_thread_rwlock **inRwlockSingleton, std::string inFile, int inLine) :
00102 #else
00103       inline __synchronizeStaticRead( LOW_thread_rwlock **inRwlockSingleton) :
00104 #endif
00105         staticRwLock( inRwlockSingleton)
00106       {
00107         if ( *staticRwLock == 0 )
00108           *staticRwLock = LOW_thread_Factory::new_rwlock();
00109 #ifdef DEBUG_LOCKING
00110         try {
00111           (*staticRwLock)->tryLockRead(); // try to obtain the lock, if it fail we get a logged message
00112           LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00113             "__synchronizeStaticRead: obtained lock from file %s, line %d\n", inFile.c_str(), inLine);
00114         }
00115         catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00116           LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00117             "__synchronizeStaticRead: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00118           (*staticRwLock)->lockRead();  // now really block in the lock
00119         }
00120 #else
00121         (*staticRwLock)->lockRead();
00122 #endif
00123       };
00124 
00125       /** Release the lock.
00126           Inlined for performance reasons.
00127        */
00128       inline ~__synchronizeStaticRead()
00129       {
00130         (*staticRwLock)->unlock();
00131       };
00132 
00133     private:
00134       LOW_thread_rwlock **staticRwLock; /**< Pointer to pointer to the static lock. */
00135   };
00136 
00137 
00138   /** Write locking class to ensure exclusive access.
00139 
00140       The class is intended to be used in a "locking is creation" design pattern.
00141       On creation a write lock on a rwlock is optained, and on destruction
00142       the rwlock is released.
00143    */
00144   class __synchronizeStaticWrite {
00145     public:
00146 
00147       /** Obtain the write lock.
00148           Inlined for performance reasons.
00149           @param inObjectSynchronizer  Reference to the object to synchronize on.
00150        */
00151 #ifdef DEBUG_LOCKING
00152       inline __synchronizeStaticWrite( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder, std::string inFile, int inLine) :
00153 #else
00154       inline __synchronizeStaticWrite( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder) :
00155 #endif
00156         staticRwLock( inRwlockSingleton),
00157         writeLockHolder(inWriteLockHolder)
00158       {
00159         if ( *staticRwLock == 0 )
00160           *staticRwLock = LOW_thread_Factory::new_rwlock();
00161 #ifdef DEBUG_LOCKING
00162         try {
00163           (*staticRwLock)->tryLockWrite(); // try to obtain the lock, if it fail we get a logged message
00164           LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00165             "__synchronizeStaticWrite: obtained lock from file %s, line %d\n", inFile.c_str(), inLine);
00166         }
00167         catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00168           LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00169             "__synchronizeStaticWrite: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00170           (*staticRwLock)->lockWrite();  // now really block in the lock
00171         }
00172 #else
00173         (*staticRwLock)->lockWrite();
00174 #endif
00175         // no need to make that block exclusive:
00176         //  - a foreign thread will block anyway waiting for a lock
00177         //  - our own thread cannot check as we are still here
00178         writeLockHolder = LOW_platformMisc::getThreadID();  // set write lock indicator
00179       };
00180 
00181       /** Release the lock.
00182           Inlined for performance reasons.
00183        */
00184       inline ~__synchronizeStaticWrite()
00185       {
00186         // no need to make that block exclusive:
00187         //  - a foreign thread will block anyway waiting for a lock
00188         //  - our own thread cannot check as we are still here
00189         writeLockHolder = 0;  // clear write lock indicator
00190         (*staticRwLock)->unlock();
00191       };
00192 
00193     private:
00194       LOW_thread_rwlock                       **staticRwLock; /**< Pointer to pointer to the static lock. */
00195       LOW_platformMiscFactory::threadIdent_t  &writeLockHolder;
00196   };
00197 
00198 
00199   /** Weak read locking class to ensure exclusive access.
00200 
00201       Works similar to __synchronizeMethodRead with one difference in the following situation:
00202       If the calling thread already has a <b>write</b> lock then <b>no blocking</b>
00203       will occur and <b>no lock</b> will be obtained.
00204    */
00205   class __synchronizeStaticReadWeak {
00206     public:
00207 
00208       /** Obtain the weak read lock.
00209           Inlined for performance reasons.
00210           @param inObjectSynchronizer  Reference to the object to synchronize on.
00211        */
00212 #ifdef DEBUG_LOCKING
00213       inline __synchronizeStaticReadWeak( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder, std::string inFile, int inLine) :
00214 #else
00215       inline __synchronizeStaticReadWeak( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder) :
00216 #endif
00217         staticRwLock( inRwlockSingleton)
00218       {
00219         if ( *staticRwLock == 0 )
00220           *staticRwLock = LOW_thread_Factory::new_rwlock();
00221         wasObtainedWeakly = false;
00222         try {
00223           (*staticRwLock)->tryLockRead();
00224           LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00225             "__synchronizeStaticReadWeak: obtained lock from file %s, line %d\n", inFile.c_str(), inLine);
00226         }
00227         catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00228           if ( LOW_platformMisc::getThreadID() == inWriteLockHolder )
00229             wasObtainedWeakly = true;  // if it was me who has the lock, "obtain" it weakly
00230           else {
00231 #ifdef DEBUG_LOCKING
00232             LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00233               "__synchronizeStaticReadWeak: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00234 #endif
00235             (*staticRwLock)->lockRead();  // if it wasn't me who obtained the lock, really block
00236           }
00237         }
00238       };
00239 
00240       /** Release the weak lock.
00241           Inlined for performance reasons.
00242        */
00243       inline ~__synchronizeStaticReadWeak()
00244       {
00245         if ( ! wasObtainedWeakly )
00246           (*staticRwLock)->unlock();
00247       };
00248 
00249     private:
00250       LOW_thread_rwlock  **staticRwLock;      /**< Pointer to pointer to the static lock. */
00251       bool               wasObtainedWeakly;   /**< Indicate if lock was really obtained */
00252   };
00253 
00254 
00255   /** Weak write locking class to ensure exclusive access.
00256 
00257       Works similar to __synchronizeMethodRead with one difference in the following situation:
00258       If the calling thread already has a <b>write</b> lock then <b>no blocking</b>
00259       will occur and <b>no lock</b> will be obtained.
00260    */
00261   class __synchronizeStaticWriteWeak {
00262     public:
00263 
00264       /** Obtain the weak write lock.
00265           Inlined for performance reasons.
00266           @param inObjectSynchronizer  Reference to the object to synchronize on.
00267        */
00268 #ifdef DEBUG_LOCKING
00269       inline __synchronizeStaticWriteWeak( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder, std::string inFile, int inLine) :
00270 #else
00271       inline __synchronizeStaticWriteWeak( LOW_thread_rwlock **inRwlockSingleton, LOW_platformMiscFactory::threadIdent_t &inWriteLockHolder) :
00272 #endif
00273         staticRwLock( inRwlockSingleton),
00274         writeLockHolder(inWriteLockHolder)
00275       {
00276         if ( *staticRwLock == 0 )
00277           *staticRwLock = LOW_thread_Factory::new_rwlock();
00278         wasObtainedWeakly = false;
00279         try {
00280           (*staticRwLock)->tryLockWrite();
00281           // no need to make that block exclusive:
00282           //  - a foreign thread will block anyway waiting for a lock
00283           //  - our own thread cannot check as we are still here
00284           writeLockHolder = LOW_platformMisc::getThreadID();  // set write lock indicator
00285           LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00286             "__synchronizeStaticWriteWeak: obtained lock from file %s, line %d\n", inFile.c_str(), inLine);
00287         }
00288         catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00289           if ( LOW_platformMisc::getThreadID() == writeLockHolder )
00290             wasObtainedWeakly = true;  // if it was me who has the lock, "obtain" it weakly
00291           else {
00292 #ifdef DEBUG_LOCKING
00293             LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00294               "__synchronizeStaticWriteWeak: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00295 #endif
00296             (*staticRwLock)->lockWrite();  // if it wasn't me who obtained the lock, really block
00297           }
00298         }
00299       };
00300 
00301       /** Release the weak write lock.
00302           Inlined for performance reasons.
00303        */
00304       inline ~__synchronizeStaticWriteWeak()
00305       {
00306         if ( ! wasObtainedWeakly ) {
00307           // no need to make that block exclusive:
00308           //  - a foreign thread will block anyway waiting for a lock
00309           //  - our own thread cannot check as we are still here
00310           writeLockHolder = 0;  // clear write lock indicator
00311           (*staticRwLock)->unlock();
00312         }
00313       };
00314 
00315     private:
00316       LOW_thread_rwlock                       **staticRwLock;      /**< Pointer to pointer to the static lock. */
00317       bool                                    wasObtainedWeakly;   /**< Indicate if lock was really obtained */
00318       LOW_platformMiscFactory::threadIdent_t  &writeLockHolder;
00319   };
00320 
00321 
00322 
00323 //=======================================================================================
00324 protected: 
00325 
00326   //=====================================================================================
00327   //
00328   // locks
00329   //
00330 
00331   /** Read locking class to ensure exclusive access.
00332 
00333       The class is intended to be used in a "locking is creation" design pattern.
00334       On creation a read lock on a rwlock is optained, and on destruction
00335       the rwlock is released.
00336    */
00337   class __synchronizeMethodRead {
00338     public:
00339 
00340       /** Obtain the read lock.
00341           Inlined for performance reasons.
00342           @param inObjectSynchronizer  Reference to the object to synchronize on.
00343        */
00344 #ifdef DEBUG_LOCKING
00345       inline __synchronizeMethodRead( const LOW_objectSynchronizer &inObjectSynchronizer, std::string inFile, int inLine) :
00346 #else
00347       inline __synchronizeMethodRead( const LOW_objectSynchronizer &inObjectSynchronizer) :
00348 #endif
00349         objectSynchronizer( inObjectSynchronizer)
00350       {
00351 #ifdef DEBUG_LOCKING
00352         try {
00353           objectSynchronizer.objectSyncRwlock->tryLockRead(); // try to obtain the lock, if it fail we get a logged message
00354           LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00355             "__synchronizeMethodRead: obtained read lock from file %s, line %d\n", inFile.c_str(), inLine);
00356         }
00357         catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00358           LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00359             "__synchronizeMethodRead: failed to obtain read lock from file %s, line %d\n", inFile.c_str(), inLine);
00360           objectSynchronizer.objectSyncRwlock->lockRead();  // now really block in the lock
00361         }
00362 #else
00363         objectSynchronizer.objectSyncRwlock->lockRead();
00364 #endif
00365       };
00366 
00367       /** Release the lock.
00368           Inlined for performance reasons.
00369        */
00370       inline ~__synchronizeMethodRead()
00371       {
00372         objectSynchronizer.objectSyncRwlock->unlock();
00373       };
00374 
00375     private:
00376       const LOW_objectSynchronizer &objectSynchronizer; /**< Reference to the object to lock on. */
00377   };
00378 
00379 
00380   /** Write locking class to ensure exclusive access.
00381 
00382       The class is intended to be used in a "locking is creation" design pattern.
00383       On creation a write lock on a rwlock is optained, and on destruction
00384       the rwlock is released.
00385    */
00386   class __synchronizeMethodWrite {
00387     public:
00388 
00389       /** Obtain the write lock.
00390           Inlined for performance reasons.
00391           @param inObjectSynchronizer  Reference to the object to synchronize on.
00392        */
00393 #ifdef DEBUG_LOCKING
00394       inline __synchronizeMethodWrite( LOW_objectSynchronizer &inObjectSynchronizer, std::string inFile, int inLine) :
00395 #else
00396       inline __synchronizeMethodWrite( LOW_objectSynchronizer &inObjectSynchronizer) :
00397 #endif
00398         objectSynchronizer( inObjectSynchronizer)
00399       {
00400 #ifdef DEBUG_LOCKING
00401         try {
00402           objectSynchronizer.objectSyncRwlock->tryLockWrite(); // try to obtain the lock, if it fail we get a logged message
00403           LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00404             "__synchronizeMethodWrite: obtained write lock from file %s, line %d\n", inFile.c_str(), inLine);
00405         }
00406         catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00407           LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00408             "__synchronizeMethodWrite: failed to obtain write lock from file %s, line %d\n", inFile.c_str(), inLine);
00409           objectSynchronizer.objectSyncRwlock->lockWrite();  // now really block in the lock
00410         }
00411 #else
00412         objectSynchronizer.objectSyncRwlock->lockWrite();
00413 #endif
00414         // no need to make that block exclusive:
00415         //  - a foreign thread will block anyway waiting for a lock
00416         //  - our own thread cannot check as we are still here
00417         objectSynchronizer.writeLockHolder = LOW_platformMisc::getThreadID();  // set write lock indicator
00418       };
00419 
00420       /** Release the lock.
00421           Inlined for performance reasons.
00422        */
00423       inline ~__synchronizeMethodWrite()
00424       {
00425         // no need to make that block exclusive:
00426         //  - a foreign thread will block anyway waiting for a lock
00427         //  - our own thread cannot check as we are still here
00428         objectSynchronizer.writeLockHolder = 0;  // clear write lock indicator
00429         objectSynchronizer.objectSyncRwlock->unlock();
00430       };
00431 
00432     private:
00433       LOW_objectSynchronizer &objectSynchronizer; /**< Reference to the object to lock on. */
00434   };
00435 
00436 
00437   /** Weak read locking class to ensure exclusive access.
00438 
00439       Works similar to __synchronizeMethodRead with one difference in the following situation:
00440       If the calling thread already has a <b>write</b> lock then <b>no blocking</b>
00441       will occur and <b>no lock</b> will be obtained.
00442    */
00443   class __synchronizeMethodReadWeak {
00444     public:
00445 
00446       /** Obtain the weak read lock.
00447           Inlined for performance reasons.
00448           @param inObjectSynchronizer  Reference to the object to synchronize on.
00449        */
00450 #ifdef DEBUG_LOCKING
00451       inline __synchronizeMethodReadWeak( const LOW_objectSynchronizer &inObjectSynchronizer, std::string inFile, int inLine) :
00452 #else
00453       inline __synchronizeMethodReadWeak( const LOW_objectSynchronizer &inObjectSynchronizer) :
00454 #endif
00455         objectSynchronizer( inObjectSynchronizer)
00456       {
00457         wasObtainedWeakly = false;
00458         try {
00459           objectSynchronizer.objectSyncRwlock->tryLockRead();
00460             LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00461               "__synchronizeMethodReadWeak: obtain weak read lock from file %s, line %d\n", inFile.c_str(), inLine);
00462         }
00463         catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00464           if ( LOW_platformMisc::getThreadID() == objectSynchronizer.writeLockHolder )
00465             wasObtainedWeakly = true;  // if it was me who has the lock, "obtain" it weakly
00466           else {
00467 #ifdef DEBUG_LOCKING
00468             LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00469               "__synchronizeMethodReadWeak: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00470 #endif
00471             objectSynchronizer.objectSyncRwlock->lockRead();  // if it wasn't me who obtained the lock, really block
00472           }
00473         }
00474       };
00475 
00476       /** Release the weak lock.
00477           Inlined for performance reasons.
00478        */
00479       inline ~__synchronizeMethodReadWeak()
00480       {
00481         if ( ! wasObtainedWeakly )
00482           objectSynchronizer.objectSyncRwlock->unlock();
00483       };
00484 
00485     private:
00486       const LOW_objectSynchronizer  &objectSynchronizer; /**< Reference to the object to lock on. */
00487       bool                          wasObtainedWeakly;   /**< Indicate if lock was really obtained */
00488   };
00489 
00490 
00491   /** Weak write locking class to ensure exclusive access.
00492 
00493       Works similar to __synchronizeMethodRead with one difference in the following situation:
00494       If the calling thread already has a <b>write</b> lock then <b>no blocking</b>
00495       will occur and <b>no lock</b> will be obtained.
00496    */
00497   class __synchronizeMethodWriteWeak {
00498     public:
00499 
00500       /** Obtain the weak write lock.
00501           Inlined for performance reasons.
00502           @param inObjectSynchronizer  Reference to the object to synchronize on.
00503        */
00504 #ifdef DEBUG_LOCKING
00505       inline __synchronizeMethodWriteWeak( LOW_objectSynchronizer &inObjectSynchronizer, std::string inFile, int inLine) :
00506 #else
00507       inline __synchronizeMethodWriteWeak( LOW_objectSynchronizer &inObjectSynchronizer) :
00508 #endif
00509         objectSynchronizer( inObjectSynchronizer)
00510       {
00511         wasObtainedWeakly = false;
00512         try {
00513           objectSynchronizer.objectSyncRwlock->tryLockWrite();
00514           LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_getLock_dl,
00515             "__synchronizeMethodWriteWeak: obtained weak write lock from file %s, line %d\n", inFile.c_str(), inLine);
00516           // no need to make that block exclusive:
00517           //  - a foreign thread will block anyway waiting for a lock
00518           //  - our own thread cannot check as we are still here
00519           objectSynchronizer.writeLockHolder = LOW_platformMisc::getThreadID();  // set write lock indicator
00520         }
00521         catch ( LOW_thread_rwlock::thread_rwlock_error ex) {
00522           if ( LOW_platformMisc::getThreadID() == objectSynchronizer.writeLockHolder )
00523             wasObtainedWeakly = true;  // if it was me who has the lock, "obtain" it weakly
00524           else {
00525 #ifdef DEBUG_LOCKING
00526             LOW_helper_msglog::printDebug( LOW_helper_msglog::objSync_lockFailed_dl,
00527               "__synchronizeMethodWriteWeak: failed to obtain lock from file %s, line %d\n", inFile.c_str(), inLine);
00528 #endif
00529             objectSynchronizer.objectSyncRwlock->lockWrite();  // if it wasn't me who obtained the lock, really block
00530           }
00531         }
00532       };
00533 
00534       /** Release the weak write lock.
00535           Inlined for performance reasons.
00536        */
00537       inline ~__synchronizeMethodWriteWeak()
00538       {
00539         if ( ! wasObtainedWeakly ) {
00540           // no need to make that block exclusive:
00541           //  - a foreign thread will block anyway waiting for a lock
00542           //  - our own thread cannot check as we are still here
00543           objectSynchronizer.writeLockHolder = 0;  // clear write lock indicator
00544           objectSynchronizer.objectSyncRwlock->unlock();
00545         }
00546       };
00547 
00548     private:
00549       LOW_objectSynchronizer  &objectSynchronizer;      /**< Reference to the object to lock on. */
00550       bool                          wasObtainedWeakly;  /**< Indicate if lock was really obtained */
00551   };
00552 
00553 
00554   //=====================================================================================
00555   //
00556   // constructors
00557   //
00558 
00559   
00560   /** Constructor.
00561    */
00562   LOW_objectSynchronizer();
00563 
00564 
00565   /** Copy constructor.
00566    */
00567   LOW_objectSynchronizer( const LOW_objectSynchronizer &inObjectSynchronizer);
00568 
00569 
00570   /** Destructor.
00571    */
00572   virtual ~LOW_objectSynchronizer();
00573   
00574   
00575 //=======================================================================================
00576 private:
00577 
00578   //=====================================================================================
00579   //
00580   // friends
00581   //
00582 
00583   friend class __synchronizeMethodRead;
00584   friend class __synchronizeMethodWrite;
00585   friend class __synchronizeMethodReadWeak;
00586   friend class __synchronizeMethodWriteWeak;
00587 
00588   
00589   //=====================================================================================
00590   //
00591   // attributes
00592   //
00593 
00594   LOW_thread_rwlock                       *objectSyncRwlock; /**< Rwlock used for locking. */
00595   LOW_platformMiscFactory::threadIdent_t  writeLockHolder;   /**< Thread id of the one who's holding a write lock */
00596 };
00597 
00598 #endif

Generated on Tue Feb 3 11:30:26 2004 for OneWireLibrary++ by doxygen 1.3.2