diff options
author | Fedor Indutny <fedor.indutny@gmail.com> | 2012-09-06 16:06:15 +0200 |
---|---|---|
committer | Bert Belder <bertbelder@gmail.com> | 2012-09-06 16:07:40 +0200 |
commit | 052e63f27f7b1edf5635d6a266653fe77c42941c (patch) | |
tree | 81a6bd5aac0110b4490a6ab1a50274cf5fd31bfd | |
parent | c5e554dc7ef36c276760f55fb702b1ac0dfa4fa8 (diff) | |
download | node-new-052e63f27f7b1edf5635d6a266653fe77c42941c.tar.gz |
v8: fix semaphore on MacOS
Landed upstream: https://chromiumcodereview.appspot.com/10867009/
-rw-r--r-- | deps/v8/src/platform-macos.cc | 22 | ||||
-rw-r--r-- | deps/v8/test/cctest/test-api.cc | 70 |
2 files changed, 86 insertions, 6 deletions
diff --git a/deps/v8/src/platform-macos.cc b/deps/v8/src/platform-macos.cc index a937ed3a5c..a216f6e4ca 100644 --- a/deps/v8/src/platform-macos.cc +++ b/deps/v8/src/platform-macos.cc @@ -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); diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index df810597a1..e24782085f 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -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 |