Pulled base class AbstractModelLoader out of ModelLoader.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30427 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -62,7 +62,8 @@ MainWindow::MainWindow(DataSource* dataSource)
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
delete fModelLoader;
|
||||
if (fModelLoader != NULL)
|
||||
fModelLoader->Delete();
|
||||
|
||||
if (fModel != NULL)
|
||||
fModel->RemoveReference();
|
||||
@@ -79,7 +80,7 @@ MainWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
printf("MSG_MODEL_LOADED_SUCCESSFULLY\n");
|
||||
Model* model = fModelLoader->DetachModel();
|
||||
delete fModelLoader;
|
||||
fModelLoader->Delete();
|
||||
fModelLoader = NULL;
|
||||
_SetModel(model);
|
||||
model->RemoveReference();
|
||||
@@ -90,7 +91,7 @@ printf("MSG_MODEL_LOADED_SUCCESSFULLY\n");
|
||||
case MSG_MODEL_LOADED_ABORTED:
|
||||
{
|
||||
printf("MSG_MODEL_LOADED_FAILED/MSG_MODEL_LOADED_ABORTED\n");
|
||||
delete fModelLoader;
|
||||
fModelLoader->Delete();
|
||||
fModelLoader = NULL;
|
||||
// TODO: User feedback (in failed case)!
|
||||
break;
|
||||
@@ -128,7 +129,7 @@ MainWindow::Show()
|
||||
|
||||
status_t error = fModelLoader->StartLoading();
|
||||
if (error != B_OK) {
|
||||
delete fModelLoader;
|
||||
fModelLoader->Delete();
|
||||
fModelLoader = NULL;
|
||||
// TODO: User feedback!
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "AbstractModelLoader.h"
|
||||
|
||||
#include <AutoLocker.h>
|
||||
|
||||
#include "MessageCodes.h"
|
||||
|
||||
|
||||
AbstractModelLoader::AbstractModelLoader(const BMessenger& target,
|
||||
void* targetCookie)
|
||||
:
|
||||
fLock("main model loader"),
|
||||
fTarget(target),
|
||||
fTargetCookie(targetCookie),
|
||||
fLoaderThread(-1),
|
||||
fLoading(false),
|
||||
fAborted(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
AbstractModelLoader::~AbstractModelLoader()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AbstractModelLoader::StartLoading()
|
||||
{
|
||||
// check initialization
|
||||
status_t error = fLock.InitCheck();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
AutoLocker<BLocker> locker(fLock);
|
||||
|
||||
if (fLoading)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// prepare for loading
|
||||
error = PrepareForLoading();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// spawn the loader thread
|
||||
fLoaderThread = spawn_thread(&_LoaderEntry, "model loader",
|
||||
B_NORMAL_PRIORITY, this);
|
||||
if (fLoaderThread < 0)
|
||||
return fLoaderThread;
|
||||
|
||||
fLoading = true;
|
||||
fAborted = false;
|
||||
|
||||
resume_thread(fLoaderThread);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AbstractModelLoader::Abort(bool wait)
|
||||
{
|
||||
AutoLocker<BLocker> locker(fLock);
|
||||
|
||||
if (fLoaderThread < 0)
|
||||
return;
|
||||
|
||||
thread_id thread = fLoaderThread;
|
||||
|
||||
if (fLoading)
|
||||
fAborted = true;
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
if (wait)
|
||||
wait_for_thread(thread, NULL);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AbstractModelLoader::Delete()
|
||||
{
|
||||
Abort(true);
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
/*! Called from StartLoading() with the lock held.
|
||||
*/
|
||||
status_t
|
||||
AbstractModelLoader::PrepareForLoading()
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AbstractModelLoader::Load()
|
||||
{
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*! Called after loading Load() is done with the lock held.
|
||||
*/
|
||||
void
|
||||
AbstractModelLoader::FinishLoading(bool success)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AbstractModelLoader::NotifyTarget(bool success)
|
||||
{
|
||||
BMessage message(success
|
||||
? MSG_MODEL_LOADED_SUCCESSFULLY
|
||||
: fAborted ? MSG_MODEL_LOADED_ABORTED : MSG_MODEL_LOADED_FAILED);
|
||||
|
||||
message.AddPointer("loader", this);
|
||||
message.AddPointer("targetCookie", fTargetCookie);
|
||||
fTarget.SendMessage(&message);
|
||||
}
|
||||
|
||||
|
||||
/*static*/ status_t
|
||||
AbstractModelLoader::_LoaderEntry(void* data)
|
||||
{
|
||||
return ((AbstractModelLoader*)data)->_Loader();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AbstractModelLoader::_Loader()
|
||||
{
|
||||
bool success = Load() == B_OK;
|
||||
|
||||
// clean up and notify the target
|
||||
AutoLocker<BLocker> locker(fLock);
|
||||
|
||||
FinishLoading(success);
|
||||
NotifyTarget(success);
|
||||
fLoading = false;
|
||||
|
||||
return B_OK;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ABSTRACT_MODEL_LOADER_H
|
||||
#define ABSTRACT_MODEL_LOADER_H
|
||||
|
||||
#include <Locker.h>
|
||||
#include <Messenger.h>
|
||||
|
||||
|
||||
class AbstractModelLoader {
|
||||
public:
|
||||
AbstractModelLoader(const BMessenger& target,
|
||||
void* targetCookie);
|
||||
|
||||
protected:
|
||||
~AbstractModelLoader();
|
||||
|
||||
public:
|
||||
virtual status_t StartLoading();
|
||||
virtual void Abort(bool wait);
|
||||
virtual void Delete();
|
||||
|
||||
protected:
|
||||
virtual status_t PrepareForLoading();
|
||||
virtual status_t Load();
|
||||
virtual void FinishLoading(bool success);
|
||||
|
||||
void NotifyTarget(bool success);
|
||||
|
||||
private:
|
||||
static status_t _LoaderEntry(void* data);
|
||||
status_t _Loader();
|
||||
|
||||
protected:
|
||||
BLocker fLock;
|
||||
BMessenger fTarget;
|
||||
void* fTargetCookie;
|
||||
thread_id fLoaderThread;
|
||||
bool fLoading;
|
||||
bool fAborted;
|
||||
};
|
||||
|
||||
|
||||
#endif // ABSTRACT_MODEL_LOADER_H
|
||||
@@ -8,5 +8,6 @@ UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ;
|
||||
|
||||
MergeObject DebugAnalyzer_model_loader.o
|
||||
:
|
||||
AbstractModelLoader.cpp
|
||||
ModelLoader.cpp
|
||||
;
|
||||
|
||||
@@ -70,80 +70,20 @@ ModelLoader::_UpdateLastEventTime(bigtime_t time)
|
||||
ModelLoader::ModelLoader(DataSource* dataSource,
|
||||
const BMessenger& target, void* targetCookie)
|
||||
:
|
||||
fLock("main model loader"),
|
||||
AbstractModelLoader(target, targetCookie),
|
||||
fModel(NULL),
|
||||
fDataSource(dataSource),
|
||||
fTarget(target),
|
||||
fTargetCookie(targetCookie),
|
||||
fLoaderThread(-1),
|
||||
fLoading(false),
|
||||
fAborted(false)
|
||||
fDataSource(dataSource)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ModelLoader::~ModelLoader()
|
||||
{
|
||||
Abort(true);
|
||||
|
||||
delete fDataSource;
|
||||
delete fModel;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ModelLoader::StartLoading()
|
||||
{
|
||||
// check initialization
|
||||
status_t error = fLock.InitCheck();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
AutoLocker<BLocker> locker(fLock);
|
||||
|
||||
if (fModel != NULL || fLoading || fDataSource == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// init the hash tables
|
||||
error = fThreads.Init();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// spawn the loader thread
|
||||
fLoaderThread = spawn_thread(&_LoaderEntry, "main model loader",
|
||||
B_NORMAL_PRIORITY, this);
|
||||
if (fLoaderThread < 0)
|
||||
return fLoaderThread;
|
||||
|
||||
fLoading = true;
|
||||
fAborted = false;
|
||||
|
||||
resume_thread(fLoaderThread);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModelLoader::Abort(bool wait)
|
||||
{
|
||||
AutoLocker<BLocker> locker(fLock);
|
||||
|
||||
if (fLoaderThread < 0)
|
||||
return;
|
||||
|
||||
thread_id thread = fLoaderThread;
|
||||
|
||||
if (fLoading)
|
||||
fAborted = true;
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
if (wait)
|
||||
wait_for_thread(thread, NULL);
|
||||
}
|
||||
|
||||
|
||||
Model*
|
||||
ModelLoader::DetachModel()
|
||||
{
|
||||
@@ -159,26 +99,35 @@ ModelLoader::DetachModel()
|
||||
}
|
||||
|
||||
|
||||
/*static*/ status_t
|
||||
ModelLoader::_LoaderEntry(void* data)
|
||||
status_t
|
||||
ModelLoader::PrepareForLoading()
|
||||
{
|
||||
return ((ModelLoader*)data)->_Loader();
|
||||
if (fModel != NULL || fDataSource == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// init the hash tables
|
||||
status_t error = fThreads.Init();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ModelLoader::_Loader()
|
||||
ModelLoader::Load()
|
||||
{
|
||||
status_t error;
|
||||
try {
|
||||
error = _Load();
|
||||
return _Load();
|
||||
} catch(...) {
|
||||
error = B_ERROR;
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// clean up and notify the target
|
||||
AutoLocker<BLocker> locker(fLock);
|
||||
|
||||
void
|
||||
ModelLoader::FinishLoading(bool success)
|
||||
{
|
||||
ThreadInfo* threadInfo = fThreads.Clear(true);
|
||||
while (threadInfo != NULL) {
|
||||
ThreadInfo* nextInfo = threadInfo->fNext;
|
||||
@@ -186,24 +135,10 @@ ModelLoader::_Loader()
|
||||
threadInfo = nextInfo;
|
||||
}
|
||||
|
||||
BMessage message;
|
||||
if (error == B_OK) {
|
||||
message.what = MSG_MODEL_LOADED_SUCCESSFULLY;
|
||||
} else {
|
||||
if (!success) {
|
||||
delete fModel;
|
||||
fModel = NULL;
|
||||
|
||||
message.what = fAborted
|
||||
? MSG_MODEL_LOADED_ABORTED : MSG_MODEL_LOADED_FAILED;
|
||||
}
|
||||
|
||||
message.AddPointer("loader", this);
|
||||
message.AddPointer("targetCookie", fTargetCookie);
|
||||
fTarget.SendMessage(&message);
|
||||
|
||||
fLoading = false;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
#ifndef MAIN_MODEL_LOADER_H
|
||||
#define MAIN_MODEL_LOADER_H
|
||||
|
||||
#include <Locker.h>
|
||||
#include <Messenger.h>
|
||||
|
||||
#include <util/OpenHashTable.h>
|
||||
|
||||
#include "AbstractModelLoader.h"
|
||||
#include "Model.h"
|
||||
|
||||
|
||||
@@ -19,18 +17,23 @@ class DataSource;
|
||||
struct system_profiler_thread_added;
|
||||
|
||||
|
||||
class ModelLoader {
|
||||
class ModelLoader : public AbstractModelLoader {
|
||||
public:
|
||||
ModelLoader(DataSource* dataSource,
|
||||
const BMessenger& target,
|
||||
void* targetCookie);
|
||||
|
||||
protected:
|
||||
~ModelLoader();
|
||||
|
||||
status_t StartLoading();
|
||||
void Abort(bool wait);
|
||||
|
||||
public:
|
||||
Model* DetachModel();
|
||||
|
||||
protected:
|
||||
virtual status_t PrepareForLoading();
|
||||
virtual status_t Load();
|
||||
virtual void FinishLoading(bool success);
|
||||
|
||||
private:
|
||||
enum ScheduleState {
|
||||
RUNNING,
|
||||
@@ -78,8 +81,6 @@ private:
|
||||
thread_removed_from_run_queue;
|
||||
|
||||
private:
|
||||
static status_t _LoaderEntry(void* data);
|
||||
status_t _Loader();
|
||||
status_t _Load();
|
||||
status_t _ReadDebugEvents(void** _eventData,
|
||||
size_t* _size);
|
||||
@@ -112,14 +113,8 @@ private:
|
||||
uint32 type, addr_t object);
|
||||
|
||||
private:
|
||||
BLocker fLock;
|
||||
Model* fModel;
|
||||
DataSource* fDataSource;
|
||||
BMessenger fTarget;
|
||||
void* fTargetCookie;
|
||||
thread_id fLoaderThread;
|
||||
bool fLoading;
|
||||
bool fAborted;
|
||||
bigtime_t fBaseTime;
|
||||
bigtime_t fLastEventTime;
|
||||
ThreadTable fThreads;
|
||||
|
||||
Reference in New Issue
Block a user