LLDB mainline
TargetAPIMutex.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_TARGET_TARGETAPIMUTEX_H
10#define LLDB_TARGET_TARGETAPIMUTEX_H
11
12#include "lldb/lldb-forward.h"
13#include <memory>
14#include <mutex>
15
16namespace lldb_private {
17
18/// A Lockable handle over a Target's API mutex, returned by
19/// Target::GetAPIMutex() and backing the public lldb::SBMutex.
20///
21/// Behaves like std::recursive_mutex: lock()/try_lock()/unlock() drive
22/// the actual synchronization, with the same contract (unlock() without
23/// a matching successful lock()/try_lock() is caller error). It carries
24/// no RAII of its own; wrap it in std::lock_guard<TargetAPIMutex> or
25/// std::unique_lock<TargetAPIMutex> for scope-based locking, exactly as
26/// with any other Lockable.
27///
28/// A handle may be constructed on one thread and then locked/unlocked
29/// on a different one, so lock()/try_lock() (re-)resolve which real
30/// mutex to use fresh on every call, rather than caching a single
31/// resolution for the handle's lifetime. The matching unlock() replays
32/// the exact resolution that call produced, rather than re-resolving,
33/// so the calling thread's policy at unlock() time can't cause it to
34/// release the wrong mutex (or fail to release the one it actually
35/// holds).
36///
37/// Default-constructed (or moved-from) handles are a genuine no-op: no
38/// synchronization primitive is touched at all.
40public:
41 TargetAPIMutex() = default;
42 explicit TargetAPIMutex(lldb::TargetSP target_sp)
43 : m_target_sp(std::move(target_sp)) {}
44
45 TargetAPIMutex(TargetAPIMutex &&other) noexcept = default;
46 TargetAPIMutex &operator=(TargetAPIMutex &&other) noexcept = default;
47
48 TargetAPIMutex(const TargetAPIMutex &) = delete;
50
51 void lock();
52 bool try_lock();
53 void unlock() {
54 if (m_mutex)
55 m_mutex->unlock();
56 }
57
58private:
59 /// An aliasing shared_ptr into m_target_sp's own mutex, resolved fresh
60 /// on every lock()/try_lock() call. Shares m_target_sp's control block
61 /// (keeping the Target alive) while pointing at the mutex living inside
62 /// it. Null when this handle is a genuine no-op.
63 std::shared_ptr<std::recursive_mutex> m_mutex;
65};
66
67} // namespace lldb_private
68
69#endif // LLDB_TARGET_TARGETAPIMUTEX_H
std::shared_ptr< std::recursive_mutex > m_mutex
An aliasing shared_ptr into m_target_sp's own mutex, resolved fresh on every lock()/try_lock() call.
TargetAPIMutex & operator=(TargetAPIMutex &&other) noexcept=default
TargetAPIMutex(TargetAPIMutex &&other) noexcept=default
TargetAPIMutex & operator=(const TargetAPIMutex &)=delete
TargetAPIMutex(lldb::TargetSP target_sp)
TargetAPIMutex(const TargetAPIMutex &)=delete
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::Target > TargetSP