mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 22:26:06 +00:00
android: Implement Semaphore with a condition variable and mutex
Bionic uses negative values of a semaphore to represent contention. `sem_timedwait` fails to restore the value to 0 on timeout resulting in an error (EBUSY) upon calling `sem_destroy`. Bug: crashpad:30 Change-Id: If1c73a54a879ebd003b0792ebb8f68ceb83ac8bb Reviewed-on: https://chromium-review.googlesource.com/894106 Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
parent
c9244d58df
commit
441789be5b
@ -23,6 +23,9 @@
|
||||
#include <dispatch/dispatch.h>
|
||||
#elif defined(OS_WIN)
|
||||
#include <windows.h>
|
||||
#elif defined(OS_ANDROID)
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#else
|
||||
#include <semaphore.h>
|
||||
#endif
|
||||
@ -77,6 +80,10 @@ class Semaphore {
|
||||
dispatch_semaphore_t semaphore_;
|
||||
#elif defined(OS_WIN)
|
||||
HANDLE semaphore_;
|
||||
#elif defined(OS_ANDROID)
|
||||
std::condition_variable cv_;
|
||||
std::mutex mutex_;
|
||||
int value_;
|
||||
#else
|
||||
sem_t semaphore_;
|
||||
#endif
|
||||
|
@ -18,13 +18,51 @@
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/posix/eintr_wrapper.h"
|
||||
#include "util/misc/time.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
#if defined(OS_ANDROID)
|
||||
|
||||
Semaphore::Semaphore(int value) : cv_(), mutex_(), value_(value) {}
|
||||
|
||||
Semaphore::~Semaphore() = default;
|
||||
|
||||
void Semaphore::Wait() {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
cv_.wait(lock, [this] { return this->value_ > 0; });
|
||||
--value_;
|
||||
}
|
||||
|
||||
bool Semaphore::TimedWait(double seconds) {
|
||||
DCHECK_GE(seconds, 0.0);
|
||||
|
||||
if (isinf(seconds)) {
|
||||
Wait();
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
if (!cv_.wait_for(lock, std::chrono::duration<double>(seconds), [this] {
|
||||
return this->value_ > 0;
|
||||
})) {
|
||||
return false;
|
||||
}
|
||||
--value_;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Semaphore::Signal() {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
++value_;
|
||||
cv_.notify_one();
|
||||
}
|
||||
|
||||
#elif !defined(OS_MACOSX)
|
||||
|
||||
Semaphore::Semaphore(int value) {
|
||||
PCHECK(sem_init(&semaphore_, 0, value) == 0) << "sem_init";
|
||||
@ -65,6 +103,6 @@ void Semaphore::Signal() {
|
||||
PCHECK(sem_post(&semaphore_) == 0) << "sem_post";
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // OS_ANDROID
|
||||
|
||||
} // namespace crashpad
|
||||
|
@ -41,7 +41,10 @@ TEST(Semaphore, TimedWait) {
|
||||
|
||||
TEST(Semaphore, TimedWaitTimeout) {
|
||||
Semaphore semaphore(0);
|
||||
EXPECT_FALSE(semaphore.TimedWait(0.01)); // 10ms
|
||||
semaphore.Signal();
|
||||
constexpr double kTenMs = 0.01;
|
||||
EXPECT_TRUE(semaphore.TimedWait(kTenMs));
|
||||
EXPECT_FALSE(semaphore.TimedWait(kTenMs));
|
||||
}
|
||||
|
||||
TEST(Semaphore, TimedWaitInfinite_0) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user