Debugger: Cleanups and improvements for status notification.
Worker/Job: - Add job listener hooks for when work actually begins for a job, and when a job is suspended to wait for user input. - Add hook for setting a job description string, and implement in several subclasses. LoadImageDebugInfoJob: - Get rid of ImageDebugInfoJobListener since its functionality can be handled via the more general job wait for user input hook. Refactor accordingly. TeamDebugger: - Adjust to use new job hooks. When a worker job is initiated, we now check if the job has a description, and if so pass it on to the UI to display a notification. DwarfLoadingStateHandler: - Notify the UI when a package download is in progress. With these changes, the status bar now notifies the user if any of the following actions are in flight: 1) Loading/parsing debug information 2) Stack trace retrieval 3) Source code retrieval 4) Downloading a debug info package
This commit is contained in:
parent
4c7fff8044
commit
9d9c74ecdb
@ -13,6 +13,7 @@
|
|||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
|
#include <InterfaceDefs.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <StringList.h>
|
#include <StringList.h>
|
||||||
|
|
||||||
@ -1369,6 +1370,17 @@ TeamDebugger::UserInterfaceQuitRequested(QuitOption quitOption)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamDebugger::JobStarted(Job* job)
|
||||||
|
{
|
||||||
|
BString description(job->GetDescription());
|
||||||
|
if (!description.IsEmpty()) {
|
||||||
|
description.Append(B_UTF8_ELLIPSIS);
|
||||||
|
fUserInterface->NotifyBackgroundWorkStatus(description.String());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TeamDebugger::JobDone(Job* job)
|
TeamDebugger::JobDone(Job* job)
|
||||||
{
|
{
|
||||||
@ -1377,6 +1389,21 @@ TeamDebugger::JobDone(Job* job)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TeamDebugger::JobWaitingForInput(Job* job)
|
||||||
|
{
|
||||||
|
LoadImageDebugInfoJob* infoJob = dynamic_cast<LoadImageDebugInfoJob*>(job);
|
||||||
|
|
||||||
|
if (infoJob == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
BMessage message(MSG_DEBUG_INFO_NEEDS_USER_INPUT);
|
||||||
|
message.AddPointer("job", infoJob);
|
||||||
|
message.AddPointer("state", infoJob->GetLoadingState());
|
||||||
|
PostMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TeamDebugger::JobFailed(Job* job)
|
TeamDebugger::JobFailed(Job* job)
|
||||||
{
|
{
|
||||||
@ -1396,30 +1423,6 @@ TeamDebugger::JobAborted(Job* job)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TeamDebugger::ImageDebugInfoJobNeedsUserInput(Job* job,
|
|
||||||
ImageDebugInfoLoadingState* state)
|
|
||||||
{
|
|
||||||
TRACE_JOBS("TeamDebugger::DebugInfoJobNeedsUserInput(%p, %p)\n",
|
|
||||||
job, state);
|
|
||||||
|
|
||||||
BMessage message(MSG_DEBUG_INFO_NEEDS_USER_INPUT);
|
|
||||||
message.AddPointer("job", job);
|
|
||||||
message.AddPointer("state", state);
|
|
||||||
PostMessage(&message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TeamDebugger::ImageDebugInfoJobInProgress(Image* image)
|
|
||||||
{
|
|
||||||
BString message;
|
|
||||||
message.SetToFormat("Loading debug information for %s...",
|
|
||||||
image->Name().String());
|
|
||||||
fUserInterface->NotifyBackgroundWorkStatus(message.String());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TeamDebugger::ThreadStateChanged(const ::Team::ThreadEvent& event)
|
TeamDebugger::ThreadStateChanged(const ::Team::ThreadEvent& event)
|
||||||
{
|
{
|
||||||
|
@ -32,8 +32,7 @@ class WatchpointManager;
|
|||||||
|
|
||||||
|
|
||||||
class TeamDebugger : public BLooper, private UserInterfaceListener,
|
class TeamDebugger : public BLooper, private UserInterfaceListener,
|
||||||
private JobListener, private ImageDebugInfoJobListener,
|
private JobListener, private Team::Listener {
|
||||||
private Team::Listener {
|
|
||||||
public:
|
public:
|
||||||
class Listener;
|
class Listener;
|
||||||
|
|
||||||
@ -134,14 +133,12 @@ private:
|
|||||||
QuitOption quitOption);
|
QuitOption quitOption);
|
||||||
|
|
||||||
// JobListener
|
// JobListener
|
||||||
|
virtual void JobStarted(Job* job);
|
||||||
virtual void JobDone(Job* job);
|
virtual void JobDone(Job* job);
|
||||||
|
virtual void JobWaitingForInput(Job* job);
|
||||||
virtual void JobFailed(Job* job);
|
virtual void JobFailed(Job* job);
|
||||||
virtual void JobAborted(Job* job);
|
virtual void JobAborted(Job* job);
|
||||||
|
|
||||||
virtual void ImageDebugInfoJobNeedsUserInput(Job* job,
|
|
||||||
ImageDebugInfoLoadingState* state);
|
|
||||||
virtual void ImageDebugInfoJobInProgress(Image* image);
|
|
||||||
|
|
||||||
// Team::Listener
|
// Team::Listener
|
||||||
virtual void ThreadStateChanged(
|
virtual void ThreadStateChanged(
|
||||||
const ::Team::ThreadEvent& event);
|
const ::Team::ThreadEvent& event);
|
||||||
|
@ -76,14 +76,13 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
ThreadHandler::ThreadHandler(Thread* thread, Worker* worker,
|
ThreadHandler::ThreadHandler(Thread* thread, Worker* worker,
|
||||||
DebuggerInterface* debuggerInterface,
|
DebuggerInterface* debuggerInterface, JobListener* jobListener,
|
||||||
ImageDebugInfoJobListener* listener,
|
|
||||||
BreakpointManager* breakpointManager)
|
BreakpointManager* breakpointManager)
|
||||||
:
|
:
|
||||||
fThread(thread),
|
fThread(thread),
|
||||||
fWorker(worker),
|
fWorker(worker),
|
||||||
fDebuggerInterface(debuggerInterface),
|
fDebuggerInterface(debuggerInterface),
|
||||||
fDebugInfoJobListener(listener),
|
fJobListener(jobListener),
|
||||||
fBreakpointManager(breakpointManager),
|
fBreakpointManager(breakpointManager),
|
||||||
fStepMode(STEP_NONE),
|
fStepMode(STEP_NONE),
|
||||||
fStepStatement(NULL),
|
fStepStatement(NULL),
|
||||||
@ -113,7 +112,7 @@ void
|
|||||||
ThreadHandler::Init()
|
ThreadHandler::Init()
|
||||||
{
|
{
|
||||||
fWorker->ScheduleJob(new(std::nothrow) GetThreadStateJob(fDebuggerInterface,
|
fWorker->ScheduleJob(new(std::nothrow) GetThreadStateJob(fDebuggerInterface,
|
||||||
fThread));
|
fThread), fJobListener);
|
||||||
fConditionWaitSem = create_sem(0, "breakpoint condition waiter");
|
fConditionWaitSem = create_sem(0, "breakpoint condition waiter");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,7 +457,8 @@ ThreadHandler::HandleThreadStateChanged()
|
|||||||
if (fThread->State() == THREAD_STATE_STOPPED
|
if (fThread->State() == THREAD_STATE_STOPPED
|
||||||
&& fThread->GetCpuState() == NULL) {
|
&& fThread->GetCpuState() == NULL) {
|
||||||
fWorker->ScheduleJob(
|
fWorker->ScheduleJob(
|
||||||
new(std::nothrow) GetCpuStateJob(fDebuggerInterface, fThread));
|
new(std::nothrow) GetCpuStateJob(fDebuggerInterface, fThread),
|
||||||
|
fJobListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,8 +475,8 @@ ThreadHandler::HandleCpuStateChanged()
|
|||||||
if (fThread->GetCpuState() != NULL && fThread->GetStackTrace() == NULL) {
|
if (fThread->GetCpuState() != NULL && fThread->GetStackTrace() == NULL) {
|
||||||
fWorker->ScheduleJob(
|
fWorker->ScheduleJob(
|
||||||
new(std::nothrow) GetStackTraceJob(fDebuggerInterface,
|
new(std::nothrow) GetStackTraceJob(fDebuggerInterface,
|
||||||
fDebugInfoJobListener, fDebuggerInterface->GetArchitecture(),
|
fJobListener, fDebuggerInterface->GetArchitecture(),
|
||||||
fThread));
|
fThread), fJobListener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,7 +954,8 @@ ThreadHandler::_HandleBreakpointConditionIfNeeded(CpuState* cpuState)
|
|||||||
|
|
||||||
status_t error = fWorker->ScheduleJob(
|
status_t error = fWorker->ScheduleJob(
|
||||||
new(std::nothrow) ExpressionEvaluationJob(fThread->GetTeam(),
|
new(std::nothrow) ExpressionEvaluationJob(fThread->GetTeam(),
|
||||||
fDebuggerInterface, language, expressionInfo, frame, fThread));
|
fDebuggerInterface, language, expressionInfo, frame, fThread),
|
||||||
|
fJobListener);
|
||||||
|
|
||||||
BPrivate::ObjectDeleter<ExpressionEvaluationListener> deleter(
|
BPrivate::ObjectDeleter<ExpressionEvaluationListener> deleter(
|
||||||
listener);
|
listener);
|
||||||
|
@ -20,6 +20,7 @@ class BreakpointManager;
|
|||||||
class DebuggerInterface;
|
class DebuggerInterface;
|
||||||
class ExpressionResult;
|
class ExpressionResult;
|
||||||
class ImageDebugInfoJobListener;
|
class ImageDebugInfoJobListener;
|
||||||
|
class JobListener;
|
||||||
class StackFrame;
|
class StackFrame;
|
||||||
class Statement;
|
class Statement;
|
||||||
class Worker;
|
class Worker;
|
||||||
@ -30,7 +31,7 @@ class ThreadHandler : public BReferenceable, private ImageDebugInfoProvider,
|
|||||||
public:
|
public:
|
||||||
ThreadHandler(Thread* thread, Worker* worker,
|
ThreadHandler(Thread* thread, Worker* worker,
|
||||||
DebuggerInterface* debuggerInterface,
|
DebuggerInterface* debuggerInterface,
|
||||||
ImageDebugInfoJobListener* listener,
|
JobListener* listener,
|
||||||
BreakpointManager* breakpointManager);
|
BreakpointManager* breakpointManager);
|
||||||
~ThreadHandler();
|
~ThreadHandler();
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ private:
|
|||||||
Thread* fThread;
|
Thread* fThread;
|
||||||
Worker* fWorker;
|
Worker* fWorker;
|
||||||
DebuggerInterface* fDebuggerInterface;
|
DebuggerInterface* fDebuggerInterface;
|
||||||
ImageDebugInfoJobListener* fDebugInfoJobListener;
|
JobListener* fJobListener;
|
||||||
BreakpointManager* fBreakpointManager;
|
BreakpointManager* fBreakpointManager;
|
||||||
uint32 fStepMode;
|
uint32 fStepMode;
|
||||||
Statement* fStepStatement;
|
Statement* fStepStatement;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
|
#include <InterfaceDefs.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <package/solver/Solver.h>
|
#include <package/solver/Solver.h>
|
||||||
#include <package/solver/SolverPackage.h>
|
#include <package/solver/SolverPackage.h>
|
||||||
@ -108,6 +109,10 @@ DwarfLoadingStateHandler::HandleState(
|
|||||||
BString command;
|
BString command;
|
||||||
command.SetToFormat("/bin/pkgman install -y %s",
|
command.SetToFormat("/bin/pkgman install -y %s",
|
||||||
requiredPackage.String());
|
requiredPackage.String());
|
||||||
|
BString notification;
|
||||||
|
notification.SetToFormat("Installing package %s" B_UTF8_ELLIPSIS,
|
||||||
|
requiredPackage.String());
|
||||||
|
interface->NotifyBackgroundWorkStatus(notification);
|
||||||
int error = system(command.String());
|
int error = system(command.String());
|
||||||
if (interface->IsInteractive()) {
|
if (interface->IsInteractive()) {
|
||||||
if (WIFEXITED(error)) {
|
if (WIFEXITED(error)) {
|
||||||
|
@ -18,12 +18,11 @@
|
|||||||
|
|
||||||
|
|
||||||
GetStackTraceJob::GetStackTraceJob(DebuggerInterface* debuggerInterface,
|
GetStackTraceJob::GetStackTraceJob(DebuggerInterface* debuggerInterface,
|
||||||
ImageDebugInfoJobListener* listener, Architecture* architecture,
|
JobListener* listener, Architecture* architecture, Thread* thread)
|
||||||
Thread* thread)
|
|
||||||
:
|
:
|
||||||
fKey(thread, JOB_TYPE_GET_STACK_TRACE),
|
fKey(thread, JOB_TYPE_GET_STACK_TRACE),
|
||||||
fDebuggerInterface(debuggerInterface),
|
fDebuggerInterface(debuggerInterface),
|
||||||
fDebugInfoJobListener(listener),
|
fJobListener(listener),
|
||||||
fArchitecture(architecture),
|
fArchitecture(architecture),
|
||||||
fThread(thread)
|
fThread(thread)
|
||||||
{
|
{
|
||||||
@ -32,6 +31,9 @@ GetStackTraceJob::GetStackTraceJob(DebuggerInterface* debuggerInterface,
|
|||||||
fCpuState = fThread->GetCpuState();
|
fCpuState = fThread->GetCpuState();
|
||||||
if (fCpuState != NULL)
|
if (fCpuState != NULL)
|
||||||
fCpuState->AcquireReference();
|
fCpuState->AcquireReference();
|
||||||
|
|
||||||
|
|
||||||
|
SetDescription("Retrieving stack trace for thread %" B_PRId32, fThread->ID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -84,7 +86,7 @@ GetStackTraceJob::GetImageDebugInfo(Image* image, ImageDebugInfo*& _info)
|
|||||||
// schedule a job, if not loaded
|
// schedule a job, if not loaded
|
||||||
ImageDebugInfo* info;
|
ImageDebugInfo* info;
|
||||||
status_t error = LoadImageDebugInfoJob::ScheduleIfNecessary(GetWorker(),
|
status_t error = LoadImageDebugInfoJob::ScheduleIfNecessary(GetWorker(),
|
||||||
image, fDebugInfoJobListener, &info);
|
image, fJobListener, &info);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -92,20 +92,11 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ImageDebugInfoJobListener {
|
|
||||||
public:
|
|
||||||
virtual ~ImageDebugInfoJobListener();
|
|
||||||
virtual void ImageDebugInfoJobNeedsUserInput(Job* job,
|
|
||||||
ImageDebugInfoLoadingState* state);
|
|
||||||
virtual void ImageDebugInfoJobInProgress(Image* image);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class GetStackTraceJob : public Job, private ImageDebugInfoProvider {
|
class GetStackTraceJob : public Job, private ImageDebugInfoProvider {
|
||||||
public:
|
public:
|
||||||
GetStackTraceJob(
|
GetStackTraceJob(
|
||||||
DebuggerInterface* debuggerInterface,
|
DebuggerInterface* debuggerInterface,
|
||||||
ImageDebugInfoJobListener* listener,
|
JobListener* jobListener,
|
||||||
Architecture* architecture, Thread* thread);
|
Architecture* architecture, Thread* thread);
|
||||||
virtual ~GetStackTraceJob();
|
virtual ~GetStackTraceJob();
|
||||||
|
|
||||||
@ -120,7 +111,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
SimpleJobKey fKey;
|
SimpleJobKey fKey;
|
||||||
DebuggerInterface* fDebuggerInterface;
|
DebuggerInterface* fDebuggerInterface;
|
||||||
ImageDebugInfoJobListener* fDebugInfoJobListener;
|
JobListener* fJobListener;
|
||||||
Architecture* fArchitecture;
|
Architecture* fArchitecture;
|
||||||
Thread* fThread;
|
Thread* fThread;
|
||||||
CpuState* fCpuState;
|
CpuState* fCpuState;
|
||||||
@ -129,8 +120,7 @@ private:
|
|||||||
|
|
||||||
class LoadImageDebugInfoJob : public Job {
|
class LoadImageDebugInfoJob : public Job {
|
||||||
public:
|
public:
|
||||||
LoadImageDebugInfoJob(Image* image,
|
LoadImageDebugInfoJob(Image* image);
|
||||||
ImageDebugInfoJobListener* listener);
|
|
||||||
virtual ~LoadImageDebugInfoJob();
|
virtual ~LoadImageDebugInfoJob();
|
||||||
|
|
||||||
virtual const JobKey& Key() const;
|
virtual const JobKey& Key() const;
|
||||||
@ -138,7 +128,7 @@ public:
|
|||||||
|
|
||||||
static status_t ScheduleIfNecessary(Worker* worker,
|
static status_t ScheduleIfNecessary(Worker* worker,
|
||||||
Image* image,
|
Image* image,
|
||||||
ImageDebugInfoJobListener* listener,
|
JobListener* jobListener,
|
||||||
ImageDebugInfo** _imageDebugInfo = NULL);
|
ImageDebugInfo** _imageDebugInfo = NULL);
|
||||||
// If already loaded returns a
|
// If already loaded returns a
|
||||||
// reference, if desired. If not loaded
|
// reference, if desired. If not loaded
|
||||||
@ -147,19 +137,16 @@ public:
|
|||||||
// if scheduling the job failed, or the
|
// if scheduling the job failed, or the
|
||||||
// debug info already failed to load
|
// debug info already failed to load
|
||||||
// earlier.
|
// earlier.
|
||||||
private:
|
|
||||||
void NotifyUserInputListener();
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef BObjectList<ImageDebugInfoJobListener> ListenerList;
|
|
||||||
|
|
||||||
|
ImageDebugInfoLoadingState*
|
||||||
|
GetLoadingState()
|
||||||
|
{ return &fState; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SimpleJobKey fKey;
|
SimpleJobKey fKey;
|
||||||
Image* fImage;
|
Image* fImage;
|
||||||
ImageDebugInfoLoadingState
|
ImageDebugInfoLoadingState
|
||||||
fState;
|
fState;
|
||||||
ImageDebugInfoJobListener* fListener;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,39 +14,19 @@
|
|||||||
#include "Team.h"
|
#include "Team.h"
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - ImageDebugInfoJobListener
|
|
||||||
|
|
||||||
|
|
||||||
ImageDebugInfoJobListener::~ImageDebugInfoJobListener()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ImageDebugInfoJobListener::ImageDebugInfoJobNeedsUserInput(Job* job,
|
|
||||||
ImageDebugInfoLoadingState* state)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ImageDebugInfoJobListener::ImageDebugInfoJobInProgress(Image* image)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - LoadImageDebugInfoJob
|
// #pragma mark - LoadImageDebugInfoJob
|
||||||
|
|
||||||
|
|
||||||
LoadImageDebugInfoJob::LoadImageDebugInfoJob(Image* image,
|
LoadImageDebugInfoJob::LoadImageDebugInfoJob(Image* image)
|
||||||
ImageDebugInfoJobListener* listener)
|
|
||||||
:
|
:
|
||||||
fKey(image, JOB_TYPE_LOAD_IMAGE_DEBUG_INFO),
|
fKey(image, JOB_TYPE_LOAD_IMAGE_DEBUG_INFO),
|
||||||
fImage(image),
|
fImage(image),
|
||||||
fState(),
|
fState()
|
||||||
fListener(listener)
|
|
||||||
{
|
{
|
||||||
fImage->AcquireReference();
|
fImage->AcquireReference();
|
||||||
|
|
||||||
|
SetDescription("Loading debugging information for %s",
|
||||||
|
fImage->Name().String());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -71,9 +51,6 @@ LoadImageDebugInfoJob::Do()
|
|||||||
ImageInfo imageInfo(fImage->Info());
|
ImageInfo imageInfo(fImage->Info());
|
||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
|
|
||||||
if (fListener != NULL)
|
|
||||||
fListener->ImageDebugInfoJobInProgress(fImage);
|
|
||||||
|
|
||||||
// create the debug info
|
// create the debug info
|
||||||
ImageDebugInfo* debugInfo;
|
ImageDebugInfo* debugInfo;
|
||||||
status_t error = fImage->GetTeam()->DebugInfo()->LoadImageDebugInfo(
|
status_t error = fImage->GetTeam()->DebugInfo()->LoadImageDebugInfo(
|
||||||
@ -83,7 +60,6 @@ LoadImageDebugInfoJob::Do()
|
|||||||
locker.Lock();
|
locker.Lock();
|
||||||
|
|
||||||
if (fState.UserInputRequired()) {
|
if (fState.UserInputRequired()) {
|
||||||
NotifyUserInputListener();
|
|
||||||
return WaitForUserInput();
|
return WaitForUserInput();
|
||||||
} else if (error == B_OK) {
|
} else if (error == B_OK) {
|
||||||
error = fImage->SetImageDebugInfo(debugInfo, IMAGE_DEBUG_INFO_LOADED);
|
error = fImage->SetImageDebugInfo(debugInfo, IMAGE_DEBUG_INFO_LOADED);
|
||||||
@ -97,7 +73,7 @@ LoadImageDebugInfoJob::Do()
|
|||||||
|
|
||||||
/*static*/ status_t
|
/*static*/ status_t
|
||||||
LoadImageDebugInfoJob::ScheduleIfNecessary(Worker* worker, Image* image,
|
LoadImageDebugInfoJob::ScheduleIfNecessary(Worker* worker, Image* image,
|
||||||
ImageDebugInfoJobListener* listener, ImageDebugInfo** _imageDebugInfo)
|
JobListener* listener, ImageDebugInfo** _imageDebugInfo)
|
||||||
{
|
{
|
||||||
AutoLocker<Team> teamLocker(image->GetTeam());
|
AutoLocker<Team> teamLocker(image->GetTeam());
|
||||||
|
|
||||||
@ -122,12 +98,12 @@ LoadImageDebugInfoJob::ScheduleIfNecessary(Worker* worker, Image* image,
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// schedule a job
|
// schedule a job
|
||||||
LoadImageDebugInfoJob* job = new(std::nothrow) LoadImageDebugInfoJob(image,
|
LoadImageDebugInfoJob* job = new(std::nothrow) LoadImageDebugInfoJob(
|
||||||
listener);
|
image);
|
||||||
if (job == NULL)
|
if (job == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
status_t error = worker->ScheduleJob(job);
|
status_t error = worker->ScheduleJob(job, listener);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
image->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_UNAVAILABLE);
|
image->SetImageDebugInfo(NULL, IMAGE_DEBUG_INFO_UNAVAILABLE);
|
||||||
return error;
|
return error;
|
||||||
@ -139,12 +115,3 @@ LoadImageDebugInfoJob::ScheduleIfNecessary(Worker* worker, Image* image,
|
|||||||
*_imageDebugInfo = NULL;
|
*_imageDebugInfo = NULL;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
LoadImageDebugInfoJob::NotifyUserInputListener()
|
|
||||||
{
|
|
||||||
if (fListener != NULL)
|
|
||||||
fListener->ImageDebugInfoJobNeedsUserInput(this, &fState);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -30,6 +30,9 @@ LoadSourceCodeJob::LoadSourceCodeJob(
|
|||||||
fLoadForFunction(loadForFunction)
|
fLoadForFunction(loadForFunction)
|
||||||
{
|
{
|
||||||
fFunctionInstance->AcquireReference();
|
fFunctionInstance->AcquireReference();
|
||||||
|
|
||||||
|
SetDescription("Loading source code for function %s",
|
||||||
|
fFunctionInstance->PrettyName().String());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -70,12 +70,24 @@ JobListener::~JobListener()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
JobListener::JobStarted(Job* job)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
JobListener::JobDone(Job* job)
|
JobListener::JobDone(Job* job)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
JobListener::JobWaitingForInput(Job* job)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
JobListener::JobFailed(Job* job)
|
JobListener::JobFailed(Job* job)
|
||||||
{
|
{
|
||||||
@ -121,6 +133,15 @@ Job::WaitForUserInput()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Job::SetDescription(const char* format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
fDescription.SetToFormatVarArgs(format, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Job::SetWorker(Worker* worker)
|
Job::SetWorker(Worker* worker)
|
||||||
{
|
{
|
||||||
@ -179,6 +200,13 @@ Job::NotifyListeners()
|
|||||||
for (int32 i = count - 1; i >= 0; i--) {
|
for (int32 i = count - 1; i >= 0; i--) {
|
||||||
JobListener* listener = fListeners.ItemAt(i);
|
JobListener* listener = fListeners.ItemAt(i);
|
||||||
switch (fState) {
|
switch (fState) {
|
||||||
|
case JOB_STATE_ACTIVE:
|
||||||
|
listener->JobStarted(this);
|
||||||
|
break;
|
||||||
|
case JOB_STATE_WAITING:
|
||||||
|
if (fWaitStatus == JOB_USER_INPUT_WAITING)
|
||||||
|
listener->JobWaitingForInput(this);
|
||||||
|
break;
|
||||||
case JOB_STATE_SUCCEEDED:
|
case JOB_STATE_SUCCEEDED:
|
||||||
listener->JobDone(this);
|
listener->JobDone(this);
|
||||||
break;
|
break;
|
||||||
@ -403,6 +431,7 @@ Worker::WaitForUserInput(Job* waitingJob)
|
|||||||
return B_INTERRUPTED;
|
return B_INTERRUPTED;
|
||||||
|
|
||||||
waitingJob->SetWaitStatus(JOB_USER_INPUT_WAITING);
|
waitingJob->SetWaitStatus(JOB_USER_INPUT_WAITING);
|
||||||
|
waitingJob->NotifyListeners();
|
||||||
fSuspendedJobs.Add(waitingJob);
|
fSuspendedJobs.Add(waitingJob);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -459,6 +488,7 @@ Worker::_ProcessJobs()
|
|||||||
// process the next job
|
// process the next job
|
||||||
if (Job* job = fUnscheduledJobs.RemoveHead()) {
|
if (Job* job = fUnscheduledJobs.RemoveHead()) {
|
||||||
job->SetState(JOB_STATE_ACTIVE);
|
job->SetState(JOB_STATE_ACTIVE);
|
||||||
|
job->NotifyListeners();
|
||||||
|
|
||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
status_t error = job->Do();
|
status_t error = job->Do();
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
#include <Referenceable.h>
|
#include <Referenceable.h>
|
||||||
|
#include <String.h>
|
||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
#include <util/OpenHashTable.h>
|
#include <util/OpenHashTable.h>
|
||||||
|
|
||||||
@ -69,7 +70,9 @@ class JobListener {
|
|||||||
public:
|
public:
|
||||||
virtual ~JobListener();
|
virtual ~JobListener();
|
||||||
|
|
||||||
|
virtual void JobStarted(Job* job);
|
||||||
virtual void JobDone(Job* job);
|
virtual void JobDone(Job* job);
|
||||||
|
virtual void JobWaitingForInput(Job* job);
|
||||||
virtual void JobFailed(Job* job);
|
virtual void JobFailed(Job* job);
|
||||||
virtual void JobAborted(Job* job);
|
virtual void JobAborted(Job* job);
|
||||||
};
|
};
|
||||||
@ -89,9 +92,13 @@ public:
|
|||||||
Worker* GetWorker() const { return fWorker; }
|
Worker* GetWorker() const { return fWorker; }
|
||||||
job_state State() const { return fState; }
|
job_state State() const { return fState; }
|
||||||
|
|
||||||
|
const BString& GetDescription() const
|
||||||
|
{ return fDescription; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
job_wait_status WaitFor(const JobKey& key);
|
job_wait_status WaitFor(const JobKey& key);
|
||||||
status_t WaitForUserInput();
|
status_t WaitForUserInput();
|
||||||
|
void SetDescription(const char* format, ...);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Worker;
|
friend class Worker;
|
||||||
@ -122,6 +129,7 @@ private:
|
|||||||
JobList fDependentJobs;
|
JobList fDependentJobs;
|
||||||
job_wait_status fWaitStatus;
|
job_wait_status fWaitStatus;
|
||||||
ListenerList fListeners;
|
ListenerList fListeners;
|
||||||
|
BString fDescription;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Job* fNext;
|
Job* fNext;
|
||||||
|
Loading…
Reference in New Issue
Block a user