Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
OpenWalnut
OpenWalnut Core
Commits
dc9edba1
Commit
dc9edba1
authored
Feb 10, 2010
by
Sebastian Eichelbaum
Browse files
[ADD] - added class for generic thread safe access to arbitrary objects
parent
5e782d3e
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
254 additions
and
69 deletions
+254
-69
src/common/WSharedObject.cpp
src/common/WSharedObject.cpp
+1
-57
src/common/WSharedObject.h
src/common/WSharedObject.h
+214
-0
src/dataHandler/WDataHandler.cpp
src/dataHandler/WDataHandler.cpp
+16
-6
src/dataHandler/WDataHandler.h
src/dataHandler/WDataHandler.h
+23
-6
No files found.
src/common/WS
TLContainer.h
→
src/common/WS
haredObject.cpp
View file @
dc9edba1
...
...
@@ -22,61 +22,5 @@
//
//---------------------------------------------------------------------------
#ifndef WSTLCONTAINER_H
#define WSTLCONTAINER_H
#include <boost/thread.hpp>
/**
* Wrapper around the STL sequence container providing thread safe iterator access.
*/
template
<
typename
T
>
class
WSTLContainer
{
public:
/**
* Default constructor.
*/
WSTLContainer
();
/**
* Destructor.
*/
virtual
~
WSTLContainer
();
protected:
/**
* The lock to ensure thread safe access.
*/
boost
::
shared_mutex
m_lock
;
/**
* The write lock used for write access.
*/
boost
::
unique_lock
<
boost
::
shared_mutex
>
m_wLock
;
/**
* The read lock used for write access.
*/
boost
::
shared_lock
<
boost
::
shared_mutex
>
m_rLock
;
private:
};
template
<
typename
T
>
WSTLContainer
<
T
>::
WSTLContainer
()
{
// init members
}
template
<
typename
T
>
WSTLContainer
<
T
>::~
WSTLContainer
()
{
// clean up
}
#endif // WSTLCONTAINER_H
#include "WSharedObject.h"
src/common/WSharedObject.h
0 → 100644
View file @
dc9edba1
//---------------------------------------------------------------------------
//
// 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 WSHAREDOBJECT_H
#define WSHAREDOBJECT_H
#include <boost/thread.hpp>
/**
* Wrapper around an object/type for thread safe sharing of objects among multiple threads.
*/
template
<
typename
T
>
class
WSharedObject
{
public:
/**
* Default constructor.
*/
WSharedObject
();
/**
* Destructor.
*/
virtual
~
WSharedObject
();
/**
* Class allowing thread-safe access to an object. It provides some convenience methods to read and write lock the access.
*/
class
WSharedObjectAccess
{
public:
/**
* Constructor. It uses the specified mutex which is shared among all access objects of the same WSharedObject.
*
* \param mutex the mutex used to lock the access.
*/
explicit
WSharedObjectAccess
(
T
&
object
,
boost
::
shared_ptr
<
boost
::
shared_mutex
>
mutex
);
/**
* Desctructor.
*/
~
WSharedObjectAccess
();
/**
* Gets the contained, and protected object.
*
* \return the contained object
*/
T
&
get
();
/**
* Acquires a read lock to the protected object for easy access. Use this EVERYTIME you want to read from the object. Use
* endRead() to free the lock.
*/
void
beginRead
();
/**
* Frees the lock to the object. If you do not free the lock, no write access will be granted in the future. To nobody!
* So always free the lock.
*/
void
endRead
();
/**
* Acquires a write lock to the object
*/
void
beginWrite
();
/**
* Frees the lock to the object. If you do not free the lock, no read or write access will be granted in the future. To nobody!
* So always free the lock.
*/
void
endWrite
();
protected:
/**
* The write lock. Used by beginWrite and endWrite.
*/
boost
::
unique_lock
<
boost
::
shared_mutex
>
m_writeLock
;
/**
* The write lock. Used by beginWrite and endWrite.
*/
boost
::
shared_lock
<
boost
::
shared_mutex
>
m_readLock
;
/**
* The lock to ensure thread safe access. It is the lock provided by WSharedObject.
*/
boost
::
shared_ptr
<
boost
::
shared_mutex
>
m_lock
;
/**
* the object protected.
*/
T
&
m_object
;
};
/**
* Use a shared_ptr since the shared and unique locks from boost are non-copyable.
*/
typedef
boost
::
shared_ptr
<
WSharedObjectAccess
>
WSharedAccess
;
/**
* This method distributes access objects. These objects are able to read/write lock the object and grant access to it, in
* a thread-safe manner.
*
* \return the access object which allows thread safe access to the object.
*/
WSharedAccess
getAccessObject
();
protected:
/**
* The object wrapped by this class.
*/
T
m_object
;
/**
* The lock to ensure thread safe access.
*/
boost
::
shared_ptr
<
boost
::
shared_mutex
>
m_lock
;
private:
};
template
<
typename
T
>
WSharedObject
<
T
>::
WSharedObject
()
:
m_lock
(
new
boost
::
shared_mutex
)
{
// init members
}
template
<
typename
T
>
WSharedObject
<
T
>::~
WSharedObject
()
{
// clean up
}
template
<
typename
T
>
typename
WSharedObject
<
T
>::
WSharedAccess
WSharedObject
<
T
>::
getAccessObject
()
{
return
WSharedObject
<
T
>::
WSharedAccess
(
new
WSharedObject
<
T
>::
WSharedObjectAccess
(
m_object
,
m_lock
)
);
}
template
<
typename
T
>
WSharedObject
<
T
>::
WSharedObjectAccess
::
WSharedObjectAccess
(
T
&
object
,
boost
::
shared_ptr
<
boost
::
shared_mutex
>
mutex
)
:
m_lock
(
mutex
),
m_object
(
object
)
{
}
template
<
typename
T
>
WSharedObject
<
T
>::
WSharedObjectAccess
::~
WSharedObjectAccess
()
{
// this shouldn't be necessary as the locks automatically unlock if the get destroyed
// m_readLock.unlock();
// m_writeLock.unlock();
}
template
<
typename
T
>
void
WSharedObject
<
T
>::
WSharedObjectAccess
::
beginRead
()
{
m_readLock
=
boost
::
shared_lock
<
boost
::
shared_mutex
>
(
*
m_lock
);
}
template
<
typename
T
>
void
WSharedObject
<
T
>::
WSharedObjectAccess
::
endRead
()
{
m_readLock
.
unlock
();
}
template
<
typename
T
>
void
WSharedObject
<
T
>::
WSharedObjectAccess
::
beginWrite
()
{
m_writeLock
=
boost
::
unique_lock
<
boost
::
shared_mutex
>
(
*
m_lock
);
}
template
<
typename
T
>
void
WSharedObject
<
T
>::
WSharedObjectAccess
::
endWrite
()
{
m_writeLock
.
unlock
();
}
template
<
typename
T
>
T
&
WSharedObject
<
T
>::
WSharedObjectAccess
::
get
()
{
return
m_object
;
}
#endif // WSHAREDOBJECT_H
src/dataHandler/WDataHandler.cpp
View file @
dc9edba1
...
...
@@ -29,15 +29,25 @@
#include "WSubject.h"
#include "exceptions/WDHNoSuchDataSet.h"
WDataHandler
::
WDataHandler
()
WDataHandler
::
WDataHandler
()
:
m_subjects
(),
m_subjectAccess
(
m_subjects
.
getAccessObject
()
)
{
}
void
WDataHandler
::
addSubject
(
boost
::
shared_ptr
<
WSubject
>
newS
ubject
)
void
WDataHandler
::
addSubject
(
boost
::
shared_ptr
<
WSubject
>
s
ubject
)
{
// add the subject to the list ( ensure mutual exclusive write )
boost
::
unique_lock
<
boost
::
shared_mutex
>
lock
=
boost
::
unique_lock
<
boost
::
shared_mutex
>
(
m_subjectsLock
);
//m_subjects.push_back( newSubject );
lock
.
unlock
();
// simply add the new subject
m_subjectAccess
->
beginWrite
();
m_subjectAccess
->
get
().
insert
(
subject
);
m_subjectAccess
->
endWrite
();
}
void
WDataHandler
::
removeSubject
(
boost
::
shared_ptr
<
WSubject
>
subject
)
{
// simply add the new subject
m_subjectAccess
->
beginWrite
();
m_subjectAccess
->
get
().
erase
(
subject
);
m_subjectAccess
->
endWrite
();
}
src/dataHandler/WDataHandler.h
View file @
dc9edba1
...
...
@@ -26,13 +26,13 @@
#define WDATAHANDLER_H
#include <string>
#include <
vector
>
#include <
set
>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include "../common/WS
TLContainer
.h"
#include "../common/WS
haredObject
.h"
#include "WDataSet.h"
...
...
@@ -45,7 +45,7 @@ class WSubject;
*
* \ingroup dataHandler
*/
class
WDataHandler
:
public
boost
::
enable_shared_from_this
<
WDataHandler
>
class
WDataHandler
{
/**
* Only UnitTests may be friends.
...
...
@@ -54,6 +54,11 @@ friend class WDataHandlerTest;
public:
/**
* For shortening: a type defining a shared vector of WSubject pointers.
*/
typedef
std
::
set
<
boost
::
shared_ptr
<
WSubject
>
>
SubjectContainerType
;
/**
* Empty standard constructor.
*/
...
...
@@ -62,16 +67,28 @@ public:
/**
* Insert a new subject referenced by a pointer.
*
* \param newSubject a pointer to the subject that will be added
* \param subject a pointer to the subject that will be added
*/
void
addSubject
(
boost
::
shared_ptr
<
WSubject
>
subject
);
/**
* Removes the specified subject if it is in the set.
*
* \param subject the subject to remove.
*/
void
add
Subject
(
boost
::
shared_ptr
<
WSubject
>
newS
ubject
);
void
remove
Subject
(
boost
::
shared_ptr
<
WSubject
>
s
ubject
);
protected:
/**
* A container for all WSubjects.
*/
WSTLContainer
<
std
::
vector
<
boost
::
shared_ptr
<
WSubject
>
>
>
m_subjects
;
WSharedObject
<
SubjectContainerType
>
m_subjects
;
/**
* The access object used for thread safe access.
*/
WSharedObject
<
SubjectContainerType
>::
WSharedAccess
m_subjectAccess
;
/**
* The lock used for avoiding mutual write to the subjects list
...
...
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