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 -~----------~----~----~----~------~----~------~--~---
