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

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 2291)
+++ 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"
@@ -431,7 +432,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;
@@ -2770,6 +2771,126 @@
RunLoopTest(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 throwException() {\n"
Ivan Posva 2011/12/14 23:59:50 This does not really throw the exception, how abou
turnidge 2011/12/15 21:30:07 Removed.
+ " return new Exception('foo');\n"
+ "}\n"
+ "\n"
+ "void function([foo='hi']) {\n"
+ "}\n"
+ "\n"
+ "void main() {\n"
+ " while (true) {\n" // Infinite loop.
+ " function();\n"
+ " }\n"
+ "}\n";
+
+ 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);
+ Dart_Handle lib = Dart_LoadScript(url, source, TestCase::library_handler);
+ EXPECT_VALID(lib);
+
+ // Tell the other thread that shared_isolate is created.
+ {
+ MonitorLocker ml(sync);
+ ml.Notify();
+ }
+
+ 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:\nException: foo\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_InvokeStatic(lib,
+ Dart_NewString(""),
+ Dart_NewString("throwException"),
+ 0,
+ NULL);
+ EXPECT_VALID(exc);
+ Dart_Handle result = Dart_ThrowException(exc);
Ivan Posva 2011/12/14 23:59:50 You could also throw a string here. That way you d
turnidge 2011/12/15 21:30:07 Done.
+ 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();
+ Thread* thread = new Thread(BusyLoop_start, 0);
+ EXPECT(thread != NULL);
+
+ // Wait for the other isolate to start.
+ while (shared_isolate == NULL) {
+ MonitorLocker ml(sync);
Ivan Posva 2011/12/14 23:59:50 This locking here is strange.
turnidge 2011/12/15 21:30:07 Fixed.
+ ml.Wait(5);
+ }
+
+ // 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);
+ Dart_InterruptIsolate(shared_isolate);
+
+ // Wait for our isolate to finish.
+ while (shared_isolate != NULL) {
+ MonitorLocker ml(sync);
+ ml.Wait(5);
+ }
+
+ // We should have received 3 interrupts.
+ EXPECT_EQ(3, interrupt_count);
+
+ // Give the spawned thread enough time to properly exit.
+ OS::Sleep(20);
+ Isolate::SetInterruptCallback(saved);
+}
+
#endif // TARGET_ARCH_IA32.
} // namespace dart

Powered by Google App Engine
This is Rietveld 408576698