mirror of
https://github.com/LSPosed/LSPlant.git
synced 2025-05-05 14:06:37 +08:00
Lock-free JavaDebuggable guard
This commit is contained in:
parent
8c92a2d5a1
commit
35612201f9
@ -615,22 +615,54 @@ std::string GetProxyMethodShorty(JNIEnv *env, jobject proxy_method) {
|
|||||||
|
|
||||||
struct JavaDebuggableGuard {
|
struct JavaDebuggableGuard {
|
||||||
JavaDebuggableGuard() {
|
JavaDebuggableGuard() {
|
||||||
std::unique_lock lk(lock);
|
while (true) {
|
||||||
if (count.fetch_add(1, std::memory_order_acq_rel) == 0) {
|
size_t expected = 0;
|
||||||
Runtime::Current()->SetJavaDebuggable(
|
if (count.compare_exchange_strong(expected, 1, std::memory_order_acq_rel,
|
||||||
Runtime::RuntimeDebugState::kJavaDebuggableAtInit);
|
std::memory_order_acquire)) {
|
||||||
|
Runtime::Current()->SetJavaDebuggable(
|
||||||
|
Runtime::RuntimeDebugState::kJavaDebuggableAtInit);
|
||||||
|
count.fetch_add(1, std::memory_order_release);
|
||||||
|
count.notify_all();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (expected == 1) {
|
||||||
|
count.wait(expected, std::memory_order_acquire);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (count.compare_exchange_strong(expected, expected + 1, std::memory_order_acq_rel,
|
||||||
|
std::memory_order_relaxed)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~JavaDebuggableGuard() {
|
~JavaDebuggableGuard() {
|
||||||
std::unique_lock lk(lock);
|
while (true) {
|
||||||
if (count.fetch_sub(1, std::memory_order_acq_rel) == 1) {
|
size_t expected = 2;
|
||||||
Runtime::Current()->SetJavaDebuggable(Runtime::RuntimeDebugState::kNonJavaDebuggable);
|
if (count.compare_exchange_strong(expected, 1, std::memory_order_acq_rel,
|
||||||
|
std::memory_order_acquire)) {
|
||||||
|
Runtime::Current()->SetJavaDebuggable(
|
||||||
|
Runtime::RuntimeDebugState::kNonJavaDebuggable);
|
||||||
|
count.fetch_sub(1, std::memory_order_release);
|
||||||
|
count.notify_all();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (expected == 1) {
|
||||||
|
count.wait(expected, std::memory_order_acquire);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (count.compare_exchange_strong(expected, expected - 1, std::memory_order_acq_rel,
|
||||||
|
std::memory_order_relaxed)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
inline static std::atomic_size_t count{0};
|
inline static std::atomic_size_t count{0};
|
||||||
inline static std::mutex lock;
|
static_assert(std::atomic_size_t::is_always_lock_free, "Unsupported architecture");
|
||||||
|
static_assert(std::is_same_v<std::atomic_size_t::value_type, size_t>,
|
||||||
|
"Unsupported architecture");
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user