Index: test/cctest/test-api.cc |
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
index cbead0fc05757971ddb5c9c5fb86316cc09661d5..d7f660250c64def3e83c28272c75ae676b76965b 100644 |
--- a/test/cctest/test-api.cc |
+++ b/test/cctest/test-api.cc |
@@ -21819,11 +21819,12 @@ class RequestInterruptTestBase { |
virtual ~RequestInterruptTestBase() { } |
+ virtual void StartInterruptThread() = 0; |
+ |
virtual void TestBody() = 0; |
void RunTest() { |
- InterruptThread i_thread(this); |
- i_thread.Start(); |
+ StartInterruptThread(); |
v8::HandleScope handle_scope(isolate_); |
@@ -21852,7 +21853,6 @@ class RequestInterruptTestBase { |
return should_continue_; |
} |
- protected: |
static void ShouldContinueCallback( |
const v8::FunctionCallbackInfo<Value>& info) { |
RequestInterruptTestBase* test = |
@@ -21861,6 +21861,24 @@ class RequestInterruptTestBase { |
info.GetReturnValue().Set(test->ShouldContinue()); |
} |
+ LocalContext env_; |
+ v8::Isolate* isolate_; |
+ i::Semaphore sem_; |
+ int warmup_; |
+ bool should_continue_; |
+}; |
+ |
+ |
+class RequestInterruptTestBaseWithSimpleInterrupt |
+ : public RequestInterruptTestBase { |
+ public: |
+ RequestInterruptTestBaseWithSimpleInterrupt() : i_thread(this) { } |
+ |
+ virtual void StartInterruptThread() { |
+ i_thread.Start(); |
+ } |
+ |
+ private: |
class InterruptThread : public i::Thread { |
public: |
explicit InterruptThread(RequestInterruptTestBase* test) |
@@ -21880,15 +21898,12 @@ class RequestInterruptTestBase { |
RequestInterruptTestBase* test_; |
}; |
- LocalContext env_; |
- v8::Isolate* isolate_; |
- i::Semaphore sem_; |
- int warmup_; |
- bool should_continue_; |
+ InterruptThread i_thread; |
}; |
-class RequestInterruptTestWithFunctionCall : public RequestInterruptTestBase { |
+class RequestInterruptTestWithFunctionCall |
+ : public RequestInterruptTestBaseWithSimpleInterrupt { |
public: |
virtual void TestBody() { |
Local<Function> func = Function::New( |
@@ -21900,7 +21915,8 @@ class RequestInterruptTestWithFunctionCall : public RequestInterruptTestBase { |
}; |
-class RequestInterruptTestWithMethodCall : public RequestInterruptTestBase { |
+class RequestInterruptTestWithMethodCall |
+ : public RequestInterruptTestBaseWithSimpleInterrupt { |
public: |
virtual void TestBody() { |
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); |
@@ -21914,7 +21930,8 @@ class RequestInterruptTestWithMethodCall : public RequestInterruptTestBase { |
}; |
-class RequestInterruptTestWithAccessor : public RequestInterruptTestBase { |
+class RequestInterruptTestWithAccessor |
+ : public RequestInterruptTestBaseWithSimpleInterrupt { |
public: |
virtual void TestBody() { |
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); |
@@ -21928,7 +21945,8 @@ class RequestInterruptTestWithAccessor : public RequestInterruptTestBase { |
}; |
-class RequestInterruptTestWithNativeAccessor : public RequestInterruptTestBase { |
+class RequestInterruptTestWithNativeAccessor |
+ : public RequestInterruptTestBaseWithSimpleInterrupt { |
public: |
virtual void TestBody() { |
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); |
@@ -21955,7 +21973,7 @@ class RequestInterruptTestWithNativeAccessor : public RequestInterruptTestBase { |
class RequestInterruptTestWithMethodCallAndInterceptor |
- : public RequestInterruptTestBase { |
+ : public RequestInterruptTestBaseWithSimpleInterrupt { |
public: |
virtual void TestBody() { |
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate_); |
@@ -21978,7 +21996,8 @@ class RequestInterruptTestWithMethodCallAndInterceptor |
}; |
-class RequestInterruptTestWithMathAbs : public RequestInterruptTestBase { |
+class RequestInterruptTestWithMathAbs |
+ : public RequestInterruptTestBaseWithSimpleInterrupt { |
public: |
virtual void TestBody() { |
env_->Global()->Set(v8_str("WakeUpInterruptor"), Function::New( |
@@ -22062,6 +22081,61 @@ TEST(RequestInterruptTestWithMathAbs) { |
} |
+class ClearInterruptFromAnotherThread |
+ : public RequestInterruptTestBase { |
+ public: |
+ ClearInterruptFromAnotherThread() : i_thread(this), sem2_(0) { } |
+ |
+ virtual void StartInterruptThread() { |
+ i_thread.Start(); |
+ } |
+ |
+ virtual void TestBody() { |
+ Local<Function> func = Function::New( |
+ isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)); |
+ env_->Global()->Set(v8_str("ShouldContinue"), func); |
+ |
+ CompileRun("while (ShouldContinue()) { }"); |
+ } |
+ |
+ private: |
+ class InterruptThread : public i::Thread { |
+ public: |
+ explicit InterruptThread(ClearInterruptFromAnotherThread* test) |
+ : Thread("RequestInterruptTest"), test_(test) {} |
+ |
+ virtual void Run() { |
+ test_->sem_.Wait(); |
+ test_->isolate_->RequestInterrupt(&OnInterrupt, test_); |
+ test_->sem_.Wait(); |
+ test_->isolate_->ClearInterrupt(); |
+ test_->sem2_.Signal(); |
+ } |
+ |
+ static void OnInterrupt(v8::Isolate* isolate, void* data) { |
+ ClearInterruptFromAnotherThread* test = |
+ reinterpret_cast<ClearInterruptFromAnotherThread*>(data); |
+ test->sem_.Signal(); |
+ bool success = test->sem2_.WaitFor(i::TimeDelta::FromSeconds(2)); |
+ // Crash instead of timeout to make this failure more prominent. |
+ CHECK(success); |
+ test->should_continue_ = false; |
+ } |
+ |
+ private: |
+ ClearInterruptFromAnotherThread* test_; |
+ }; |
+ |
+ InterruptThread i_thread; |
+ i::Semaphore sem2_; |
+}; |
+ |
+ |
+TEST(ClearInterruptFromAnotherThread) { |
+ ClearInterruptFromAnotherThread().RunTest(); |
+} |
+ |
+ |
static Local<Value> function_new_expected_env; |
static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) { |
CHECK_EQ(function_new_expected_env, info.Data()); |