public void ExecuteOnWorkerThreadIfStoppedAndBlock(FPWorker workerFunction) { // We should not be issuing commands while the debuggee is running. if (!IsProcessStopped) { // May deadlock if called when process is running (because worker thread is only // available when process is stopped). // Only the UI thread can Go commands; so the UI thread knows if // the debuggee may be running; and another thread can't change this underneath it. // Protect us. return; } m_fpWorker = workerFunction; // The MDbg main loop's ReadCommand is waiting on this event. m_inputEvent.Set(); // Wait for input to finish // This won't pump. (but we wouldn't mind if it pumped WM_paint) // Thus we must be gauranteed that the worker won't block. m_inputDoneEvent.WaitOne(); }
// Real worker to get commands and feed them back to the MDbg command loop. // This is on the Command-thread. bool ReadCommandWorker(out string command) { while(true) { // If we already have queued up commands, execute them immediately. lock (m_cmdQueue) { if (m_cmdQueue.Count > 0) { command = m_cmdQueue.Dequeue(); return true; } } // Now actually wait until a command is entered. // This is set by either: // - the UI sends the MDbg engine commands (via AsyncProcessEnteredText) // this may come from UI elements (such as menu commands), or from edit input control. // representing the console, or closing the GUI // This may resume the process (eg, "step", "go"). // - Synchronous worker commands (which are not supposed to be able to resume the process). // These worker functions let the UI thread gather information from ICorDebug (since the // STA UI thread can't call the MTA ICorDebug directly) // m_inputEvent.WaitOne(); // Did we get a delegate work item? If yes, we can process it right now. if (m_fpWorker != null) { try { Debug.Assert(m_process != null); m_fpWorker(m_process); } catch { Debug.Assert(false, "Unexpected exception on worker thread."); // rethrow it on original thread? } m_fpWorker = null; m_inputDoneEvent.Set(); continue; // loop around and try again. } } // loop around. }