summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFedor Indutny <fedor.indutny@gmail.com>2012-09-06 16:06:15 +0200
committerBert Belder <bertbelder@gmail.com>2012-09-06 16:07:40 +0200
commit052e63f27f7b1edf5635d6a266653fe77c42941c (patch)
tree81a6bd5aac0110b4490a6ab1a50274cf5fd31bfd
parentc5e554dc7ef36c276760f55fb702b1ac0dfa4fa8 (diff)
downloadnode-new-052e63f27f7b1edf5635d6a266653fe77c42941c.tar.gz
v8: fix semaphore on MacOS
Landed upstream: https://chromiumcodereview.appspot.com/10867009/
-rw-r--r--deps/v8/src/platform-macos.cc22
-rw-r--r--deps/v8/test/cctest/test-api.cc70
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