00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef _OASYS_LOCK_H_
00040 #define _OASYS_LOCK_H_
00041
00042 #include <memory>
00043
00044 #include "Atomic.h"
00045 #include "Thread.h"
00046
00047 #include "../debug/Logger.h"
00048 #include "../util/Pointers.h"
00049
00050 namespace oasys {
00051
00055 class Lock : public Logger {
00056 public:
00060 Lock() : Logger("Lock", "/lock"),
00061 lock_count_(0),
00062 lock_holder_(0),
00063 lock_holder_name_(0),
00064 scope_lock_count_(0)
00065 {}
00066
00071 virtual ~Lock()
00072 {
00073 if (is_locked()) {
00074 ASSERT(is_locked_by_me());
00075 ASSERT(scope_lock_count_ == 0);
00076 }
00077 }
00078
00084 virtual int lock(const char* lock_user) = 0;
00085
00091 virtual int unlock() = 0;
00092
00098 virtual int try_lock(const char* lock_user) = 0;
00099
00105 bool is_locked()
00106 {
00107 return (lock_count_.value != 0);
00108 }
00109
00116 bool is_locked_by_me()
00117 {
00118 return is_locked() &&
00119 pthread_equal(lock_holder_, Thread::current());
00120 }
00121
00122 protected:
00123 friend class ScopeLock;
00124 friend class ScopeLockIf;
00125
00131 atomic_t lock_count_;
00132
00143 volatile pthread_t lock_holder_;
00144
00149 const char* lock_holder_name_;
00150
00157 int scope_lock_count_;
00158 };
00159
00173 class ScopeLock {
00174 public:
00175 ScopeLock(Lock* l,
00176 const char* lock_user)
00177 : lock_(l)
00178 {
00179 do_lock(lock_user);
00180 }
00181
00182 ScopeLock(const Lock* l,
00183 const char* lock_user)
00184 : lock_(const_cast<Lock*>(l))
00185 {
00186 do_lock(lock_user);
00187 }
00188
00189 ScopeLock(oasys::ScopePtr<Lock> l,
00190 const char* lock_user)
00191 : lock_(l.ptr())
00192 {
00193 do_lock(lock_user);
00194 }
00195
00196 ScopeLock(std::auto_ptr<Lock> l,
00197 const char* lock_user)
00198 : lock_(l.get())
00199 {
00200 do_lock(lock_user);
00201 }
00202
00203 void do_lock(const char* lock_user) {
00204 int ret = lock_->lock(lock_user);
00205 ASSERT(ret == 0);
00206 lock_->scope_lock_count_++;
00207 }
00208
00209 void unlock() {
00210 lock_->scope_lock_count_--;
00211 lock_->unlock();
00212 lock_ = 0;
00213 }
00214
00215 ~ScopeLock()
00216 {
00217 if (lock_) {
00218 unlock();
00219 }
00220 }
00221
00222 protected:
00223 Lock* lock_;
00224 };
00225
00231 class ScopeLockIf {
00232 public:
00233 ScopeLockIf(Lock* l,
00234 const char* lock_user,
00235 bool use_lock)
00236 : lock_(l), use_lock_(use_lock)
00237 {
00238 do_lock(lock_user);
00239 }
00240
00241 ScopeLockIf(const Lock* l,
00242 const char* lock_user,
00243 bool use_lock)
00244 : lock_(const_cast<Lock*>(l)), use_lock_(use_lock)
00245 {
00246 do_lock(lock_user);
00247 }
00248
00249 ScopeLockIf(oasys::ScopePtr<Lock> l,
00250 const char* lock_user,
00251 bool use_lock)
00252 : lock_(l.ptr()), use_lock_(use_lock)
00253 {
00254 do_lock(lock_user);
00255 }
00256
00257 ScopeLockIf(std::auto_ptr<Lock> l,
00258 const char* lock_user,
00259 bool use_lock)
00260 : lock_(l.get()), use_lock_(use_lock)
00261 {
00262 do_lock(lock_user);
00263 }
00264
00265 void do_lock(const char* lock_user) {
00266 if (use_lock_)
00267 {
00268 int ret = lock_->lock(lock_user);
00269 ASSERT(ret == 0);
00270 lock_->scope_lock_count_++;
00271 }
00272 }
00273
00274 void unlock() {
00275 if (use_lock_)
00276 {
00277 lock_->scope_lock_count_--;
00278 lock_->unlock();
00279 lock_ = 0;
00280 }
00281 }
00282
00283 ~ScopeLockIf()
00284 {
00285 if (use_lock_ && lock_) {
00286 unlock();
00287 }
00288 }
00289
00290 protected:
00291 Lock* lock_;
00292 bool use_lock_;
00293 };
00294
00295 }
00296
00297 #endif