text: /*
   * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
   * Copyright 2014-2016, Rene Gollent, rene@gollent.com.
   * Distributed under the terms of the MIT License.
   */
  #ifndef THREAD_HANDLER_H
  #define THREAD_HANDLER_H
  
  
  #include <Referenceable.h>
  #include <util/OpenHashTable.h>
  
  #include <Breakpoint.h>
  #include <ImageDebugInfoProvider.h>
  #include <model/Thread.h>
  
  
  class BreakpointHitEvent;
  class BreakpointManager;
  class DebugEvent;
  class DebuggerCallEvent;
  class DebuggerInterface;
  class ExceptionOccurredEvent;
  class ExpressionResult;
  class ImageDebugInfoJobListener;
  class JobListener;
  class SignalReceivedEvent;
  class SingleStepEvent;
  class StackFrame;
  class Statement;
  class ThreadDebuggedEvent;
  class WatchpointHitEvent;
  class Worker;
  
  
  class ThreadHandler : public BReferenceable, private ImageDebugInfoProvider,
  	private BreakpointClient {
  public:
  								ThreadHandler(::Thread* thread, Worker* worker,
  									DebuggerInterface* debuggerInterface,
  									JobListener* listener,
  									BreakpointManager* breakpointManager);
  								~ThreadHandler();
  
  			void				Init();
  
  			thread_id			ThreadID() const	{ return fThread->ID(); }
  			::Thread*			GetThread() const	{ return fThread; }
  
  			status_t			SetBreakpointAndRun(target_addr_t address);
  									// team lock held
  
  			// All Handle*() methods are invoked in team debugger thread,
  			// looper lock held.
  			bool				HandleThreadDebugged(
  									ThreadDebuggedEvent* event,
  									const BString& stoppedReason = BString());
  			bool				HandleDebuggerCall(
  									DebuggerCallEvent* event);
  			bool				HandleBreakpointHit(
  									BreakpointHitEvent* event);
  			bool				HandleWatchpointHit(
  									WatchpointHitEvent* event);
  			bool				HandleSingleStep(
  									SingleStepEvent* event);
  			bool				HandleExceptionOccurred(
  									ExceptionOccurredEvent* event);
  			bool				HandleSignalReceived(
  									SignalReceivedEvent* event);
  
  			void				HandleThreadAction(uint32 action,
  									target_addr_t address);
  
  			void				HandleThreadStateChanged();
  			void				HandleCpuStateChanged();
  			void				HandleStackTraceChanged();
  
  private:
  			friend class ExpressionEvaluationListener;
  
  private:
  	// ImageDebugInfoProvider
  	virtual	status_t			GetImageDebugInfo(Image* image,
  									ImageDebugInfo*& _info);
  
  			bool				_HandleThreadStopped(CpuState* cpuState,
  									uint32 stoppedReason,
  									const BString& stoppedReasonInfo
  										= BString());
  
  			bool				_HandleSetAddress(CpuState* cpuState,
  									target_addr_t address);
  
  			void				_SetThreadState(uint32 state,
  									CpuState* cpuState, uint32 stoppedReason,
  									const BString& stoppedReasonInfo);
  
  			Statement*			_GetStatementAtInstructionPointer(
  									StackFrame* frame);
  
  			void				_StepFallback();
  			bool				_DoStepOver(CpuState* cpuState);
  
  			status_t			_InstallTemporaryBreakpoint(
  									target_addr_t address);
  			void				_UninstallTemporaryBreakpoint();
  			void				_ClearContinuationState();
  			void				_RunThread(target_addr_t instructionPointer);
  			void				_SingleStepThread(
  									target_addr_t instructionPointer);
  
  			bool				_HandleBreakpointConditionIfNeeded(
  									CpuState* cpuState);
  			void				_HandleBreakpointConditionEvaluated(
  									ExpressionResult* value);
  			bool				_CheckStopCondition();
  
  			bool				_HandleBreakpointHitStep(CpuState* cpuState);
  			bool				_HandleSingleStepStep(CpuState* cpuState);
  
  			bool				_HasExitedFrame(target_addr_t framePointer)
  									const;
  
  private:
  			::Thread*			fThread;
  			Worker*				fWorker;
  			DebuggerInterface*	fDebuggerInterface;
  			JobListener*		fJobListener;
  			BreakpointManager*	fBreakpointManager;
  			uint32				fStepMode;
  			Statement*			fStepStatement;
  			target_addr_t		fBreakpointAddress;
  			target_addr_t		fSteppedOverFunctionAddress;
  			target_addr_t		fPreviousInstructionPointer;
  			target_addr_t		fPreviousFrameAddress;
  			bool				fSingleStepping;
  			sem_id				fConditionWaitSem;
  			ExpressionResult*	fConditionResult;
  
  public:
  			ThreadHandler*		fNext;
  };
  
  
  struct ThreadHandlerHashDefinition {
  	typedef thread_id		KeyType;
  	typedef	ThreadHandler	ValueType;
  
  	size_t HashKey(thread_id key) const
  	{
  		return (size_t)key;
  	}
  
  	size_t Hash(const ThreadHandler* value) const
  	{
  		return HashKey(value->ThreadID());
  	}
  
  	bool Compare(thread_id key, ThreadHandler* value) const
  	{
  		return value->ThreadID() == key;
  	}
  
  	ThreadHandler*& GetLink(ThreadHandler* value) const
  	{
  		return value->fNext;
  	}
  };
  
  typedef BOpenHashTable<ThreadHandlerHashDefinition> ThreadHandlerTable;
  
  
  #endif	// THREAD_HANDLER_H
  