class Mutex

Defined at line 151 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

-----------------------------------------------------------------------------

Mutex

-----------------------------------------------------------------------------

A `Mutex` is a non-reentrant (aka non-recursive) Mutually Exclusive lock

on some resource, typically a variable or data structure with associated

invariants. Proper usage of mutexes prevents concurrent access by different

threads to the same resource.

A `Mutex` has two basic operations: `Mutex::Lock()` and `Mutex::Unlock()`.

The `Lock()` operation *acquires* a `Mutex` (in a state known as an

*exclusive* -- or *write* -- lock), and the `Unlock()` operation *releases* a

Mutex. During the span of time between the Lock() and Unlock() operations,

a mutex is said to be *held*. By design, all mutexes support exclusive/write

locks, as this is the most common way to use a mutex.

Mutex operations are only allowed under certain conditions; otherwise an

operation is "invalid", and disallowed by the API. The conditions concern

both the current state of the mutex and the identity of the threads that

are performing the operations.

The `Mutex` state machine for basic lock/unlock operations is quite simple:

| | Lock() | Unlock() |

|----------------+------------------------+----------|

| Free | Exclusive | invalid |

| Exclusive | blocks, then exclusive | Free |

The full conditions are as follows.

* Calls to `Unlock()` require that the mutex be held, and must be made in the

same thread that performed the corresponding `Lock()` operation which

acquired the mutex; otherwise the call is invalid.

* The mutex being non-reentrant (or non-recursive) means that a call to

`Lock()` or `TryLock()` must not be made in a thread that already holds the

mutex; such a call is invalid.

* In other words, the state of being "held" has both a temporal component

(from `Lock()` until `Unlock()`) as well as a thread identity component:

the mutex is held *by a particular thread*.

An "invalid" operation has undefined behavior. The `Mutex` implementation

is allowed to do anything on an invalid call, including, but not limited to,

crashing with a useful error message, silently succeeding, or corrupting

data structures. In debug mode, the implementation may crash with a useful

error message.

`Mutex` is not guaranteed to be "fair" in prioritizing waiting threads; it

is, however, approximately fair over long periods, and starvation-free for

threads at the same priority.

The lock/unlock primitives are now annotated with lock annotations

defined in (base/thread_annotations.h). When writing multi-threaded code,

you should use lock annotations whenever possible to document your lock

synchronization policy. Besides acting as documentation, these annotations

also help compilers or static analysis tools to identify and warn about

issues that could potentially result in race conditions and deadlocks.

For more information about the lock annotations, please see

[Thread Safety

Analysis](http://clang.llvm.org/docs/ThreadSafetyAnalysis.html) in the Clang

documentation.

See also `MutexLock`, below, for scoped `Mutex` acquisition.

Public Methods

void WriterLock ()

Mutex::WriterLock()

Mutex::WriterUnlock()

Mutex::WriterTryLock()

Aliases for `Mutex::Lock()`, `Mutex::Unlock()`, and `Mutex::TryLock()`.

These methods may be used (along with the complementary `Reader*()`

methods) to distinguish simple exclusive `Mutex` usage (`Lock()`,

etc.) from reader/writer lock usage.

Defined at line 280 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

void WriterUnlock ()

Defined at line 282 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

bool WriterTryLock ()

Defined at line 284 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

void Await (const Condition & cond)

Mutex::Await()

Unlocks this `Mutex` and blocks until simultaneously both `cond` is `true`

and this `Mutex` can be reacquired, then reacquires this `Mutex` in the

same mode in which it was previously held. If the condition is initially

`true`, `Await()` *may* skip the release/re-acquire step.

`Await()` requires that this thread holds this `Mutex` in some mode.

Defined at line 328 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

void LockWhen (const Condition & cond)

Mutex::LockWhen()

Mutex::ReaderLockWhen()

Mutex::WriterLockWhen()

Blocks until simultaneously both `cond` is `true` and this `Mutex` can

be acquired, then atomically acquires this `Mutex`. `LockWhen()` is

logically equivalent to `*Lock(); Await();` though they may have different

performance characteristics.

Defined at line 340 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

void ReaderLockWhen (const Condition & cond)

Defined at line 345 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

void WriterLockWhen (const Condition & cond)

Defined at line 350 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

bool AwaitWithTimeout (const Condition & cond, absl::Duration timeout)

Mutex::AwaitWithTimeout()

Mutex::AwaitWithDeadline()

Unlocks this `Mutex` and blocks until simultaneously:

- either `cond` is true or the {timeout has expired, deadline has passed}

and

- this `Mutex` can be reacquired,

then reacquire this `Mutex` in the same mode in which it was previously

held, returning `true` iff `cond` is `true` on return.

If the condition is initially `true`, the implementation *may* skip the

release/re-acquire step and return immediately.

Deadlines in the past are equivalent to an immediate deadline.

Negative timeouts are equivalent to a zero timeout.

This method requires that this thread holds this `Mutex` in some mode.

Defined at line 375 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

bool AwaitWithDeadline (const Condition & cond, absl::Time deadline)

Defined at line 379 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

bool LockWhenWithTimeout (const Condition & cond, absl::Duration timeout)

Mutex::LockWhenWithTimeout()

Mutex::ReaderLockWhenWithTimeout()

Mutex::WriterLockWhenWithTimeout()

Blocks until simultaneously both:

- either `cond` is `true` or the timeout has expired, and

- this `Mutex` can be acquired,

then atomically acquires this `Mutex`, returning `true` iff `cond` is

`true` on return.

Negative timeouts are equivalent to a zero timeout.

Defined at line 394 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

bool ReaderLockWhenWithTimeout (const Condition & cond, absl::Duration timeout)

Defined at line 399 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

bool WriterLockWhenWithTimeout (const Condition & cond, absl::Duration timeout)

Defined at line 404 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

bool LockWhenWithDeadline (const Condition & cond, absl::Time deadline)

Mutex::LockWhenWithDeadline()

Mutex::ReaderLockWhenWithDeadline()

Mutex::WriterLockWhenWithDeadline()

Blocks until simultaneously both:

- either `cond` is `true` or the deadline has been passed, and

- this `Mutex` can be acquired,

then atomically acquires this Mutex, returning `true` iff `cond` is `true`

on return.

Deadlines in the past are equivalent to an immediate deadline.

Defined at line 420 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

bool ReaderLockWhenWithDeadline (const Condition & cond, absl::Time deadline)

Defined at line 425 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

bool WriterLockWhenWithDeadline (const Condition & cond, absl::Time deadline)

Defined at line 430 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

void Mutex ()

Creates a `Mutex` that is not held by anyone. This constructor is

typically used for Mutexes allocated on the heap or the stack.

To create `Mutex` instances with static storage duration

(e.g. a namespace-scoped or global variable), see

`Mutex::Mutex(absl::kConstInit)` below instead.

Defined at line 1061 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

void Mutex (absl::ConstInitType )

Creates a mutex with static storage duration. A global variable

constructed this way avoids the lifetime issues that can occur on program

startup and shutdown. (See absl/base/const_init.h.)

For Mutexes allocated on the heap and stack, instead use the default

constructor, which can interact more fully with the thread sanitizer.

Example usage:

namespace foo {

ABSL_CONST_INIT absl::Mutex mu(absl::kConstInit);

}

Defined at line 1065 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

void ~Mutex ()

Defined at line 1068 of file ../../third_party/abseil-cpp/absl/synchronization/mutex.h

void Lock ()

Mutex::Lock()

Blocks the calling thread, if necessary, until this `Mutex` is free, and

then acquires it exclusively. (This lock is also known as a "write lock.")

void Unlock ()

Mutex::Unlock()

Releases this `Mutex` and returns it from the exclusive/write state to the

free state. Calling thread must hold the `Mutex` exclusively.

bool TryLock ()

Mutex::TryLock()

If the mutex can be acquired without blocking, does so exclusively and

returns `true`. Otherwise, returns `false`. Returns `true` with high

probability if the `Mutex` was free.

void AssertHeld ()

Mutex::AssertHeld()

Require that the mutex be held exclusively (write mode) by this thread.

If the mutex is not currently held by this thread, this function may report

an error (typically by crashing with a diagnostic) or it may do nothing.

This function is intended only as a tool to assist debugging; it doesn't

guarantee correctness.

void ReaderLock ()

Mutex::ReaderLock()

Blocks the calling thread, if necessary, until this `Mutex` is either free,

or in shared mode, and then acquires a share of it. Note that

`ReaderLock()` will block if some other thread has an exclusive/writer lock

on the mutex.

void ReaderUnlock ()

Mutex::ReaderUnlock()

Releases a read share of this `Mutex`. `ReaderUnlock` may return a mutex to

the free state if this thread holds the last reader lock on the mutex. Note

that you cannot call `ReaderUnlock()` on a mutex held in write mode.

bool ReaderTryLock ()

Mutex::ReaderTryLock()

If the mutex can be acquired without blocking, acquires this mutex for

shared access and returns `true`. Otherwise, returns `false`. Returns

`true` with high probability if the `Mutex` was free or shared.

void AssertReaderHeld ()

Mutex::AssertReaderHeld()

Require that the mutex be held at least in shared mode (read mode) by this

thread.

If the mutex is not currently held by this thread, this function may report

an error (typically by crashing with a diagnostic) or it may do nothing.

This function is intended only as a tool to assist debugging; it doesn't

guarantee correctness.

void EnableInvariantDebugging (void (*)(void *) invariant, void * arg)

Mutex::EnableInvariantDebugging()

If `invariant`!=null and if invariant debugging has been enabled globally,

cause `(*invariant)(arg)` to be called at moments when the invariant for

this `Mutex` should hold (for example: just after acquire, just before

release).

The routine `invariant` should have no side-effects since it is not

guaranteed how many times it will be called; it should check the invariant

and crash if it does not hold. Enabling global invariant debugging may

substantially reduce `Mutex` performance; it should be set only for

non-production runs. Optimization options may also disable invariant

checks.

void EnableDebugLog (const char * name)

Mutex::EnableDebugLog()

Cause all subsequent uses of this `Mutex` to be logged via

`ABSL_RAW_LOG(INFO)`. Log entries are tagged with `name` if no previous

call to `EnableInvariantDebugging()` or `EnableDebugLog()` has been made.

Note: This method substantially reduces `Mutex` performance.

void ForgetDeadlockInfo ()

Mutex::ForgetDeadlockInfo()

Forget any deadlock-detection information previously gathered

about this `Mutex`. Call this method in debug mode when the lock ordering

of a `Mutex` changes.

void AssertNotHeld ()

Mutex::AssertNotHeld()

Return immediately if this thread does not hold this `Mutex` in any

mode; otherwise, may report an error (typically by crashing with a

diagnostic), or may return immediately.

Currently this check is performed only if all of:

- in debug mode

- SetMutexDeadlockDetectionMode() has been set to kReport or kAbort

- number of locks concurrently held by this thread is not large.

are true.

void InternalAttemptToUseMutexInFatalSignalHandler ()

Mutex::InternalAttemptToUseMutexInFatalSignalHandler()

Causes the `Mutex` implementation to prepare itself for re-entry caused by

future use of `Mutex` within a fatal signal handler. This method is

intended for use only for last-ditch attempts to log crash information.

It does not guarantee that attempts to use Mutexes within the handler will

not deadlock; it merely makes other faults less likely.

WARNING: This routine must be invoked from a signal handler, and the

signal handler must either loop forever or terminate the process.

Attempts to return from (or `longjmp` out of) the signal handler once this

call has been made may cause arbitrary program behaviour including

crashes and deadlocks.

Friends

class CondVar