mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08:00
Add Semaphore::TimedWait().
This also splits the per-OS Semaphore methods into their own files. TEST=util_test Semaphore.* R=rsesek@chromium.org, scottmg@chromium.org Review URL: https://codereview.chromium.org/909263002
This commit is contained in:
parent
b16b89c89d
commit
10c264cd57
@ -44,8 +44,21 @@ class Semaphore {
|
||||
//! Atomically decrements the value of the semaphore by 1. If the new value is
|
||||
//! negative, this function blocks and will not return until the semaphore’s
|
||||
//! value is incremented to 0 by Signal().
|
||||
//!
|
||||
//! \sa TimedWait()
|
||||
void Wait();
|
||||
|
||||
//! \brief Performs a timed wait (or “procure”) operation on the semaphore.
|
||||
//!
|
||||
//! \param[in] seconds The maximum number of seconds to wait for the operation
|
||||
//! to complete.
|
||||
//!
|
||||
//! \return `false` if the wait timed out, `true` otherwise.
|
||||
//!
|
||||
//! This method is simlar to Wait(), except that the amount of time that it
|
||||
//! blocks is limited.
|
||||
bool TimedWait(double seconds);
|
||||
|
||||
//! \brief Performs the signal (or “post”) operation on the semaphore.
|
||||
//!
|
||||
//! Atomically increments the value of the semaphore by 1. If the new value is
|
||||
|
45
util/synchronization/semaphore_mac.cc
Normal file
45
util/synchronization/semaphore_mac.cc
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "util/synchronization/semaphore.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
Semaphore::Semaphore(int value)
|
||||
: semaphore_(dispatch_semaphore_create(value)) {
|
||||
CHECK(semaphore_) << "dispatch_semaphore_create";
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore() {
|
||||
dispatch_release(semaphore_);
|
||||
}
|
||||
|
||||
void Semaphore::Wait() {
|
||||
CHECK_EQ(dispatch_semaphore_wait(semaphore_, DISPATCH_TIME_FOREVER), 0);
|
||||
}
|
||||
|
||||
bool Semaphore::TimedWait(double seconds) {
|
||||
DCHECK_GE(seconds, 0.0);
|
||||
const dispatch_time_t timeout =
|
||||
dispatch_time(DISPATCH_TIME_NOW, seconds * NSEC_PER_SEC);
|
||||
return dispatch_semaphore_wait(semaphore_, timeout) == 0;
|
||||
}
|
||||
|
||||
void Semaphore::Signal() {
|
||||
dispatch_semaphore_signal(semaphore_);
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
57
util/synchronization/semaphore_posix.cc
Normal file
57
util/synchronization/semaphore_posix.cc
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "util/synchronization/semaphore.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/posix/eintr_wrapper.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
#if !defined(OS_MACOSX)
|
||||
|
||||
Semaphore::Semaphore(int value) {
|
||||
PCHECK(sem_init(&semaphore_, 0, value) == 0) << "sem_init";
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore() {
|
||||
PCHECK(sem_destroy(&semaphore_) == 0) << "sem_destroy";
|
||||
}
|
||||
|
||||
void Semaphore::Wait() {
|
||||
PCHECK(HANDLE_EINTR(sem_wait(&semaphore_)) == 0) << "sem_wait";
|
||||
}
|
||||
|
||||
bool Semaphore::TimedWait(double seconds) {
|
||||
DCHECK_GE(seconds, 0.0);
|
||||
timespec timeout;
|
||||
timeout.tv_sec = seconds;
|
||||
timeout.tv_nsec = (seconds - trunc(seconds)) * 1E9;
|
||||
|
||||
int rv = HANDLE_EINTR(sem_timedwait(&semaphore_, &timeout));
|
||||
PCHECK(rv == 0 || errno == ETIMEDOUT) << "sem_timedwait";
|
||||
return rv == 0;
|
||||
}
|
||||
|
||||
void Semaphore::Signal() {
|
||||
PCHECK(sem_post(&semaphore_) == 0) << "sem_post";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace crashpad
|
@ -30,6 +30,17 @@ TEST(Semaphore, Simple) {
|
||||
semaphore.Signal();
|
||||
}
|
||||
|
||||
TEST(Semaphore, TimedWait) {
|
||||
Semaphore semaphore(0);
|
||||
semaphore.Signal();
|
||||
EXPECT_TRUE(semaphore.TimedWait(0.01)); // 10ms
|
||||
}
|
||||
|
||||
TEST(Semaphore, TimedWaitTimeout) {
|
||||
Semaphore semaphore(0);
|
||||
EXPECT_FALSE(semaphore.TimedWait(0.01)); // 10ms
|
||||
}
|
||||
|
||||
struct ThreadMainInfo {
|
||||
#if defined(OS_POSIX)
|
||||
pthread_t pthread;
|
||||
|
@ -17,31 +17,9 @@
|
||||
#include <limits>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/posix/eintr_wrapper.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
|
||||
Semaphore::Semaphore(int value)
|
||||
: semaphore_(dispatch_semaphore_create(value)) {
|
||||
CHECK(semaphore_) << "dispatch_semaphore_create";
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore() {
|
||||
dispatch_release(semaphore_);
|
||||
}
|
||||
|
||||
void Semaphore::Wait() {
|
||||
CHECK_EQ(dispatch_semaphore_wait(semaphore_, DISPATCH_TIME_FOREVER), 0);
|
||||
}
|
||||
|
||||
void Semaphore::Signal() {
|
||||
dispatch_semaphore_signal(semaphore_);
|
||||
}
|
||||
|
||||
#elif defined(OS_WIN)
|
||||
|
||||
Semaphore::Semaphore(int value)
|
||||
: semaphore_(CreateSemaphore(nullptr,
|
||||
value,
|
||||
@ -58,28 +36,15 @@ void Semaphore::Wait() {
|
||||
PCHECK(WaitForSingleObject(semaphore_, INFINITE) == WAIT_OBJECT_0);
|
||||
}
|
||||
|
||||
bool Semaphore::TimedWait(double seconds) {
|
||||
DCHECK_GE(seconds, 0.0);
|
||||
DWORD rv = WaitForSingleObject(semaphore_, static_cast<DWORD>(seconds * 1E3));
|
||||
PCHECK(rv == WAIT_OBJECT_0 || rv == WAIT_TIMEOUT) << "WaitForSingleObject";
|
||||
return rv == WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
void Semaphore::Signal() {
|
||||
PCHECK(ReleaseSemaphore(semaphore_, 1, nullptr));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
Semaphore::Semaphore(int value) {
|
||||
PCHECK(sem_init(&semaphore_, 0, value) == 0) << "sem_init";
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore() {
|
||||
PCHECK(sem_destroy(&semaphore_)) << "sem_destroy";
|
||||
}
|
||||
|
||||
void Semaphore::Wait() {
|
||||
PCHECK(HANDLE_EINTR(sem_wait(&semaphore_))) << "sem_wait";
|
||||
}
|
||||
|
||||
void Semaphore::Signal() {
|
||||
PCHECK(sem_post(&semaphore_)) << "sem_post";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace crashpad
|
@ -121,7 +121,9 @@
|
||||
'stdlib/strlcpy.h',
|
||||
'stdlib/strnlen.cc',
|
||||
'stdlib/strnlen.h',
|
||||
'synchronization/semaphore.cc',
|
||||
'synchronization/semaphore_mac.cc',
|
||||
'synchronization/semaphore_posix.cc',
|
||||
'synchronization/semaphore_win.cc',
|
||||
'synchronization/semaphore.h',
|
||||
'win/scoped_handle.cc',
|
||||
'win/scoped_handle.h',
|
||||
|
Loading…
x
Reference in New Issue
Block a user