Page Speed Optimization Libraries  1.13.35.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
named_lock_tester.h
Go to the documentation of this file.
1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http:///www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 #ifndef PAGESPEED_KERNEL_BASE_NAMED_LOCK_TESTER_H_
20 #define PAGESPEED_KERNEL_BASE_NAMED_LOCK_TESTER_H_
21 
22 #include "base/logging.h"
29 
30 namespace net_instaweb {
31 
38  public:
39  explicit NamedLockTester(ThreadSystem* thread_system)
40  : acquired_(false),
41  failed_(false),
42  mutex_(thread_system->NewMutex()) {
43  }
44 
45  bool TryLock(NamedLock* lock) {
46  Clear();
47  lock->LockTimedWait(0, MakeFunction(
48  this,
49  &NamedLockTester::LockAcquired,
50  &NamedLockTester::LockFailed));
51  Quiesce();
52  CHECK(WasCalled()) << "LockTimedWait returned lock operation completed";
53  return Acquired();
54  }
55  bool LockTimedWaitStealOld(int64 wait_ms, int64 steal_ms, NamedLock* lock) {
56  Clear();
57  lock->LockTimedWaitStealOld(wait_ms, steal_ms, MakeFunction(
58  this,
59  &NamedLockTester::LockAcquired,
60  &NamedLockTester::LockFailed));
61  Quiesce();
62  CHECK(WasCalled())
63  << "LockTimedWaitStealOld returned lock operation completed";
64  return Acquired();
65  }
66  bool LockTimedWait(int64 wait_ms, NamedLock* lock) {
67  Clear();
68  lock->LockTimedWait(wait_ms, MakeFunction(
69  this,
70  &NamedLockTester::LockAcquired,
71  &NamedLockTester::LockFailed));
72  Quiesce();
73  CHECK(WasCalled()) << "LockTimedWait returned lock operation completed";
74  return Acquired();
75  }
76 
80  bool UnlockWithDelete(NamedLock* old_lock, NamedLock* new_lock) {
81  scoped_ptr<NamedLock> new_lock_deleter(new_lock);
82  lock_for_deletion_.reset(old_lock);
83  CHECK(old_lock->Held()) << "UnlockWithDelete old_lock must be held";
84  CHECK(!new_lock->Held()) << "UnlockWithDelete new_lock must not be held";
85  Clear();
86  new_lock->LockTimedWait(
87  60000 ,
89  this,
90  &NamedLockTester::DeleteLock,
91  &NamedLockTester::LockFailed));
92  old_lock->Unlock();
93  Quiesce();
94  CHECK(WasCalled()) << "UnlockWithDelete lock operation did not complete";
95  return Acquired();
96  }
97 
99  bool StealWithDelete(int64 steal_ms, NamedLock* old_lock,
100  NamedLock* new_lock) {
101  scoped_ptr<NamedLock> new_lock_deleter(new_lock);
102  lock_for_deletion_.reset(old_lock);
103  CHECK(old_lock->Held()) << "StealWithDelete old_lock must be held";
104  CHECK(!new_lock->Held()) << "StealWithDelete new_lock must not be held";
105  Clear();
106  new_lock->LockTimedWaitStealOld(
107  0 , steal_ms,
108  MakeFunction(
109  this,
110  &NamedLockTester::DeleteLock,
111  &NamedLockTester::LockFailed));
112  Quiesce();
113  CHECK(WasCalled()) << "StealWithDelete lock operation did not complete";
114  return Acquired();
115  }
116 
117  void DeleteLock() {
118  ScopedMutex lock(mutex_.get());
119  acquired_ = true;
120  lock_for_deletion_.reset();
121  }
122 
123  void Quiesce() {
124  if (quiesce_.get() != NULL) {
125  quiesce_->CallRun();
126  quiesce_->Reset();
127  }
128  }
129 
133  void set_quiesce(Function* quiesce) {
134  quiesce->set_delete_after_callback(false);
135  quiesce_.reset(quiesce);
136  }
137 
138  private:
139  void Clear() {
140  ScopedMutex lock(mutex_.get());
141  acquired_ = false;
142  failed_ = false;
143  }
144 
145  void LockAcquired() {
146  ScopedMutex lock(mutex_.get());
147  acquired_ = true;
148  }
149  void LockFailed() {
150  ScopedMutex lock(mutex_.get());
151  failed_ = true;
152  }
153  bool WasCalled() {
154  ScopedMutex lock(mutex_.get());
155  return acquired_ || failed_;
156  }
157  bool Acquired() {
158  ScopedMutex lock(mutex_.get());
159  return acquired_;
160  }
161 
162  bool acquired_;
163  bool failed_;
164  scoped_ptr<AbstractMutex> mutex_;
165  scoped_ptr<Function> quiesce_;
166  scoped_ptr<NamedLock> lock_for_deletion_;
167 
168 
169 };
170 
171 }
172 
173 #endif
Function * MakeFunction(C *object, void(C::*run)())
Makes a Function* that calls a 0-arg class method.
Definition: function.h:291
Definition: named_lock_tester.h:37
virtual void LockTimedWaitStealOld(int64 wait_ms, int64 steal_ms, Function *callback)=0
Non-blocking locking class.
Definition: named_lock_manager.h:31
bool StealWithDelete(int64 steal_ms, NamedLock *old_lock, NamedLock *new_lock)
As for UnlockWithDelete, but for a steal. Frees both locks.
Definition: named_lock_tester.h:99
virtual bool Held()=0
void set_quiesce(Function *quiesce)
Definition: named_lock_tester.h:133
Definition: scoped_ptr.h:30
Definition: function.h:47
#define ScopedMutex(x)
Definition: abstract_mutex.h:69
Helper class for lexically scoped mutexing.
Definition: abstract_mutex.h:46
bool UnlockWithDelete(NamedLock *old_lock, NamedLock *new_lock)
Definition: named_lock_tester.h:80
void set_delete_after_callback(bool x)
Definition: function.h:80
Definition: thread_system.h:40
virtual void LockTimedWait(int64 wait_ms, Function *callback)=0
virtual void Unlock()=0
virtual CondvarCapableMutex * NewMutex()=0