Commit c6094f52 authored by erikcorry's avatar erikcorry

Fix semaphore on MacOS. This is a commit of...

Fix semaphore on MacOS.  This is a commit of https://chromiumcodereview.appspot.com/10867009/ for Fedor Indutny

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12371 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 44c3b03a
...@@ -682,17 +682,27 @@ Mutex* OS::CreateMutex() { ...@@ -682,17 +682,27 @@ Mutex* OS::CreateMutex() {
class MacOSSemaphore : public Semaphore { class MacOSSemaphore : public Semaphore {
public: public:
explicit MacOSSemaphore(int count) { 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() { ~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 void Wait() {
// wakeups, the way pthreads semaphores do. So the code from the linux int r;
// platform is not needed here. do {
void Wait() { semaphore_wait(semaphore_); } r = semaphore_wait(semaphore_);
ASSERT(r == KERN_SUCCESS || r == KERN_ABORTED);
} while (r == KERN_ABORTED);
}
bool Wait(int timeout); bool Wait(int timeout);
......
...@@ -28,6 +28,11 @@ ...@@ -28,6 +28,11 @@
#include <limits.h> #include <limits.h>
#ifndef WIN32
#include <signal.h> // kill
#include <unistd.h> // getpid
#endif // WIN32
#include "v8.h" #include "v8.h"
#include "api.h" #include "api.h"
...@@ -17194,3 +17199,68 @@ THREADED_TEST(Regress137496) { ...@@ -17194,3 +17199,68 @@ THREADED_TEST(Regress137496) {
CompileRun("try { throw new Error(); } finally { gc(); }"); CompileRun("try { throw new Error(); } finally { gc(); }");
CHECK(try_catch.HasCaught()); CHECK(try_catch.HasCaught());
} }
#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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment