| Index: src/debug.cc
|
| diff --git a/src/debug.cc b/src/debug.cc
|
| index 9a02355f1b2c1a56c74e0cdccdd5dea76da15c19..34b3a6d5ade317e08b2a820c0156313474f48a68 100644
|
| --- a/src/debug.cc
|
| +++ b/src/debug.cc
|
| @@ -1761,8 +1761,10 @@ bool Debugger::never_unload_debugger_ = false;
|
| v8::Debug::MessageHandler2 Debugger::message_handler_ = NULL;
|
| bool Debugger::debugger_unload_pending_ = false;
|
| v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL;
|
| +Mutex* Debugger::dispatch_handler_access_ = OS::CreateMutex();
|
| v8::Debug::DebugMessageDispatchHandler
|
| Debugger::debug_message_dispatch_handler_ = NULL;
|
| +MessageDispatchHelperThread* Debugger::message_dispatch_helper_thread_ = NULL;
|
| int Debugger::host_dispatch_micros_ = 100 * 1000;
|
| DebuggerAgent* Debugger::agent_ = NULL;
|
| LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize);
|
| @@ -2399,8 +2401,14 @@ void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler,
|
|
|
|
|
| void Debugger::SetDebugMessageDispatchHandler(
|
| - v8::Debug::DebugMessageDispatchHandler handler) {
|
| + v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) {
|
| + ScopedLock with(dispatch_handler_access_);
|
| debug_message_dispatch_handler_ = handler;
|
| +
|
| + if (provide_locker && message_dispatch_helper_thread_ == NULL) {
|
| + message_dispatch_helper_thread_ = new MessageDispatchHelperThread;
|
| + message_dispatch_helper_thread_->Start();
|
| + }
|
| }
|
|
|
|
|
| @@ -2435,8 +2443,16 @@ void Debugger::ProcessCommand(Vector<const uint16_t> command,
|
| StackGuard::DebugCommand();
|
| }
|
|
|
| - if (Debugger::debug_message_dispatch_handler_ != NULL) {
|
| - Debugger::debug_message_dispatch_handler_();
|
| + MessageDispatchHelperThread* dispatch_thread;
|
| + {
|
| + ScopedLock with(dispatch_handler_access_);
|
| + dispatch_thread = message_dispatch_helper_thread_;
|
| + }
|
| +
|
| + if (dispatch_thread == NULL) {
|
| + CallMessageDispatchHandler();
|
| + } else {
|
| + dispatch_thread->Schedule();
|
| }
|
| }
|
|
|
| @@ -2523,6 +2539,19 @@ void Debugger::WaitForAgent() {
|
| agent_->WaitUntilListening();
|
| }
|
|
|
| +
|
| +void Debugger::CallMessageDispatchHandler() {
|
| + v8::Debug::DebugMessageDispatchHandler handler;
|
| + {
|
| + ScopedLock with(dispatch_handler_access_);
|
| + handler = Debugger::debug_message_dispatch_handler_;
|
| + }
|
| + if (handler != NULL) {
|
| + handler();
|
| + }
|
| +}
|
| +
|
| +
|
| MessageImpl MessageImpl::NewEvent(DebugEvent event,
|
| bool running,
|
| Handle<JSObject> exec_state,
|
| @@ -2743,6 +2772,45 @@ void LockingCommandMessageQueue::Clear() {
|
| queue_.Clear();
|
| }
|
|
|
| +
|
| +MessageDispatchHelperThread::MessageDispatchHelperThread()
|
| + : sem_(OS::CreateSemaphore(0)), mutex_(OS::CreateMutex()),
|
| + already_signalled_(false) {
|
| +}
|
| +
|
| +
|
| +MessageDispatchHelperThread::~MessageDispatchHelperThread() {
|
| + delete mutex_;
|
| + delete sem_;
|
| +}
|
| +
|
| +
|
| +void MessageDispatchHelperThread::Schedule() {
|
| + {
|
| + ScopedLock lock(mutex_);
|
| + if (already_signalled_) {
|
| + return;
|
| + }
|
| + already_signalled_ = true;
|
| + }
|
| + sem_->Signal();
|
| +}
|
| +
|
| +
|
| +void MessageDispatchHelperThread::Run() {
|
| + while (true) {
|
| + sem_->Wait();
|
| + {
|
| + ScopedLock lock(mutex_);
|
| + already_signalled_ = false;
|
| + }
|
| + {
|
| + Locker locker;
|
| + Debugger::CallMessageDispatchHandler();
|
| + }
|
| + }
|
| +}
|
| +
|
| #endif // ENABLE_DEBUGGER_SUPPORT
|
|
|
| } } // namespace v8::internal
|
|
|