parent
64efcfd9da
commit
a87978afef
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef SEMAPHORE_HPP
|
||||||
|
#define SEMAPHORE_HPP
|
||||||
|
|
||||||
|
#include "Mutex.hpp"
|
||||||
|
#include "ConditionVariable.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
class Semaphore
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Semaphore( int maxCount = 1 );
|
||||||
|
~Semaphore( void );
|
||||||
|
|
||||||
|
bool lock( int interval = 0 );
|
||||||
|
bool unLock( void );
|
||||||
|
int getCount( void ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int m_maxCount;
|
||||||
|
int m_count;
|
||||||
|
mutable Mutex m_mutex;
|
||||||
|
ConditionVariable m_condVar;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SEMAPHORE_HPP
|
@ -0,0 +1,54 @@
|
|||||||
|
#include "Semaphore.hpp"
|
||||||
|
|
||||||
|
#include "ScopedLock.hpp"
|
||||||
|
#include "Common.hpp"
|
||||||
|
|
||||||
|
Semaphore::Semaphore( int maxCount )
|
||||||
|
: m_maxCount( maxCount )
|
||||||
|
, m_count( maxCount )
|
||||||
|
, m_mutex()
|
||||||
|
, m_condVar(m_mutex)
|
||||||
|
{
|
||||||
|
TRACE(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Semaphore::~Semaphore( void )
|
||||||
|
{
|
||||||
|
TRACE(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Semaphore::lock( int interval )
|
||||||
|
{
|
||||||
|
TRACE(this);
|
||||||
|
ScopedLock sl(m_mutex);
|
||||||
|
if ( m_count == 0 ) {
|
||||||
|
if ( m_condVar.wait(interval) != 0 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_count -= 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Semaphore::unLock( void )
|
||||||
|
{
|
||||||
|
TRACE(this);
|
||||||
|
ScopedLock sc(m_mutex);
|
||||||
|
if ( m_count == m_maxCount ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_count += 1;
|
||||||
|
m_condVar.signal();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Semaphore::getCount( void ) const
|
||||||
|
{
|
||||||
|
TRACE(this);
|
||||||
|
ScopedLock sc(m_mutex);
|
||||||
|
return m_count;
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
#include <cxxtest/TestSuite.h>
|
||||||
|
|
||||||
|
#include "Semaphore.hpp"
|
||||||
|
#include "Thread.hpp"
|
||||||
|
#include "Common.hpp"
|
||||||
|
|
||||||
|
class TestSemaphore : public CxxTest::TestSuite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void testBasic( void )
|
||||||
|
{
|
||||||
|
Semaphore s;
|
||||||
|
TS_ASSERT_EQUALS( s.getCount(), 1 );
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS( s.lock(), true );
|
||||||
|
TS_ASSERT_EQUALS( s.getCount(), 0 );
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS( s.unLock(), true );
|
||||||
|
TS_ASSERT_EQUALS( s.getCount(), 1 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
class ThreadClassWithSemaphore : public Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ThreadClassWithSemaphore(Semaphore &semaphore)
|
||||||
|
: m_semaphore(semaphore)
|
||||||
|
{
|
||||||
|
TRACE(this);
|
||||||
|
}
|
||||||
|
~ThreadClassWithSemaphore() {
|
||||||
|
TRACE(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool use( int timeout = 0 ) {
|
||||||
|
TRACE(this);
|
||||||
|
bool retval = m_semaphore.lock(timeout);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool release( void ) {
|
||||||
|
TRACE(this);
|
||||||
|
return m_semaphore.unLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void* run( void ) {
|
||||||
|
TRACE(this);
|
||||||
|
while (m_isRunning) {
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Semaphore &m_semaphore;
|
||||||
|
|
||||||
|
}; // class ThreadClassWithSemaphore
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void testWithTwoThreads( void )
|
||||||
|
{
|
||||||
|
Semaphore semaphore(2);
|
||||||
|
TS_ASSERT_EQUALS( semaphore.getCount(), 2 );
|
||||||
|
|
||||||
|
ThreadClassWithSemaphore *t1 = new ThreadClassWithSemaphore(semaphore);
|
||||||
|
ThreadClassWithSemaphore *t2 = new ThreadClassWithSemaphore(semaphore);
|
||||||
|
t1->start();
|
||||||
|
t2->start();
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS( t1->use(), true );
|
||||||
|
TS_ASSERT_EQUALS( semaphore.getCount(), 1 );
|
||||||
|
TS_ASSERT_EQUALS( t1->use(), true );
|
||||||
|
TS_ASSERT_EQUALS( semaphore.getCount(), 0 );
|
||||||
|
TS_ASSERT_EQUALS( t1->use(1), false );
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS( t2->use(1), false );
|
||||||
|
TS_ASSERT_EQUALS( semaphore.getCount(), 0 );
|
||||||
|
TS_ASSERT_EQUALS( t1->release(), true );
|
||||||
|
TS_ASSERT_EQUALS( semaphore.getCount(), 1 );
|
||||||
|
TS_ASSERT_EQUALS( t2->use(1), true );
|
||||||
|
TS_ASSERT_EQUALS( semaphore.getCount(), 0 );
|
||||||
|
|
||||||
|
TS_ASSERT_EQUALS( t2->release(), true );
|
||||||
|
TS_ASSERT_EQUALS( semaphore.getCount(), 1 );
|
||||||
|
TS_ASSERT_EQUALS( t2->release(), true );
|
||||||
|
TS_ASSERT_EQUALS( semaphore.getCount(), 2 );
|
||||||
|
TS_ASSERT_EQUALS( t2->release(), false );
|
||||||
|
|
||||||
|
t1->stop();
|
||||||
|
t2->stop();
|
||||||
|
t1->join();
|
||||||
|
t2->join();
|
||||||
|
delete t1;
|
||||||
|
delete t2;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
Loading…
Reference in new issue