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>
|
#include <dispatch/dispatch.h>
|
||||||
#elif defined(OS_WIN)
|
#elif defined(OS_WIN)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#elif defined(OS_ANDROID)
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
#else
|
#else
|
||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#endif
|
#endif
|
||||||
@ -77,6 +80,10 @@ class Semaphore {
|
|||||||
dispatch_semaphore_t semaphore_;
|
dispatch_semaphore_t semaphore_;
|
||||||
#elif defined(OS_WIN)
|
#elif defined(OS_WIN)
|
||||||
HANDLE semaphore_;
|
HANDLE semaphore_;
|
||||||
|
#elif defined(OS_ANDROID)
|
||||||
|
std::condition_variable cv_;
|
||||||
|
std::mutex mutex_;
|
||||||
|
int value_;
|
||||||
#else
|
#else
|
||||||
sem_t semaphore_;
|
sem_t semaphore_;
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,13 +18,51 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
#include "base/posix/eintr_wrapper.h"
|
#include "base/posix/eintr_wrapper.h"
|
||||||
#include "util/misc/time.h"
|
#include "util/misc/time.h"
|
||||||
|
|
||||||
namespace crashpad {
|
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) {
|
Semaphore::Semaphore(int value) {
|
||||||
PCHECK(sem_init(&semaphore_, 0, value) == 0) << "sem_init";
|
PCHECK(sem_init(&semaphore_, 0, value) == 0) << "sem_init";
|
||||||
@ -65,6 +103,6 @@ void Semaphore::Signal() {
|
|||||||
PCHECK(sem_post(&semaphore_) == 0) << "sem_post";
|
PCHECK(sem_post(&semaphore_) == 0) << "sem_post";
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif // OS_ANDROID
|
||||||
|
|
||||||
} // namespace crashpad
|
} // namespace crashpad
|
||||||
|
@ -41,7 +41,10 @@ TEST(Semaphore, TimedWait) {
|
|||||||
|
|
||||||
TEST(Semaphore, TimedWaitTimeout) {
|
TEST(Semaphore, TimedWaitTimeout) {
|
||||||
Semaphore semaphore(0);
|
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) {
|
TEST(Semaphore, TimedWaitInfinite_0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user