Fawkes API Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * read_write_lock.cpp - Read Write Lock 00004 * 00005 * Generated: Thu Sep 15 00:10:54 2006 00006 * Copyright 2006 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program 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 Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <core/threading/read_write_lock.h> 00025 00026 #include <pthread.h> 00027 #include <cstring> 00028 00029 namespace fawkes { 00030 00031 00032 /// @cond INTERNALS 00033 class ReadWriteLockData 00034 { 00035 public: 00036 pthread_rwlock_t rwlock; 00037 }; 00038 /// @endcond 00039 00040 00041 /** @class ReadWriteLock core/threading/read_write_lock.h 00042 * Read/write lock to allow multiple readers but only a single writer 00043 * on the resource at a time. 00044 * This can be used if you have a value that only a few writers modify but 00045 * several readers use. In this case the readers can read all at the same 00046 * time as long as there is no writer modifying the value. 00047 * 00048 * @ingroup Threading 00049 * @ingroup FCL 00050 * @see example_rwlock.cpp 00051 * 00052 * @author Tim Niemueller 00053 */ 00054 00055 00056 /** Constructor 00057 * @param policy The read/write lock policy to use. The default is to 00058 * prefer writers. 00059 */ 00060 ReadWriteLock::ReadWriteLock(ReadWriteLockPolicy policy) 00061 { 00062 rwlock_data = new ReadWriteLockData(); 00063 00064 #if defined __USE_UNIX98 || defined __USE_XOPEN2K 00065 pthread_rwlockattr_t attr; 00066 pthread_rwlockattr_init( &attr ); 00067 00068 switch (policy) { 00069 case RWLockPolicyPreferWriter: 00070 pthread_rwlockattr_setkind_np( &attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP ); 00071 break; 00072 case RWLockPolicyPreferReader: 00073 pthread_rwlockattr_setkind_np( &attr, PTHREAD_RWLOCK_PREFER_READER_NP ); 00074 break; 00075 } 00076 00077 pthread_rwlock_init( &(rwlock_data->rwlock), &attr ); 00078 #else 00079 pthread_rwlock_init( &(rwlock_data->rwlock), NULL ); 00080 #endif 00081 } 00082 00083 00084 /** Destructor */ 00085 ReadWriteLock::~ReadWriteLock() 00086 { 00087 pthread_rwlock_destroy( &(rwlock_data->rwlock) ); 00088 delete rwlock_data; 00089 } 00090 00091 00092 /** Aquire a reader lock. 00093 * This will aquire the lock for reading. Multiple readers can aquire the 00094 * lock at the same time. But never when a writer has the lock. 00095 * This method will block until the lock has been aquired. 00096 */ 00097 void 00098 ReadWriteLock::lock_for_read() 00099 { 00100 pthread_rwlock_rdlock( &(rwlock_data->rwlock) ); 00101 } 00102 00103 00104 /** Aquire a writer lock. 00105 * This will aquire the lock for writing. Only a single writer at a time 00106 * will be allowed to aquire the lock. 00107 * This method will block until the lock has been aquired. 00108 */ 00109 void 00110 ReadWriteLock::lock_for_write() 00111 { 00112 pthread_rwlock_wrlock( &(rwlock_data->rwlock) ); 00113 } 00114 00115 00116 /** Tries to aquire a reader lock. 00117 * This will try to aquire the lock for reading. This will succeed if 00118 * no writer has aquired the lock already. Multiple readers may aquire the 00119 * lock. 00120 * @return true, if the lock could be aquired, false otherwise. 00121 */ 00122 bool 00123 ReadWriteLock::try_lock_for_read() 00124 { 00125 return ( pthread_rwlock_tryrdlock( &(rwlock_data->rwlock) ) == 0 ); 00126 } 00127 00128 00129 /** Tries to aquire a writer lock. 00130 * This will try to aquire the lock for writing. This will succeed if the 00131 * read/write lock is currently unlocked. No other threads may hold this lock 00132 * at the same time. Neither for writing nor for reading. 00133 * @return true, if the lock has been aquired, false otherwise. 00134 */ 00135 bool 00136 ReadWriteLock::try_lock_for_write() 00137 { 00138 return ( pthread_rwlock_trywrlock( &(rwlock_data->rwlock) ) == 0 ); 00139 } 00140 00141 00142 /** Release the lock. 00143 * Releases the lock, no matter whether it was locked for reading or writing. 00144 */ 00145 void 00146 ReadWriteLock::unlock() 00147 { 00148 pthread_rwlock_unlock( &(rwlock_data->rwlock) ); 00149 } 00150 00151 00152 } // end namespace fawkes