Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
OpenWalnut
OpenWalnut Core
Commits
e058294f
Commit
e058294f
authored
Jan 18, 2010
by
Sebastian Eichelbaum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[CHANGE] - now the data loading is asynchronous but keeps the order
parent
2074992c
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
285 additions
and
18 deletions
+285
-18
src/common/WThreadedRunner.cpp
src/common/WThreadedRunner.cpp
+7
-0
src/common/WThreadedRunner.h
src/common/WThreadedRunner.h
+12
-1
src/gui/qt4/WQt4Gui.cpp
src/gui/qt4/WQt4Gui.cpp
+1
-1
src/gui/qt4/datasetbrowser/WQtDatasetBrowser.cpp
src/gui/qt4/datasetbrowser/WQtDatasetBrowser.cpp
+2
-2
src/kernel/WBatchLoader.cpp
src/kernel/WBatchLoader.cpp
+72
-0
src/kernel/WBatchLoader.h
src/kernel/WBatchLoader.h
+81
-0
src/kernel/WKernel.cpp
src/kernel/WKernel.cpp
+9
-12
src/kernel/WKernel.h
src/kernel/WKernel.h
+10
-1
src/kernel/WModuleContainer.cpp
src/kernel/WModuleContainer.cpp
+43
-1
src/kernel/WModuleContainer.h
src/kernel/WModuleContainer.h
+48
-0
No files found.
src/common/WThreadedRunner.cpp
View file @
e058294f
...
...
@@ -25,6 +25,7 @@
#include <iostream>
#include "WConditionOneShot.h"
#include "../common/WLogger.h"
#include "WThreadedRunner.h"
...
...
@@ -48,6 +49,11 @@ void WThreadedRunner::run()
m_Thread
=
new
boost
::
thread
(
boost
::
bind
(
&
WThreadedRunner
::
threadMain
,
this
)
);
}
void
WThreadedRunner
::
run
(
THREADFUNCTION
f
)
{
m_Thread
=
new
boost
::
thread
(
f
);
}
void
WThreadedRunner
::
wait
(
bool
requestFinish
)
{
if
(
requestFinish
)
...
...
@@ -69,6 +75,7 @@ void WThreadedRunner::waitForStop()
void
WThreadedRunner
::
threadMain
()
{
WLogger
::
getLogger
()
->
addLogMessage
(
"This should never be called. Implement a thread function here."
,
"WThreadedRunner"
,
LL_WARNING
);
}
void
WThreadedRunner
::
notifyStop
()
...
...
src/common/WThreadedRunner.h
View file @
e058294f
...
...
@@ -27,6 +27,7 @@
#include <boost/thread.hpp>
#include <boost/thread/thread.hpp>
#include <boost/function.hpp>
#include "WFlag.h"
...
...
@@ -37,6 +38,11 @@ class WThreadedRunner
{
public:
/**
* Type used for simple thread functions.
*/
typedef
boost
::
function
<
void
(
void
)
>
THREADFUNCTION
;
/**
* Default constructor.
*/
...
...
@@ -50,7 +56,12 @@ public:
/**
* Run thread.
*/
void
run
();
virtual
void
run
();
/**
* Run thread. This does not start threadMain(() but runs a specified function instead.
*/
void
run
(
THREADFUNCTION
f
);
/**
* Wait for the thread to be finished.
...
...
src/gui/qt4/WQt4Gui.cpp
View file @
e058294f
...
...
@@ -129,7 +129,7 @@ int WQt4Gui::run()
m_mainWindow
=
new
WMainWindow
();
m_mainWindow
->
show
();
// connect out loader signal with krnel
// connect out loader signal with k
e
rnel
getLoadButtonSignal
()
->
connect
(
boost
::
bind
(
&
WKernel
::
loadDataSets
,
m_kernel
,
_1
)
);
m_mainWindow
->
getModuleButtonSignal
()
->
connect
(
boost
::
bind
(
&
WKernel
::
applyModule
,
m_kernel
,
_1
,
_2
)
);
...
...
src/gui/qt4/datasetbrowser/WQtDatasetBrowser.cpp
View file @
e058294f
...
...
@@ -212,7 +212,7 @@ WQtDatasetTreeItem* WQtDatasetBrowser::addDataset( boost::shared_ptr< WModule >
WQtSubjectTreeItem
*
subject
=
(
WQtSubjectTreeItem
*
)
m_treeWidget
->
topLevelItem
(
subjectId
+
1
);
subject
->
setExpanded
(
true
);
WQtDatasetTreeItem
*
item
=
subject
->
addDatasetItem
(
module
);
item
->
setDisabled
(
fals
e
);
item
->
setDisabled
(
tru
e
);
return
item
;
}
...
...
@@ -419,7 +419,7 @@ std::vector< boost::shared_ptr< WDataSet > > WQtDatasetBrowser::getDataSetList(
boost
::
shared_ptr
<
WMData
>
dm
=
boost
::
shared_dynamic_cast
<
WMData
>
(
(
(
WQtDatasetTreeItem
*
)
m_treeWidget
->
invisibleRootItem
()
->
child
(
subjectId
+
1
)
->
child
(
i
)
)
->
getModule
()
);
if
(
!
onlyTextures
||
dm
->
getDataSet
()
->
isTexture
()
)
if
(
dm
->
isReady
()()
&&
(
!
onlyTextures
||
dm
->
getDataSet
()
->
isTexture
()
)
)
{
if
(
dm
->
getProperties
()
->
getValue
<
bool
>
(
"active"
)
)
{
...
...
src/kernel/WBatchLoader.cpp
0 → 100644
View file @
e058294f
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <iostream>
#include "WModuleContainer.h"
#include "WModule.h"
#include "WModuleFactory.h"
#include "WBatchLoader.h"
WBatchLoader
::
WBatchLoader
(
std
::
vector
<
std
::
string
>
fileNames
,
boost
::
shared_ptr
<
WModuleContainer
>
targetContainer
)
:
WThreadedRunner
(),
boost
::
enable_shared_from_this
<
WBatchLoader
>
(),
m_fileNamesToLoad
(
fileNames
),
m_targetContainer
(
targetContainer
)
{
// initialize members
}
WBatchLoader
::~
WBatchLoader
()
{
// cleanup
}
void
WBatchLoader
::
run
()
{
// the module needs to be add here, as it else could be freed before the thread finishes ( remember: it is a shared_ptr).
m_targetContainer
->
addPendingThread
(
shared_from_this
()
);
// actually run
WThreadedRunner
::
run
();
}
void
WBatchLoader
::
threadMain
()
{
// add a new data module for each file to load
for
(
std
::
vector
<
std
::
string
>::
iterator
iter
=
m_fileNamesToLoad
.
begin
();
iter
!=
m_fileNamesToLoad
.
end
();
++
iter
)
{
boost
::
shared_ptr
<
WModule
>
mod
=
WModuleFactory
::
getModuleFactory
()
->
create
(
WModuleFactory
::
getModuleFactory
()
->
getPrototypeByName
(
"Data Module"
)
);
mod
->
getProperties
()
->
setValue
(
"filename"
,
(
*
iter
)
);
m_targetContainer
->
add
(
mod
);
// serialize loading of a couple of data sets
mod
->
isReady
().
wait
();
}
m_targetContainer
->
finishedPendingThread
(
shared_from_this
()
);
}
src/kernel/WBatchLoader.h
0 → 100644
View file @
e058294f
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WBATCHLOADER_H
#define WBATCHLOADER_H
#include <iostream>
#include <boost/shared_ptr.hpp>
#include "../common/WThreadedRunner.h"
class
WModuleContainer
;
/**
* Class for loading many datasets. It runs in a separate thread.
*/
class
WBatchLoader
:
public
WThreadedRunner
,
public
boost
::
enable_shared_from_this
<
WBatchLoader
>
{
public:
/**
* Initializes the batchloader but does not start it. Use run().
*
* \param fileNames the files to load.
*/
WBatchLoader
(
std
::
vector
<
std
::
string
>
fileNames
,
boost
::
shared_ptr
<
WModuleContainer
>
targetContainer
);
/**
* Destructor.
*/
virtual
~
WBatchLoader
();
/**
* Run thread and load the data.
*/
virtual
void
run
();
protected:
/**
* Function that has to be overwritten for execution. It gets executed in a separate thread after run()
* has been called.
*/
virtual
void
threadMain
();
/**
* List of files to load.
*/
std
::
vector
<
std
::
string
>
m_fileNamesToLoad
;
/**
* The container which later will contain the loaded datasets.
*/
boost
::
shared_ptr
<
WModuleContainer
>
m_targetContainer
;
private:
};
#endif // WBATCHLOADER_H
src/kernel/WKernel.cpp
View file @
e058294f
...
...
@@ -39,6 +39,7 @@
#include "WModule.h"
#include "WModuleFactory.h"
#include "WBatchLoader.h"
#include "../common/WException.h"
#include "../common/WCondition.h"
#include "../common/WConditionOneShot.h"
...
...
@@ -147,10 +148,10 @@ void WKernel::threadMain()
{
bool
ignore
;
m_moduleContainer
->
add
(
m_moduleFactory
->
create
(
m_moduleFactory
->
getPrototypeByName
(
"Navigation Slice Module"
)
)
,
true
);
m_moduleContainer
->
add
(
m_moduleFactory
->
create
(
m_moduleFactory
->
getPrototypeByName
(
"Coordinate System Module"
)
)
,
true
);
//
m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "Coordinate System Module" ) ) , true );
if
(
!
(
WPreferences
::
getPreference
(
"modules.standard.ignoreHUD"
,
&
ignore
)
&&
ignore
)
)
{
m_moduleContainer
->
add
(
m_moduleFactory
->
create
(
m_moduleFactory
->
getPrototypeByName
(
"HUD"
)
)
,
true
);
//
m_moduleContainer->add( m_moduleFactory->create( m_moduleFactory->getPrototypeByName( "HUD" ) ) , true );
}
}
...
...
@@ -252,16 +253,12 @@ const WBoolFlag& WKernel::isFinishRequested() const
void
WKernel
::
loadDataSets
(
std
::
vector
<
std
::
string
>
fileNames
)
{
// add a new data module for each file to load
using
boost
::
shared_ptr
;
for
(
std
::
vector
<
std
::
string
>::
iterator
iter
=
fileNames
.
begin
();
iter
!=
fileNames
.
end
();
++
iter
)
{
shared_ptr
<
WModule
>
mod
=
m_moduleFactory
->
create
(
m_moduleFactory
->
getPrototypeByName
(
"Data Module"
)
);
mod
->
getProperties
()
->
setValue
(
"filename"
,
(
*
iter
)
);
m_moduleContainer
->
add
(
mod
);
// serialize loading of a couple of data sets
mod
->
isReady
().
wait
();
}
getRootContainer
()
->
loadDataSets
(
fileNames
);
}
void
WKernel
::
loadDataSetsSynchronously
(
std
::
vector
<
std
::
string
>
fileNames
)
{
getRootContainer
()
->
loadDataSetsSynchronously
(
fileNames
);
}
boost
::
shared_ptr
<
WModule
>
WKernel
::
applyModule
(
boost
::
shared_ptr
<
WModule
>
applyOn
,
boost
::
shared_ptr
<
WModule
>
prototype
)
...
...
src/kernel/WKernel.h
View file @
e058294f
...
...
@@ -34,6 +34,7 @@
#include "WModule.h"
#include "WModuleFactory.h"
#include "WModuleContainer.h"
#include "WBatchLoader.h"
#include "../common/WLogger.h"
#include "../common/WThreadedRunner.h"
#include "../common/WFlag.h"
...
...
@@ -98,13 +99,21 @@ public:
const
WBoolFlag
&
isFinishRequested
()
const
;
/**
* Load specified datasets.
* Load specified datasets.
It immediately returns and starts another thread, which actually loads the data.
*
* \param fileNames list of filenames to load. The registered notification handler for the root container will get notified on
* error and success.
*/
void
loadDataSets
(
std
::
vector
<
std
::
string
>
fileNames
);
/**
* Loads the specified files synchronously.
*
* \param fileNames list of filenames to load. The registered notification handler for the root container will get notified on
* error and success.
*/
void
loadDataSetsSynchronously
(
std
::
vector
<
std
::
string
>
fileNames
);
/**
* Function combines to modules. This is a simple alias for "getRootContainer()->applyModule".
*
...
...
src/kernel/WModuleContainer.cpp
View file @
e058294f
...
...
@@ -32,10 +32,12 @@
#include "exceptions/WModuleAlreadyAssociated.h"
#include "exceptions/WModuleSignalSubscriptionFailed.h"
#include "../common/WLogger.h"
#include "../common/WThreadedRunner.h"
#include "WKernel.h"
#include "WModuleFactory.h"
#include "WModuleInputConnector.h"
#include "WModuleOutputConnector.h"
#include "WBatchLoader.h"
#include "WModuleContainer.h"
...
...
@@ -142,10 +144,20 @@ void WModuleContainer::remove( boost::shared_ptr< WModule > module )
void
WModuleContainer
::
stop
()
{
WLogger
::
getLogger
()
->
addLogMessage
(
"Stopping pending threads."
,
"ModuleContainer ("
+
m_name
+
")"
,
LL_INFO
);
// read lock
boost
::
shared_lock
<
boost
::
shared_mutex
>
slock
=
boost
::
shared_lock
<
boost
::
shared_mutex
>
(
m_pendingThreadsLock
);
for
(
std
::
set
<
boost
::
shared_ptr
<
WThreadedRunner
>
>::
iterator
listIter
=
m_pendingThreads
.
begin
();
listIter
!=
m_pendingThreads
.
end
();
++
listIter
)
{
(
*
listIter
)
->
wait
(
true
);
}
slock
.
unlock
();
WLogger
::
getLogger
()
->
addLogMessage
(
"Stopping modules."
,
"ModuleContainer ("
+
m_name
+
")"
,
LL_INFO
);
// read lock
boost
::
shared_lock
<
boost
::
shared_mutex
>
slock
=
boost
::
shared_lock
<
boost
::
shared_mutex
>
(
m_moduleSetLock
);
slock
=
boost
::
shared_lock
<
boost
::
shared_mutex
>
(
m_moduleSetLock
);
for
(
std
::
set
<
boost
::
shared_ptr
<
WModule
>
>::
iterator
listIter
=
m_modules
.
begin
();
listIter
!=
m_modules
.
end
();
++
listIter
)
{
WLogger
::
getLogger
()
->
addLogMessage
(
"Waiting for module
\"
"
+
(
*
listIter
)
->
getName
()
+
"
\"
to finish."
,
...
...
@@ -243,3 +255,33 @@ boost::shared_ptr< WModule > WModuleContainer::applyModule( boost::shared_ptr< W
return
m
;
}
boost
::
shared_ptr
<
WBatchLoader
>
WModuleContainer
::
loadDataSets
(
std
::
vector
<
std
::
string
>
fileNames
)
{
// create thread which actually loads the data
boost
::
shared_ptr
<
WBatchLoader
>
t
=
boost
::
shared_ptr
<
WBatchLoader
>
(
new
WBatchLoader
(
fileNames
,
shared_from_this
()
)
);
t
->
run
();
return
t
;
}
void
WModuleContainer
::
loadDataSetsSynchronously
(
std
::
vector
<
std
::
string
>
fileNames
)
{
// create thread which actually loads the data
boost
::
shared_ptr
<
WBatchLoader
>
t
=
boost
::
shared_ptr
<
WBatchLoader
>
(
new
WBatchLoader
(
fileNames
,
shared_from_this
()
)
);
t
->
run
();
t
->
wait
();
}
void
WModuleContainer
::
addPendingThread
(
boost
::
shared_ptr
<
WThreadedRunner
>
thread
)
{
boost
::
unique_lock
<
boost
::
shared_mutex
>
lock
=
boost
::
unique_lock
<
boost
::
shared_mutex
>
(
m_pendingThreadsLock
);
m_pendingThreads
.
insert
(
thread
);
lock
.
unlock
();
}
void
WModuleContainer
::
finishedPendingThread
(
boost
::
shared_ptr
<
WThreadedRunner
>
thread
)
{
boost
::
unique_lock
<
boost
::
shared_mutex
>
lock
=
boost
::
unique_lock
<
boost
::
shared_mutex
>
(
m_pendingThreadsLock
);
m_pendingThreads
.
erase
(
thread
);
lock
.
unlock
();
}
src/kernel/WModuleContainer.h
View file @
e058294f
...
...
@@ -32,6 +32,10 @@
#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include "WModuleSignals.h"
class
WThreadedRunner
;
class
WBatchLoader
;
class
WModule
;
/**
...
...
@@ -128,6 +132,40 @@ public:
*/
virtual
boost
::
shared_ptr
<
WModule
>
applyModule
(
boost
::
shared_ptr
<
WModule
>
applyOn
,
boost
::
shared_ptr
<
WModule
>
prototype
);
/**
* Load specified datasets. It immediately returns and starts another thread, which actually loads the data.
*
* \param fileNames list of filenames to load. The registered notification handler for the root container will get notified on
* error and success.
*/
boost
::
shared_ptr
<
WBatchLoader
>
loadDataSets
(
std
::
vector
<
std
::
string
>
fileNames
);
/**
* Loads the specified files synchronously.
*
* \param fileNames list of filenames to load. The registered notification handler for the root container will get notified on
* error and success.
*/
void
loadDataSetsSynchronously
(
std
::
vector
<
std
::
string
>
fileNames
);
/**
* Add the specified thread to the list of pending jobs. Only this ensures, that ALL pending threads got stopped before the
* container gets stopped.
*
* \note use this to register threads whenever you start threads belonging to this container. This avoids shutting down the
* container while other threads depend upon them.
*
* \param thread the thread to add
*/
void
addPendingThread
(
boost
::
shared_ptr
<
WThreadedRunner
>
thread
);
/**
* The specified thread has finished and does not longer depend upon this container instance.
*
* \param thread the thread.
*/
void
finishedPendingThread
(
boost
::
shared_ptr
<
WThreadedRunner
>
thread
);
protected:
/**
...
...
@@ -180,6 +218,16 @@ protected:
*/
std
::
list
<
t_ModuleGenericSignalHandlerType
>
m_associatedNotifiers
;
/**
* Set of all threads that currently depend upon this container.
*/
std
::
set
<
boost
::
shared_ptr
<
WThreadedRunner
>
>
m_pendingThreads
;
/**
* Lock for m_pendingThreads.
*/
boost
::
shared_mutex
m_pendingThreadsLock
;
private:
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment