public bool Run() { Report.Debug (DebugFlags.SSE, "{0} managed callback execute: {1}", sse, sse.thread_lock); // // Steal the thread-lock. // if (sse.HasThreadLock) { this.thread_lock = sse.thread_lock; sse.thread_lock = null; this.thread_lock.PopRegisters (inferior); } if (do_execute ()) { sse.PushOperationNoExec (this); return true; } // // If we actually stole the thread-lock, then we must give it back here. // if ((thread_lock != null) && (thread_lock.StopEvent != null)) { sse.ThreadManager.AddPendingEvent (sse, thread_lock.StopEvent); return true; } return false; }
internal override void SuspendUserThread() { if (!ThreadManager.InBackgroundThread) throw new InternalError (); if (HasThreadLock) throw new InternalError ("Recursive thread lock"); Report.Debug (DebugFlags.Threads, "{0} suspend user thread: {1} {2}", this, engine_stopped, current_operation); if (engine_stopped) return; Inferior.ChildEvent stop_event; bool stopped = inferior.Stop (out stop_event); stop_requested = true; if (stop_event != null) { if (ProcessEvent (stop_event)) stop_event = null; } else { OperationInterrupted (); } if (stop_event != null) thread_lock = new ThreadLockData (stopped, stop_event, false); Report.Debug (DebugFlags.Threads, "{0} suspend user thread done: {1} {2} {3}", this, stopped, stop_event, current_operation); }
internal override void ReleaseThreadLock() { if (thread_lock == null) { Report.Debug (DebugFlags.Threads, "{0} thread lock already released!", this); return; } Report.Debug (DebugFlags.Threads, "{0} releasing thread lock: {1} {2} {3}", this, thread_lock, inferior.CurrentFrame, current_operation); thread_lock.PopRegisters (inferior); if (thread_lock.StopEvent != null) manager.AddPendingEvent (this, thread_lock.StopEvent); if (thread_lock.Stopped) engine_stopped = false; thread_lock = null; }
internal override void ResumeUserThread(CommandResult result) { if (!ThreadManager.InBackgroundThread) throw new InternalError (); Report.Debug (DebugFlags.Threads, "{0} resume user thread: {1} {2} {3}", this, engine_stopped, HasThreadLock, thread.ThreadFlags); if (thread_lock != null) { if (thread_lock.PushedRegisters || (thread_lock.StopEvent == null)) throw new InternalError (); manager.AddPendingEvent (this, thread_lock.StopEvent); thread_lock = null; engine_stopped = false; current_operation = new OperationStep (this, StepMode.Run, result); return; } if (!engine_stopped) return; StartOperation (new OperationStep (this, StepMode.Run, result)); }
// <summary> // Interrupt any currently running stepping operation, but don't send // any notifications to the caller. The currently running operation is // automatically resumed when ReleaseThreadLock() is called. // </summary> internal override void AcquireThreadLock() { if (HasThreadLock) throw new InternalError ("Recursive thread lock"); Report.Debug (DebugFlags.Threads, "{0} acquiring thread lock: {1} {2}", this, engine_stopped, current_operation); if (engine_stopped) return; Inferior.ChildEvent stop_event; bool stopped = inferior.Stop (out stop_event); thread_lock = new ThreadLockData (stopped, stop_event, true); Report.Debug (DebugFlags.Threads, "{0} acquiring thread lock #1: {1} {2}", this, stopped, stop_event); if ((stop_event != null) && ((stop_event.Type == Inferior.ChildEventType.CHILD_EXITED) || ((stop_event.Type == Inferior.ChildEventType.CHILD_SIGNALED)))) return; TargetAddress new_rsp = inferior.PushRegisters (); Report.Debug (DebugFlags.Threads, "{0} acquired thread lock: {1} {2} {3} {4} {5}", this, stopped, stop_event, EndStackAddress, new_rsp, inferior.CurrentFrame); if (!EndStackAddress.IsNull) inferior.WriteAddress (EndStackAddress, new_rsp); frame_changed (inferior.CurrentFrame, null); engine_stopped = true; }