From 64d5660eab5c2e8e4b7f3c8287b6c7a1c07ef968 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 26 Apr 2009 13:59:38 +0000 Subject: [PATCH] Pulled base class AbstractModelLoader out of ModelLoader. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30427 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../gui/main_window/MainWindow.cpp | 9 +- .../model_loader/AbstractModelLoader.cpp | 150 ++++++++++++++++++ .../model_loader/AbstractModelLoader.h | 46 ++++++ src/apps/debuganalyzer/model_loader/Jamfile | 1 + .../model_loader/ModelLoader.cpp | 107 +++---------- .../debuganalyzer/model_loader/ModelLoader.h | 25 ++- 6 files changed, 233 insertions(+), 105 deletions(-) create mode 100644 src/apps/debuganalyzer/model_loader/AbstractModelLoader.cpp create mode 100644 src/apps/debuganalyzer/model_loader/AbstractModelLoader.h diff --git a/src/apps/debuganalyzer/gui/main_window/MainWindow.cpp b/src/apps/debuganalyzer/gui/main_window/MainWindow.cpp index 22fd86aa89..8cca6d98e1 100644 --- a/src/apps/debuganalyzer/gui/main_window/MainWindow.cpp +++ b/src/apps/debuganalyzer/gui/main_window/MainWindow.cpp @@ -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! } diff --git a/src/apps/debuganalyzer/model_loader/AbstractModelLoader.cpp b/src/apps/debuganalyzer/model_loader/AbstractModelLoader.cpp new file mode 100644 index 0000000000..8956375ea3 --- /dev/null +++ b/src/apps/debuganalyzer/model_loader/AbstractModelLoader.cpp @@ -0,0 +1,150 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + +#include "AbstractModelLoader.h" + +#include + +#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 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 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 locker(fLock); + + FinishLoading(success); + NotifyTarget(success); + fLoading = false; + + return B_OK; + +} diff --git a/src/apps/debuganalyzer/model_loader/AbstractModelLoader.h b/src/apps/debuganalyzer/model_loader/AbstractModelLoader.h new file mode 100644 index 0000000000..34241e93c1 --- /dev/null +++ b/src/apps/debuganalyzer/model_loader/AbstractModelLoader.h @@ -0,0 +1,46 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef ABSTRACT_MODEL_LOADER_H +#define ABSTRACT_MODEL_LOADER_H + +#include +#include + + +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 diff --git a/src/apps/debuganalyzer/model_loader/Jamfile b/src/apps/debuganalyzer/model_loader/Jamfile index 7e2c938e0b..29ec0115a3 100644 --- a/src/apps/debuganalyzer/model_loader/Jamfile +++ b/src/apps/debuganalyzer/model_loader/Jamfile @@ -8,5 +8,6 @@ UseHeaders $(HAIKU_DEBUG_ANALYZER_HEADERS) ; MergeObject DebugAnalyzer_model_loader.o : + AbstractModelLoader.cpp ModelLoader.cpp ; diff --git a/src/apps/debuganalyzer/model_loader/ModelLoader.cpp b/src/apps/debuganalyzer/model_loader/ModelLoader.cpp index 8e0402f2c6..d0a5f874bb 100644 --- a/src/apps/debuganalyzer/model_loader/ModelLoader.cpp +++ b/src/apps/debuganalyzer/model_loader/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 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 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 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; } diff --git a/src/apps/debuganalyzer/model_loader/ModelLoader.h b/src/apps/debuganalyzer/model_loader/ModelLoader.h index a7ca085c4f..b4fe2f78ad 100644 --- a/src/apps/debuganalyzer/model_loader/ModelLoader.h +++ b/src/apps/debuganalyzer/model_loader/ModelLoader.h @@ -5,11 +5,9 @@ #ifndef MAIN_MODEL_LOADER_H #define MAIN_MODEL_LOADER_H -#include -#include - #include +#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;