Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Unified Diff: runtime/vm/dart_api_impl_test.cc

Issue 8851008: Add support for interrupting an isolate in the vm. Interrupts are (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/dart_api_impl_test.cc
===================================================================
--- runtime/vm/dart_api_impl_test.cc (revision 2528)
+++ runtime/vm/dart_api_impl_test.cc (working copy)
@@ -7,6 +7,7 @@
#include "vm/assert.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_api_state.h"
+#include "vm/thread.h"
#include "vm/unit_test.h"
#include "vm/utils.h"
#include "vm/verifier.h"
@@ -497,7 +498,7 @@
result = Dart_ExternalStringGetPeer(ext8, NULL);
EXPECT(Dart_IsError(result));
EXPECT_STREQ("Dart_ExternalStringGetPeer expects argument 'peer' to be "
- "non-NULL.", Dart_GetError(result));
+ "non-null.", Dart_GetError(result));
// String is not external.
peer = NULL;
@@ -2850,6 +2851,125 @@
RunLoopTest(false, true);
}
+
+static Monitor* sync = NULL;
+static Dart_Isolate shared_isolate = NULL;
+void BusyLoop_start(uword unused) {
+ // TODO(turnidge): Get rid of call to 'function' after interrupts
+ // are checked on backward branches.
+ const char* kScriptChars =
+ "void function([foo='hi']) {\n"
+ "}\n"
+ "\n"
+ "void main() {\n"
+ " while (true) {\n" // Infinite loop.
+ " function();\n"
+ " }\n"
+ "}\n";
+
+
+ // Tell the other thread that shared_isolate is created.
+ Dart_Handle lib;
+ {
+ sync->Enter();
+ char* error = NULL;
+ shared_isolate = Dart_CreateIsolate(NULL, NULL, &error);
+ EXPECT(shared_isolate != NULL);
+ Dart_EnterScope();
+ Dart_Handle url = Dart_NewString(TestCase::url());
+ Dart_Handle source = Dart_NewString(kScriptChars);
+ lib = Dart_LoadScript(url, source, TestCase::library_handler);
+ EXPECT_VALID(lib);
+
+ sync->Notify();
+ sync->Exit();
+ }
+
+ Dart_Handle result = Dart_InvokeStatic(lib,
+ Dart_NewString(""),
+ Dart_NewString("main"),
+ 0,
+ NULL);
+ EXPECT(Dart_IsError(result));
+ EXPECT(Dart_ErrorHasException(result));
+ EXPECT_SUBSTRING("Unhandled exception:\nfoo\n",
+ Dart_GetError(result));
+
+ // Tell the other thread that we are done.
+ {
+ MonitorLocker ml(sync);
+ shared_isolate = NULL;
+ ml.Notify();
+ }
+
+ Dart_ExitScope();
+ Dart_ShutdownIsolate();
+}
+
+
+// This callback handles isolate interrupts for the IsolateInterrupt
+// test. It ignores the first two interrupts and throws an exception
+// on the third interrupt.
+static int interrupt_count = 0;
+static bool IsolateInterruptTestCallback() {
+ interrupt_count++;
+ OS::Print(" =========== Interrupt callback called #%d\n", interrupt_count);
+ if (interrupt_count >= 3) {
+ Dart_EnterScope();
+ Dart_Handle lib = Dart_LookupLibrary(Dart_NewString(TestCase::url()));
+ EXPECT_VALID(lib);
+ Dart_Handle exc = Dart_NewString("foo");
+ EXPECT_VALID(exc);
+ Dart_Handle result = Dart_ThrowException(exc);
+ EXPECT_VALID(result);
+ UNREACHABLE(); // Dart_ThrowException only returns if it gets an error.
+ return false;
+ }
+ return true;
+}
+
+
+TEST_CASE(IsolateInterrupt) {
+ Dart_IsolateInterruptCallback saved = Isolate::InterruptCallback();
+ Isolate::SetInterruptCallback(IsolateInterruptTestCallback);
+
+ sync = new Monitor();
siva 2011/12/17 00:05:38 Where is 'sync' deleted? Should be done at the end
+ Thread* thread = new Thread(BusyLoop_start, 0);
+ EXPECT(thread != NULL);
+
+ {
+ MonitorLocker ml(sync);
+ // Wait for the other isolate to start.
+ while (shared_isolate == NULL) {
+ ml.Wait();
+ }
+ }
+
+ // Send three interrupts to the other isolate. The first two allow
+ // execution to continue. The third causes an exception in the
+ // isolate.
+ Dart_InterruptIsolate(shared_isolate);
+ OS::Sleep(5);
+ Dart_InterruptIsolate(shared_isolate);
+ OS::Sleep(5);
siva 2011/12/17 00:05:38 These sleeps make the test a little non determinis
+ Dart_InterruptIsolate(shared_isolate);
+
+ {
+ MonitorLocker ml(sync);
+ // Wait for our isolate to finish.
+ while (shared_isolate != NULL) {
+ ml.Wait();
+ }
+ }
+
+ // We should have received 3 interrupts.
+ EXPECT_EQ(3, interrupt_count);
+
+ // Give the spawned thread enough time to properly exit.
+ OS::Sleep(20);
siva 2011/12/17 00:05:38 Why is this sleep necessary, won't the other threa
+ Isolate::SetInterruptCallback(saved);
+}
+
#endif // TARGET_ARCH_IA32.
} // namespace dart

Powered by Google App Engine
This is Rietveld 408576698