1
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
5
#ifndef BASE_SYNCHRONIZATION_LOCK_H_
6
#define BASE_SYNCHRONIZATION_LOCK_H_
8
#include "base/base_export.h"
9
#include "base/synchronization/lock_impl.h"
10
#include "base/threading/platform_thread.h"
14
// A convenient wrapper for an OS specific critical section. The only real
15
// intelligence in this class is in debug mode for the support for the
16
// AssertAcquired() method.
17
class BASE_EXPORT Lock {
19
#if defined(NDEBUG) // Optimized wrapper implementation
22
void Acquire() { lock_.Lock(); }
23
void Release() { lock_.Unlock(); }
25
// If the lock is not held, take it and return true. If the lock is already
26
// held by another thread, immediately return false. This must not be called
27
// by a thread already holding the lock (what happens is undefined and an
28
// assertion may fail).
29
bool Try() { return lock_.Try(); }
31
// Null implementation if not debug.
32
void AssertAcquired() const {}
37
// NOTE: Although windows critical sections support recursive locks, we do not
38
// allow this, and we will commonly fire a DCHECK() if a thread attempts to
39
// acquire the lock a second time (while already holding it).
50
bool rv = lock_.Try();
57
void AssertAcquired() const;
61
// The posix implementation of ConditionVariable needs to be able
62
// to see our lock and tweak our debugging counters, as it releases
63
// and acquires locks inside of pthread_cond_{timed,}wait.
64
friend class ConditionVariable;
66
// The Windows Vista implementation of ConditionVariable needs the
67
// native handle of the critical section.
68
friend class WinVistaCondVar;
73
// Members and routines taking care of locks assertions.
74
// Note that this checks for recursive locks and allows them
75
// if the variable is set. This is allowed by the underlying implementation
76
// on windows but not on Posix, so we're doing unneeded checks on Posix.
77
// It's worth it to share the code.
78
void CheckHeldAndUnmark();
79
void CheckUnheldAndMark();
81
// All private data is implicitly protected by lock_.
82
// Be VERY careful to only access members under that lock.
84
// Determines validity of owning_thread_id_. Needed as we don't have
85
// a null owning_thread_id_ value.
86
bool owned_by_thread_;
87
base::PlatformThreadId owning_thread_id_;
90
// Platform specific underlying lock implementation.
91
internal::LockImpl lock_;
93
DISALLOW_COPY_AND_ASSIGN(Lock);
96
// A helper class that acquires the given Lock while the AutoLock is in scope.
99
struct AlreadyAcquired {};
101
explicit AutoLock(Lock& lock) : lock_(lock) {
105
AutoLock(Lock& lock, const AlreadyAcquired&) : lock_(lock) {
106
lock_.AssertAcquired();
110
lock_.AssertAcquired();
116
DISALLOW_COPY_AND_ASSIGN(AutoLock);
119
// AutoUnlock is a helper that will Release() the |lock| argument in the
120
// constructor, and re-Acquire() it in the destructor.
123
explicit AutoUnlock(Lock& lock) : lock_(lock) {
124
// We require our caller to have the lock.
125
lock_.AssertAcquired();
135
DISALLOW_COPY_AND_ASSIGN(AutoUnlock);
140
#endif // BASE_SYNCHRONIZATION_LOCK_H_