Revision: 3326
Author: [email protected]
Date: Wed Nov 18 00:59:28 2009
Log: Add DebugMessageDispatchHandler

A callback on the debugger thread when a message is received. Allows the
embedding application to wake up the main thread in order to handle the
message. Useful when the embedding application is idle and sitting in a
select() call.

Patch by Ryan Dahl <[email protected]>

Review URL: http://codereview.chromium.org/395013

http://code.google.com/p/v8/source/detail?r=3326

Modified:
  /branches/bleeding_edge/include/v8-debug.h
  /branches/bleeding_edge/src/api.cc
  /branches/bleeding_edge/src/debug.cc
  /branches/bleeding_edge/src/debug.h
  /branches/bleeding_edge/test/cctest/test-debug.cc

=======================================
--- /branches/bleeding_edge/include/v8-debug.h  Mon Aug 17 07:26:48 2009
+++ /branches/bleeding_edge/include/v8-debug.h  Wed Nov 18 00:59:28 2009
@@ -188,6 +188,11 @@
     */
    typedef void (*HostDispatchHandler)();

+  /**
+   * Callback function for the host to ensure debug messages are processed.
+   */
+  typedef void (*DebugMessageDispatchHandler)();
+
    // Set a C debug event listener.
    static bool SetDebugEventListener(EventCallback that,
                                      Handle<Value> data = Handle<Value>());
@@ -211,6 +216,18 @@
    static void SetHostDispatchHandler(HostDispatchHandler handler,
                                       int period = 100);

+  /**
+   * Register a callback function to be called when a debug message has  
been
+   * received and is ready to be processed. For the debug messages to be
+   * processed V8 needs to be entered, and in certain embedding scenarios  
this
+   * callback can be used to make sure V8 is entered for the debug message  
to
+   * be processed. Note that debug messages will only be processed if  
there is
+   * a V8 break. This can happen automatically by using the option
+   * --debugger-auto-break.
+   */
+  static void SetDebugMessageDispatchHandler(
+      DebugMessageDispatchHandler handler);
+
   /**
    * Run a JavaScript function in the debugger.
    * \param fun the function to call
=======================================
--- /branches/bleeding_edge/src/api.cc  Mon Nov 16 04:08:40 2009
+++ /branches/bleeding_edge/src/api.cc  Wed Nov 18 00:59:28 2009
@@ -3732,6 +3732,14 @@
    ENTER_V8;
    i::Debugger::SetHostDispatchHandler(handler, period);
  }
+
+
+void Debug::SetDebugMessageDispatchHandler(
+    DebugMessageDispatchHandler handler) {
+  EnsureInitialized("v8::Debug::SetDebugMessageDispatchHandler");
+  ENTER_V8;
+  i::Debugger::SetDebugMessageDispatchHandler(handler);
+}


  Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
=======================================
--- /branches/bleeding_edge/src/debug.cc        Wed Nov 11 01:50:06 2009
+++ /branches/bleeding_edge/src/debug.cc        Wed Nov 18 00:59:28 2009
@@ -1759,6 +1759,8 @@
  v8::Debug::MessageHandler2 Debugger::message_handler_ = NULL;
  bool Debugger::debugger_unload_pending_ = false;
  v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
+v8::Debug::DebugMessageDispatchHandler
+    Debugger::debug_message_dispatch_handler_ = NULL;
  int Debugger::host_dispatch_micros_ = 100 * 1000;
  DebuggerAgent* Debugger::agent_ = NULL;
  LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize);
@@ -2397,6 +2399,12 @@
    host_dispatch_handler_ = handler;
    host_dispatch_micros_ = period * 1000;
  }
+
+
+void Debugger::SetDebugMessageDispatchHandler(
+    v8::Debug::DebugMessageDispatchHandler handler) {
+  debug_message_dispatch_handler_ = handler;
+}


  // Calls the registered debug message handler. This callback is part of the
@@ -2429,6 +2437,10 @@
    if (!Debug::InDebugger()) {
      StackGuard::DebugCommand();
    }
+
+  if (Debugger::debug_message_dispatch_handler_ != NULL) {
+    Debugger::debug_message_dispatch_handler_();
+  }
  }


=======================================
--- /branches/bleeding_edge/src/debug.h Wed Nov 11 01:50:06 2009
+++ /branches/bleeding_edge/src/debug.h Wed Nov 18 00:59:28 2009
@@ -629,6 +629,8 @@
    static void SetMessageHandler(v8::Debug::MessageHandler2 handler);
    static void SetHostDispatchHandler(v8::Debug::HostDispatchHandler  
handler,
                                       int period);
+  static void SetDebugMessageDispatchHandler(
+      v8::Debug::DebugMessageDispatchHandler handler);

    // Invoke the message handler function.
    static void InvokeMessageHandler(MessageImpl message);
@@ -689,6 +691,7 @@
    static v8::Debug::MessageHandler2 message_handler_;
    static bool debugger_unload_pending_;  // Was message handler cleared?
    static v8::Debug::HostDispatchHandler host_dispatch_handler_;
+  static v8::Debug::DebugMessageDispatchHandler  
debug_message_dispatch_handler_;
    static int host_dispatch_micros_;

    static DebuggerAgent* agent_;
=======================================
--- /branches/bleeding_edge/test/cctest/test-debug.cc   Mon Nov 16 08:58:09  
2009
+++ /branches/bleeding_edge/test/cctest/test-debug.cc   Wed Nov 18 00:59:28  
2009
@@ -4689,6 +4689,71 @@
    host_dispatch_v8_thread.Join();
    host_dispatch_debugger_thread.Join();
  }
+
+
+/* Test DebugMessageDispatch */
+/* In this test, the V8 thread waits for a message from the debug thread.
+ * The DebugMessageDispatchHandler is executed from the debugger thread
+ * which signals the V8 thread to wake up.
+ */
+
+class DebugMessageDispatchV8Thread : public v8::internal::Thread {
+ public:
+  void Run();
+};
+
+class DebugMessageDispatchDebuggerThread : public v8::internal::Thread {
+ public:
+  void Run();
+};
+
+Barriers* debug_message_dispatch_barriers;
+
+
+static void DebugMessageHandler() {
+  debug_message_dispatch_barriers->semaphore_1->Signal();
+}
+
+
+void DebugMessageDispatchV8Thread::Run() {
+  v8::HandleScope scope;
+  DebugLocalContext env;
+
+  // Setup debug message dispatch handler.
+  v8::Debug::SetDebugMessageDispatchHandler(DebugMessageHandler);
+
+  CompileRun("var y = 1 + 2;\n");
+  debug_message_dispatch_barriers->barrier_1.Wait();
+  debug_message_dispatch_barriers->semaphore_1->Wait();
+  debug_message_dispatch_barriers->barrier_2.Wait();
+}
+
+
+void DebugMessageDispatchDebuggerThread::Run() {
+  debug_message_dispatch_barriers->barrier_1.Wait();
+  SendContinueCommand();
+  debug_message_dispatch_barriers->barrier_2.Wait();
+}
+
+DebugMessageDispatchDebuggerThread debug_message_dispatch_debugger_thread;
+DebugMessageDispatchV8Thread debug_message_dispatch_v8_thread;
+
+
+TEST(DebuggerDebugMessageDispatch) {
+  i::FLAG_debugger_auto_break = true;
+
+  // Create a V8 environment
+  Barriers stack_allocated_debug_message_dispatch_barriers;
+  stack_allocated_debug_message_dispatch_barriers.Initialize();
+  debug_message_dispatch_barriers =
+      &stack_allocated_debug_message_dispatch_barriers;
+
+  debug_message_dispatch_v8_thread.Start();
+  debug_message_dispatch_debugger_thread.Start();
+
+  debug_message_dispatch_v8_thread.Join();
+  debug_message_dispatch_debugger_thread.Join();
+}


  TEST(DebuggerAgent) {

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

Reply via email to