Index: test/cctest/test-api.cc |
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
index 87e3c0c10071865c88929b7d4d99468310c1d924..79158ae4b503aebf6406a20fda137cb0f8b8807c 100644 |
--- a/test/cctest/test-api.cc |
+++ b/test/cctest/test-api.cc |
@@ -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 @@ THREADED_TEST(Regress137496) { |
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 |