v8: fix semaphore on MacOS

Landed upstream: https://chromiumcodereview.appspot.com/10867009/
v0.8.16-release
Fedor Indutny 2012-09-06 16:06:15 +02:00 committed by Bert Belder
parent c5e554dc7e
commit 052e63f27f
2 changed files with 86 additions and 6 deletions

View File

@ -682,17 +682,27 @@ Mutex* OS::CreateMutex() {
class MacOSSemaphore : public Semaphore {
public:
explicit MacOSSemaphore(int count) {
semaphore_create(mach_task_self(), &semaphore_, SYNC_POLICY_FIFO, count);
int r;
r = semaphore_create(mach_task_self(),
&semaphore_,
SYNC_POLICY_FIFO,
count);
ASSERT(r == KERN_SUCCESS);
}
~MacOSSemaphore() {
semaphore_destroy(mach_task_self(), semaphore_);
int r;
r = semaphore_destroy(mach_task_self(), semaphore_);
ASSERT(r == KERN_SUCCESS);
}
// The MacOS mach semaphore documentation claims it does not have spurious
// wakeups, the way pthreads semaphores do. So the code from the linux
// platform is not needed here.
void Wait() { semaphore_wait(semaphore_); }
void Wait() {
int r;
do {
r = semaphore_wait(semaphore_);
ASSERT(r == KERN_SUCCESS || r == KERN_ABORTED);
} while (r == KERN_ABORTED);
}
bool Wait(int timeout);

View File

@ -27,6 +27,11 @@
#include <limits.h>
#ifndef WIN32
#include <signal.h> // kill
#include <unistd.h> // getpid
#endif // WIN32
#include "v8.h"
#include "api.h"
@ -17017,3 +17022,68 @@ THREADED_TEST(Regress142088) {
CHECK(context->Global()->Get(v8_str("y_from_obj"))->IsUndefined());
CHECK(context->Global()->Get(v8_str("y_from_subobj"))->IsUndefined());
}
#ifndef WIN32
class ThreadInterruptTest {
public:
ThreadInterruptTest() : sem_(NULL), sem_value_(0) { }
~ThreadInterruptTest() { delete sem_; }
void RunTest() {
sem_ = i::OS::CreateSemaphore(0);
InterruptThread i_thread(this);
i_thread.Start();
sem_->Wait();
CHECK_EQ(kExpectedValue, sem_value_);
}
private:
static const int kExpectedValue = 1;
class InterruptThread : public i::Thread {
public:
explicit InterruptThread(ThreadInterruptTest* test)
: Thread("InterruptThread"), test_(test) {}
virtual void Run() {
struct sigaction action;
// Ensure that we'll enter waiting condition
i::OS::Sleep(100);
// Setup signal handler
memset(&action, 0, sizeof(action));
action.sa_handler = SignalHandler;
sigaction(SIGCHLD, &action, NULL);
// Send signal
kill(getpid(), SIGCHLD);
// Ensure that if wait has returned because of error
i::OS::Sleep(100);
// Set value and signal semaphore
test_->sem_value_ = 1;
test_->sem_->Signal();
}
static void SignalHandler(int signal) {
}
private:
ThreadInterruptTest* test_;
struct sigaction sa_;
};
i::Semaphore* sem_;
volatile int sem_value_;
};
THREADED_TEST(SemaphoreInterruption) {
ThreadInterruptTest().RunTest();
}
#endif // WIN32