Revision: 12371
Author:   erikcorry
Date:     Thu Aug 23 04:15:06 2012
Log: Fix semaphore on MacOS. This is a commit of https://chromiumcodereview.appspot.com/10867009/ for Fedor Indutny
http://code.google.com/p/v8/source/detail?r=12371

Modified:
 /branches/bleeding_edge/src/platform-macos.cc
 /branches/bleeding_edge/test/cctest/test-api.cc

=======================================
--- /branches/bleeding_edge/src/platform-macos.cc       Fri Apr 13 07:08:31 2012
+++ /branches/bleeding_edge/src/platform-macos.cc       Thu Aug 23 04:15:06 2012
@@ -682,17 +682,27 @@
 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);

=======================================
--- /branches/bleeding_edge/test/cctest/test-api.cc     Mon Aug 20 07:32:32 2012
+++ /branches/bleeding_edge/test/cctest/test-api.cc     Thu Aug 23 04:15:06 2012
@@ -28,6 +28,11 @@

 #include <limits.h>

+#ifndef WIN32
+#include <signal.h>  // kill
+#include <unistd.h>  // getpid
+#endif  // WIN32
+
 #include "v8.h"

 #include "api.h"
@@ -17194,3 +17199,68 @@
   CompileRun("try { throw new Error(); } finally { gc(); }");
   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

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to