Bitcoin Core 29.99.0
P2P Digital Currency
util.h
Go to the documentation of this file.
1// Copyright (c) The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#ifndef MP_UTIL_H
6#define MP_UTIL_H
7
8#include <capnp/schema.h>
9#include <cassert>
10#include <cstddef>
11#include <cstring>
12#include <functional>
13#include <kj/string-tree.h>
14#include <mutex>
15#include <string>
16#include <tuple>
17#include <type_traits>
18#include <utility>
19#include <variant>
20#include <vector>
21
22namespace mp {
23
25
30template <typename... Types>
32{
33 static constexpr size_t size = sizeof...(Types);
34};
35
44template <template <typename...> class Class, typename... Types, typename... Args>
45Class<Types..., std::remove_reference_t<Args>...> Make(Args&&... args)
46{
47 return Class<Types..., std::remove_reference_t<Args>...>{std::forward<Args>(args)...};
48}
49
55template <std::size_t index, typename List, typename _First = TypeList<>, bool done = index == 0>
56struct Split;
57
59template <typename _Second, typename _First>
60struct Split<0, _Second, _First, true>
61{
62 using First = _First;
63 using Second = _Second;
64};
65
67template <std::size_t index, typename Type, typename... _Second, typename... _First>
68struct Split<index, TypeList<Type, _Second...>, TypeList<_First...>, false>
69{
70 using _Next = Split<index - 1, TypeList<_Second...>, TypeList<_First..., Type>>;
71 using First = typename _Next::First;
72 using Second = typename _Next::Second;
73};
74
76template <typename Callable>
77using ResultOf = decltype(std::declval<Callable>()());
78
80template <typename T>
81using RemoveCvRef = std::remove_cv_t<std::remove_reference_t<T>>;
82
84template <typename T>
85using Decay = std::decay_t<T>;
86
88template <typename SfinaeExpr, typename Result_>
90{
91 using Result = Result_;
92};
93
95template <typename SfinaeExpr, typename Result = void>
97
106template <int priority>
107struct Priority : Priority<priority - 1>
108{
109};
110
112template <>
113struct Priority<0>
114{
115};
116
118template <typename T>
119const char* TypeName()
120{
121 // DisplayName string looks like
122 // "interfaces/capnp/common.capnp:ChainNotifications.resendWalletTransactions$Results"
123 // This discards the part of the string before the first ':' character.
124 // Another alternative would be to use the displayNamePrefixLength field,
125 // but this discards everything before the last '.' character, throwing away
126 // the object name, which is useful.
127 const char* display_name = ::capnp::Schema::from<T>().getProto().getDisplayName().cStr();
128 const char* short_name = strchr(display_name, ':');
129 return short_name ? short_name + 1 : display_name;
130}
131
133template <typename T>
135 std::variant<T*, T> data;
136
137 template <typename... Args>
138 PtrOrValue(T* ptr, Args&&... args) : data(ptr ? ptr : std::variant<T*, T>{std::in_place_type<T>, std::forward<Args>(args)...}) {}
139
140 T& operator*() { return data.index() ? std::get<T>(data) : *std::get<T*>(data); }
141 T* operator->() { return &**this; }
142 T& operator*() const { return data.index() ? std::get<T>(data) : *std::get<T*>(data); }
143 T* operator->() const { return &**this; }
144};
145
146// Annotated mutex and lock class (https://clang.llvm.org/docs/ThreadSafetyAnalysis.html)
147#if defined(__clang__) && (!defined(SWIG))
148#define MP_TSA(x) __attribute__((x))
149#else
150#define MP_TSA(x) // no-op
151#endif
152
153#define MP_CAPABILITY(x) MP_TSA(capability(x))
154#define MP_SCOPED_CAPABILITY MP_TSA(scoped_lockable)
155#define MP_REQUIRES(x) MP_TSA(requires_capability(x))
156#define MP_ACQUIRE(...) MP_TSA(acquire_capability(__VA_ARGS__))
157#define MP_RELEASE(...) MP_TSA(release_capability(__VA_ARGS__))
158#define MP_ASSERT_CAPABILITY(x) MP_TSA(assert_capability(x))
159#define MP_GUARDED_BY(x) MP_TSA(guarded_by(x))
160#define MP_NO_TSA MP_TSA(no_thread_safety_analysis)
161
162class MP_CAPABILITY("mutex") Mutex {
163public:
164 void lock() MP_ACQUIRE() { m_mutex.lock(); }
165 void unlock() MP_RELEASE() { m_mutex.unlock(); }
166
167 std::mutex m_mutex;
168};
169
171public:
172 explicit Lock(Mutex& m) MP_ACQUIRE(m) : m_lock(m.m_mutex) {}
173 ~Lock() MP_RELEASE() = default;
174 void unlock() MP_RELEASE() { m_lock.unlock(); }
175 void lock() MP_ACQUIRE() { m_lock.lock(); }
177 {
178 assert(m_lock.mutex() == &mutex.m_mutex);
179 assert(m_lock);
180 }
181
182 std::unique_lock<std::mutex> m_lock;
183};
184
186template <typename Lock>
188{
189 UnlockGuard(Lock& lock) : m_lock(lock) { m_lock.unlock(); }
192};
193
194template <typename Lock, typename Callback>
195void Unlock(Lock& lock, Callback&& callback)
196{
197 const UnlockGuard<Lock> unlock(lock);
198 callback();
199}
200
202std::string ThreadName(const char* exe_name);
203
206std::string LogEscape(const kj::StringTree& string);
207
209using FdToArgsFn = std::function<std::vector<std::string>(int fd)>;
210
217int SpawnProcess(int& pid, FdToArgsFn&& fd_to_args);
218
220void ExecProcess(const std::vector<std::string>& args);
221
223int WaitProcess(int pid);
224
225inline char* CharCast(char* c) { return c; }
226inline char* CharCast(unsigned char* c) { return (char*)c; }
227inline const char* CharCast(const char* c) { return c; }
228inline const char* CharCast(const unsigned char* c) { return (const char*)c; }
229
230} // namespace mp
231
232#endif // MP_UTIL_H
ArgsManager & args
Definition: bitcoind.cpp:277
Definition: util.h:170
void assert_locked(Mutex &mutex) MP_ASSERT_CAPABILITY() MP_ASSERT_CAPABILITY(mutex)
Definition: util.h:176
void unlock() MP_RELEASE()
Definition: util.h:174
Lock(Mutex &m) MP_ACQUIRE(m)
Definition: util.h:172
~Lock() MP_RELEASE()=default
std::unique_lock< std::mutex > m_lock
Definition: util.h:182
void lock() MP_ACQUIRE()
Definition: util.h:175
#define T(expected, seed, data)
#define MP_RELEASE(...)
Definition: util.h:157
#define MP_SCOPED_CAPABILITY
Definition: util.h:154
#define MP_ACQUIRE(...)
Definition: util.h:156
#define MP_ASSERT_CAPABILITY(x)
Definition: util.h:158
Functions to serialize / deserialize common bitcoin types.
Definition: common-types.h:57
void Unlock(Lock &lock, Callback &&callback)
Definition: util.h:195
int WaitProcess(int pid)
Wait for a process to exit and return its exit code.
Definition: util.cpp:146
const char * TypeName()
Return capnp type name with filename prefix removed.
Definition: util.h:119
class MP_CAPABILITY("mutex") Mutex
Definition: util.h:162
std::string ThreadName(const char *exe_name)
Format current thread name as "{exe_name}-{$pid}/{thread_name}-{$tid}".
Definition: util.cpp:48
typename _Require< SfinaeExpr, Result >::Result Require
SFINAE helper, basically the same as to C++17's void_t, but allowing types other than void to be retu...
Definition: util.h:96
int SpawnProcess(int &pid, FdToArgsFn &&fd_to_args)
Spawn a new process that communicates with the current process over a socket pair.
Definition: util.cpp:104
Class< Types..., std::remove_reference_t< Args >... > Make(Args &&... args)
Construct a template class value by deducing template arguments from the types of constructor argumen...
Definition: util.h:45
std::decay_t< T > Decay
Type helper abbreviating std::decay.
Definition: util.h:85
std::remove_cv_t< std::remove_reference_t< T > > RemoveCvRef
Substitutue for std::remove_cvref_t.
Definition: util.h:81
std::string LogEscape(const kj::StringTree &string)
Escape binary string for use in log so it doesn't trigger unicode decode errors in python unit tests.
Definition: util.cpp:79
decltype(std::declval< Callable >()()) ResultOf
Type helper giving return type of a callable type.
Definition: util.h:77
char * CharCast(char *c)
Definition: util.h:225
std::function< std::vector< std::string >(int fd)> FdToArgsFn
Callback type used by SpawnProcess below.
Definition: util.h:209
void ExecProcess(const std::vector< std::string > &args)
Call execvp with vector args.
Definition: util.cpp:132
SFINAE helper, see using Require below.
Definition: util.h:90
Result_ Result
Definition: util.h:91
Function parameter type for prioritizing overloaded function calls that would otherwise be ambiguous.
Definition: util.h:108
Convenient wrapper around std::variant<T*, T>
Definition: util.h:134
T & operator*()
Definition: util.h:140
T * operator->() const
Definition: util.h:143
std::variant< T *, T > data
Definition: util.h:135
T & operator*() const
Definition: util.h:142
T * operator->()
Definition: util.h:141
PtrOrValue(T *ptr, Args &&... args)
Definition: util.h:138
Type helper splitting a TypeList into two halves at position index.
Definition: util.h:56
Generic utility functions used by capnp code.
Definition: util.h:32
static constexpr size_t size
Definition: util.h:33
Analog to std::lock_guard that unlocks instead of locks.
Definition: util.h:188
UnlockGuard(Lock &lock)
Definition: util.h:189
~UnlockGuard()
Definition: util.h:190
Lock & m_lock
Definition: util.h:191
assert(!tx.IsCoinBase())