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
9fddfb4c
Commit
9fddfb4c
authored
Nov 18, 2009
by
Sebastian Eichelbaum
Browse files
[ADD] - One Shot conditions avoiding endless wait of threads when a condition was fired already
parent
7721fab4
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
229 additions
and
0 deletions
+229
-0
src/common/WConditionOneShot.cpp
src/common/WConditionOneShot.cpp
+59
-0
src/common/WConditionOneShot.h
src/common/WConditionOneShot.h
+75
-0
src/common/test/WConditionOneShot_test.h
src/common/test/WConditionOneShot_test.h
+95
-0
No files found.
src/common/WConditionOneShot.cpp
0 → 100644
View file @
9fddfb4c
//---------------------------------------------------------------------------
//
// 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 "WConditionOneShot.h"
WConditionOneShot
::
WConditionOneShot
()
:
WCondition
()
{
// initialize members
m_lock
=
boost
::
unique_lock
<
boost
::
shared_mutex
>
(
m_mutex
);
}
WConditionOneShot
::~
WConditionOneShot
()
{
// cleanup
try
{
m_lock
.
unlock
();
}
catch
(
const
boost
::
lock_error
&
e
)
{
// ignore this particular error since it is thrown when the lock is not locked anymore
}
}
void
WConditionOneShot
::
wait
()
{
// now we wait until the write lock is released and we can get a read lock
boost
::
shared_lock
<
boost
::
shared_mutex
>
slock
=
boost
::
shared_lock
<
boost
::
shared_mutex
>
(
m_mutex
);
slock
.
unlock
();
}
void
WConditionOneShot
::
notify
()
{
// release the write lock to allow waiting threads to achieve read lock
m_lock
.
unlock
();
}
src/common/WConditionOneShot.h
0 → 100644
View file @
9fddfb4c
//---------------------------------------------------------------------------
//
// 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 WCONDITIONONESHOT_H
#define WCONDITIONONESHOT_H
#include <boost/thread.hpp>
#include "WCondition.h"
/**
* Implements a WCondition, but can be fired only ONCE. This is useful if you want to have a thread waiting for a condition but
* you can not assure that the thread already waits when you set the condition. This would cause the thread to wait endlessly
* because he does not know that you already fired it. Implementation is simple. The constructor uses a unique lock (write lock)
* on a mutex. All waiting threads try to get a read lock which is not possible as long it is write-locked. The notify method
* releases the write lock and all waiting threads can continue.
*/
class
WConditionOneShot
:
public
WCondition
{
friend
class
WConditionOneShot_test
;
public:
/**
* Default constructor.
*/
WConditionOneShot
();
/**
* Destructor.
*/
virtual
~
WConditionOneShot
();
/**
* Wait for the condition. Sets the calling thread asleep.
*/
virtual
void
wait
();
/**
* Notifies all waiting threads.
*/
virtual
void
notify
();
protected:
/**
* Locked as long the condition was not fired.
*/
boost
::
unique_lock
<
boost
::
shared_mutex
>
m_lock
;
private:
};
#endif // WCONDITIONONESHOT_H
src/common/test/WConditionOneShot_test.h
0 → 100644
View file @
9fddfb4c
//---------------------------------------------------------------------------
//
// 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 WCONDITION_TEST_H
#define WCONDITION_TEST_H
#include <iostream>
#include <boost/thread.hpp>
#include <cxxtest/TestSuite.h>
#include "../WConditionOneShot.h"
/**
* Helper class.
*/
class
Callable
{
public:
bool
flag
;
WConditionOneShot
*
c
;
void
threadMain
()
{
flag
=
true
;
boost
::
this_thread
::
sleep
(
boost
::
posix_time
::
seconds
(
1
)
);
c
->
notify
();
};
};
/**
* Test WConditionOneShot
*/
class
WConditionOneShotTest
:
public
CxxTest
::
TestSuite
{
public:
/**
* An instantiation should never throw an exception, as well as tear down.
*/
void
testInstantiation
(
void
)
{
WConditionOneShot
*
c
;
TS_ASSERT_THROWS_NOTHING
(
c
=
new
WConditionOneShot
()
);
TS_ASSERT_THROWS_NOTHING
(
delete
c
);
}
/**
* Test whether notification is working.
*/
void
testWaitNotify
()
{
WConditionOneShot
c
;
Callable
t
;
t
.
flag
=
false
;
t
.
c
=
&
c
;
// start a thread
boost
::
thread
thread
=
boost
::
thread
(
boost
::
bind
(
&
Callable
::
threadMain
,
&
t
)
);
// wait for condition
c
.
wait
();
// since it is a one shot condition -> another wait will not cause a freeze
c
.
wait
();
TS_ASSERT
(
t
.
flag
);
}
};
#endif // WCONDITION_TEST_H
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