Lock.h

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 
00018 #ifndef _OASYS_LOCK_H_
00019 #define _OASYS_LOCK_H_
00020 
00021 #include "Atomic.h"
00022 #include "Thread.h"
00023 
00024 #include "../debug/Logger.h"
00025 #include "../util/Pointers.h"
00026 
00027 namespace oasys {
00028 
00032 class Lock : public Logger {
00033 public:
00037     Lock() : Logger("Lock", "/lock"),
00038              lock_count_(0),
00039              lock_holder_(0),
00040              lock_holder_name_(0), 
00041              scope_lock_count_(0) 
00042     {}
00043 
00048     virtual ~Lock()
00049     {
00050         if (is_locked()) {
00051             ASSERT(is_locked_by_me());
00052             ASSERT(scope_lock_count_ == 0);
00053         }
00054     }
00055     
00061     virtual int lock(const char* lock_user) = 0;
00062 
00068     virtual int unlock() = 0;
00069 
00075     virtual int try_lock(const char* lock_user) = 0;
00076 
00082     bool is_locked()
00083     {
00084         return (lock_count_.value != 0);
00085     }
00086 
00093     bool is_locked_by_me()
00094     {
00095         return is_locked() &&
00096             pthread_equal(lock_holder_, Thread::current());
00097     }
00098 
00099 protected:
00100     friend class ScopeLock;
00101     friend class ScopeLockIf;
00102 
00108     atomic_t lock_count_;
00109     
00120     volatile pthread_t lock_holder_;
00121 
00126     const char* lock_holder_name_;
00127 
00134     int scope_lock_count_;
00135 };
00136 
00150 class ScopeLock {
00151 public:
00152     ScopeLock()
00153         : lock_(NULL)
00154     {
00155     }
00156     
00157     ScopeLock(Lock*       l,
00158               const char* lock_user)
00159         : lock_(l)
00160     {
00161         do_lock(lock_user);
00162     }
00163 
00164     ScopeLock(const Lock* l,
00165               const char* lock_user)
00166         : lock_(const_cast<Lock*>(l))
00167     {
00168         do_lock(lock_user);
00169     }
00170 
00171     ScopeLock(oasys::ScopePtr<Lock> l,
00172               const char*           lock_user)
00173         : lock_(l.ptr())
00174     {
00175         do_lock(lock_user);
00176     }
00177 
00178     void set_lock(Lock* l, const char* lock_user)
00179     {
00180         lock_ = l;
00181         do_lock(lock_user);
00182     }
00183 
00184     void do_lock(const char* lock_user) {
00185         ASSERT(lock_ != NULL);
00186         int ret = lock_->lock(lock_user);
00187         ASSERT(ret == 0);
00188         lock_->scope_lock_count_++;
00189     }
00190 
00191     void unlock() {
00192         if (lock_ != NULL) {
00193             lock_->scope_lock_count_--;
00194             lock_->unlock();
00195             lock_ = NULL;
00196         }
00197     }
00198 
00199     ~ScopeLock()
00200     {
00201         if (lock_) {
00202             unlock();
00203         }
00204     }
00205     
00206 protected:
00207     Lock* lock_;
00208 };
00209 
00215 class ScopeLockIf {
00216 public:
00217     ScopeLockIf(Lock*       l,
00218                 const char* lock_user,
00219                 bool        use_lock)
00220         : lock_(l), use_lock_(use_lock)
00221     {
00222         do_lock(lock_user);
00223     }
00224 
00225     ScopeLockIf(const Lock* l,
00226                 const char* lock_user,
00227                 bool        use_lock)
00228         : lock_(const_cast<Lock*>(l)), use_lock_(use_lock)
00229     {
00230         do_lock(lock_user);
00231     }
00232 
00233     ScopeLockIf(oasys::ScopePtr<Lock> l,
00234                 const char*           lock_user,
00235                 bool                  use_lock)
00236         : lock_(l.ptr()), use_lock_(use_lock)
00237     {
00238         do_lock(lock_user);
00239     }
00240     
00241     void do_lock(const char* lock_user) {
00242         if (use_lock_) 
00243         {
00244             int ret = lock_->lock(lock_user);       
00245             ASSERT(ret == 0);                       
00246             lock_->scope_lock_count_++;
00247         }
00248     }
00249     
00250     void unlock() {
00251         if (use_lock_) 
00252         {
00253             lock_->scope_lock_count_--;
00254             lock_->unlock();
00255             lock_ = 0;
00256         }
00257     }
00258     
00259     ~ScopeLockIf()
00260     {
00261         if (use_lock_ && lock_) {
00262             unlock();
00263         }
00264     }
00265     
00266 protected:
00267     Lock* lock_;
00268     bool  use_lock_;
00269 };
00270 
00271 } // namespace oasys
00272 
00273 #endif /* LOCK_h */

Generated on Thu Jun 7 12:54:28 2007 for DTN Reference Implementation by  doxygen 1.5.1