mirror of
https://bitbucket.org/theswgsource/src-1.2.git
synced 2026-07-28 23:16:15 -04:00
Added sharedSynchronization library
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
|
||||
set(SHARED_SOURCES
|
||||
shared/BlockingPointer.h
|
||||
shared/BlockingQueue.h
|
||||
shared/CountingSemaphore.h
|
||||
shared/Guard.h
|
||||
shared/WriteOnce.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(PLATFORM_SOURCES
|
||||
win32/ConditionVariable.cpp
|
||||
win32/ConditionVariable.h
|
||||
win32/FirstSharedSynchronization.cpp
|
||||
win32/Gate.cpp
|
||||
win32/Gate.h
|
||||
win32/InterlockedInteger.h
|
||||
win32/InterlockedVoidPointer.h
|
||||
win32/Mutex.cpp
|
||||
win32/Mutex.h
|
||||
win32/RecursiveMutex.cpp
|
||||
win32/RecursiveMutex.h
|
||||
win32/Semaphore.cpp
|
||||
win32/Semaphore.h
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32)
|
||||
else()
|
||||
set(PLATFORM_SOURCES
|
||||
linux/ConditionVariable.cpp
|
||||
linux/ConditionVariable.h
|
||||
linux/Gate.cpp
|
||||
linux/Gate.h
|
||||
linux/InterlockedInteger.h
|
||||
linux/InterlockedVoidPointer.h
|
||||
linux/Mutex.cpp
|
||||
linux/Mutex.h
|
||||
linux/RecursiveMutex.cpp
|
||||
linux/RecursiveMutex.h
|
||||
linux/Semaphore.cpp
|
||||
linux/Semaphore.h
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/linux)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shared
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public
|
||||
)
|
||||
|
||||
add_library(sharedSynchronization STATIC
|
||||
${SHARED_SOURCES}
|
||||
${PLATFORM_SOURCES}
|
||||
)
|
||||
@@ -0,0 +1,38 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConditionVariable.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedSynchronization/ConditionVariable.h"
|
||||
|
||||
ConditionVariable::ConditionVariable(Mutex &m)
|
||||
: _mutex(m)
|
||||
{
|
||||
pthread_cond_init(&cond, 0);
|
||||
}
|
||||
|
||||
ConditionVariable::~ConditionVariable()
|
||||
{
|
||||
pthread_cond_destroy(&cond);
|
||||
}
|
||||
|
||||
void ConditionVariable::wait()
|
||||
{
|
||||
pthread_cond_wait(&cond, &_mutex.getInternalMutex());
|
||||
}
|
||||
|
||||
void ConditionVariable::signal()
|
||||
{
|
||||
pthread_cond_signal(&cond);
|
||||
}
|
||||
|
||||
void ConditionVariable::broadcast()
|
||||
{
|
||||
pthread_cond_broadcast(&cond);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConditionVariable.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ConditionVariable_h
|
||||
#define INCLUDED_ConditionVariable_h
|
||||
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
|
||||
class ConditionVariable
|
||||
{
|
||||
public:
|
||||
ConditionVariable(Mutex &m);
|
||||
~ConditionVariable();
|
||||
void wait();
|
||||
// You must own the mutex before calling signal.
|
||||
void signal();
|
||||
void broadcast();
|
||||
Mutex &mutex() { return _mutex; }
|
||||
private:
|
||||
ConditionVariable(const ConditionVariable &o);
|
||||
ConditionVariable &operator =(const ConditionVariable &o);
|
||||
|
||||
Mutex &_mutex;
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Gate.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedSynchronization/Gate.h"
|
||||
|
||||
Gate::Gate(bool open)
|
||||
: cond(lock)
|
||||
{
|
||||
opened = open;
|
||||
}
|
||||
|
||||
Gate::~Gate()
|
||||
{
|
||||
}
|
||||
|
||||
void Gate::wait()
|
||||
{
|
||||
lock.enter();
|
||||
while (!opened)
|
||||
cond.wait();
|
||||
lock.leave();
|
||||
}
|
||||
|
||||
void Gate::close()
|
||||
{
|
||||
lock.enter();
|
||||
opened = false;
|
||||
lock.leave();
|
||||
}
|
||||
|
||||
void Gate::open()
|
||||
{
|
||||
lock.enter();
|
||||
opened = true;
|
||||
cond.broadcast();
|
||||
lock.leave();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Gate.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Gate_h
|
||||
#define INCLUDED_Gate_h
|
||||
|
||||
#include "sharedSynchronization/ConditionVariable.h"
|
||||
|
||||
class Gate
|
||||
{
|
||||
public:
|
||||
Gate(bool open);
|
||||
~Gate();
|
||||
|
||||
void wait();
|
||||
|
||||
void close();
|
||||
void open();
|
||||
private:
|
||||
Gate(const Gate &o);
|
||||
Gate &operator =(const Gate &o);
|
||||
|
||||
Mutex lock;
|
||||
bool opened;
|
||||
ConditionVariable cond;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,63 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// InterlockedInteger.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_InterlockedInteger_h
|
||||
#define INCLUDED_InterlockedInteger_h
|
||||
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
class InterlockedInteger
|
||||
{
|
||||
public:
|
||||
explicit InterlockedInteger(int initialValue=0);
|
||||
int operator =(int); // returns prior value (exchange)
|
||||
int operator ++(); // returns new value
|
||||
int operator --(); // returns new value
|
||||
operator int() const { return value; }
|
||||
private:
|
||||
InterlockedInteger(const InterlockedInteger &o);
|
||||
InterlockedInteger &operator =(const InterlockedInteger &o);
|
||||
pthread_mutex_t lock;
|
||||
volatile int value;
|
||||
};
|
||||
|
||||
inline InterlockedInteger::InterlockedInteger(int i_value)
|
||||
: value(i_value)
|
||||
{
|
||||
pthread_mutex_init(&lock, 0);
|
||||
}
|
||||
|
||||
inline int InterlockedInteger::operator =(int i_value)
|
||||
{
|
||||
pthread_mutex_lock(&lock);
|
||||
int oldvalue = value;
|
||||
value = i_value;
|
||||
pthread_mutex_unlock(&lock);
|
||||
return oldvalue;
|
||||
}
|
||||
|
||||
inline int InterlockedInteger::operator ++()
|
||||
{
|
||||
pthread_mutex_lock(&lock);
|
||||
int newvalue = value+1;
|
||||
value = newvalue;
|
||||
pthread_mutex_unlock(&lock);
|
||||
return newvalue;
|
||||
}
|
||||
|
||||
inline int InterlockedInteger::operator --()
|
||||
{
|
||||
pthread_mutex_lock(&lock);
|
||||
int newvalue = value-1;
|
||||
value = newvalue;
|
||||
pthread_mutex_unlock(&lock);
|
||||
return newvalue;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// InterlockedVoidPointer.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_InterlockedVoidPointer_h
|
||||
#define INCLUDED_InterlockedVoidPointer_h
|
||||
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
class InterlockedVoidPointer
|
||||
{
|
||||
public:
|
||||
explicit InterlockedVoidPointer(void * initialValue=0);
|
||||
void * compareExchange(void * compare, void * exchange); // compare and exchange if same
|
||||
operator void * () const { return reinterpret_cast<void *>(value); }
|
||||
private:
|
||||
InterlockedVoidPointer(const InterlockedVoidPointer &o);
|
||||
InterlockedVoidPointer &operator =(const InterlockedVoidPointer &o);
|
||||
Mutex lock;
|
||||
void * volatile value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class InterlockedPointer: public InterlockedVoidPointer
|
||||
{
|
||||
public:
|
||||
explicit InterlockedPointer(T * initialValue): InterlockedVoidPointer(initialValue) {}
|
||||
operator T * () const { return static_cast<const T *>(value); }
|
||||
};
|
||||
|
||||
inline InterlockedVoidPointer::InterlockedVoidPointer(void * initialValue)
|
||||
: value(initialValue)
|
||||
{
|
||||
}
|
||||
|
||||
inline void * InterlockedVoidPointer::compareExchange(void * compare, void * exchange)
|
||||
{
|
||||
lock.enter();
|
||||
void * temp = value;
|
||||
if (temp == compare)
|
||||
value = exchange;
|
||||
lock.leave();
|
||||
return temp;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Mutex.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
|
||||
Mutex::Mutex()
|
||||
{
|
||||
pthread_mutex_init(&mutex, 0);
|
||||
}
|
||||
|
||||
Mutex::~Mutex()
|
||||
{
|
||||
pthread_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
void Mutex::enter()
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
}
|
||||
|
||||
void Mutex::leave()
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Mutex.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Mutex_h
|
||||
#define INCLUDED_Mutex_h
|
||||
|
||||
class Mutex
|
||||
{
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
void enter();
|
||||
void leave();
|
||||
|
||||
pthread_mutex_t &getInternalMutex() { return mutex; }
|
||||
private:
|
||||
Mutex(const Mutex &o);
|
||||
Mutex &operator =(const Mutex &o);
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// RecursiveMutex.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedSynchronization/RecursiveMutex.h"
|
||||
|
||||
RecursiveMutex::RecursiveMutex()
|
||||
{
|
||||
pthread_mutexattr_t attributes;
|
||||
|
||||
pthread_mutexattr_init(&attributes);
|
||||
pthread_mutexattr_settype(&attributes,PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&mutex,&attributes);
|
||||
pthread_mutexattr_destroy(&attributes);
|
||||
}
|
||||
|
||||
RecursiveMutex::~RecursiveMutex()
|
||||
{
|
||||
pthread_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
void RecursiveMutex::enter()
|
||||
{
|
||||
pthread_mutex_lock(&mutex);
|
||||
}
|
||||
|
||||
void RecursiveMutex::leave()
|
||||
{
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// RecursiveMutex.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_RecursiveMutex_h
|
||||
#define INCLUDED_RecursiveMutex_h
|
||||
|
||||
#include "sharedSynchronization/InterlockedInteger.h"
|
||||
|
||||
class RecursiveMutex
|
||||
{
|
||||
public:
|
||||
RecursiveMutex();
|
||||
~RecursiveMutex();
|
||||
|
||||
void enter();
|
||||
void leave();
|
||||
private:
|
||||
RecursiveMutex(const RecursiveMutex &o);
|
||||
RecursiveMutex &operator =(const RecursiveMutex &o);
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Semaphore.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedSynchronization/Semaphore.h"
|
||||
|
||||
Semaphore::Semaphore(int count, int initial)
|
||||
{
|
||||
sem_init(&sem, false, initial);
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
sem_destroy(&sem);
|
||||
}
|
||||
|
||||
void Semaphore::wait()
|
||||
{
|
||||
sem_wait(&sem);
|
||||
}
|
||||
|
||||
void Semaphore::wait(unsigned int maxDurationMs)
|
||||
{
|
||||
timespec ts;
|
||||
ts.tv_sec = maxDurationMs/1000000;
|
||||
ts.tv_nsec = maxDurationMs%1000000;
|
||||
sem_timedwait(&sem, &ts);
|
||||
}
|
||||
|
||||
void Semaphore::signal(int count)
|
||||
{
|
||||
sem_post(&sem);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Semaphore.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Semaphore_h
|
||||
#define INCLUDED_Semaphore_h
|
||||
|
||||
class Semaphore
|
||||
{
|
||||
public:
|
||||
Semaphore(int count=0x7FFFFFFF, int initial=0);
|
||||
~Semaphore();
|
||||
|
||||
void wait();
|
||||
void wait(unsigned int maxDurationMs);
|
||||
void signal(int count=1);
|
||||
private:
|
||||
Semaphore(const Semaphore &o);
|
||||
Semaphore &operator =(const Semaphore &o);
|
||||
|
||||
sem_t sem;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// BlockingPointer.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_BlockingPointer_h
|
||||
#define INCLUDED_BlockingPointer_h
|
||||
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
#include "sharedSynchronization/Semaphore.h"
|
||||
|
||||
template<class T>
|
||||
class BlockingPointer
|
||||
{
|
||||
public:
|
||||
BlockingPointer(Mutex &m, T * begin, T * end);
|
||||
T * operator ++(int);
|
||||
T * operator --();
|
||||
private:
|
||||
BlockingPointer(const BlockingPointer &o);
|
||||
BlockingPointer &operator =(const BlockingPointer &o);
|
||||
Mutex &_mutex;
|
||||
T * volatile value;
|
||||
T * begin, * end;
|
||||
Semaphore high, low;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
BlockingPointer<T>::BlockingPointer<T>(Mutex &m, T * i_begin, T * i_end)
|
||||
: _mutex(m), value(i_begin), begin(i_begin), end(i_end)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T * BlockingPointer<T>::operator ++(int)
|
||||
{
|
||||
++value;
|
||||
if (value == begin)
|
||||
{
|
||||
low.release();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value > end)
|
||||
{
|
||||
_mutex.leave();
|
||||
high.wait();
|
||||
_mutex.enter();
|
||||
}
|
||||
}
|
||||
return value-1;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T * BlockingPointer<T>::operator --()
|
||||
{
|
||||
--value;
|
||||
if (value == end - 1)
|
||||
{
|
||||
high.release();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value < begin)
|
||||
{
|
||||
_mutex.leave();
|
||||
low.wait();
|
||||
_mutex.enter();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// BlockingQueue.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_BlockingQueue_h
|
||||
#define INCLUDED_BlockingQueue_h
|
||||
|
||||
template<class T>
|
||||
class BlockingQueue
|
||||
{
|
||||
public:
|
||||
BlockingQueue(Mutex &m, T * begin, T * end);
|
||||
T * operator ++(int);
|
||||
T * operator --();
|
||||
private:
|
||||
BlockingQueue(const BlockingQueue &o);
|
||||
BlockingQueue &operator =(const BlockingQueue &o);
|
||||
Mutex &_mutex;
|
||||
T * volatile first, * volatile last;
|
||||
T * begin, * end;
|
||||
int size, maxsize;
|
||||
Semaphore notFull, notEmpty;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
BlockingQueue<T>::BlockingQueue<T>(Mutex &m, T * i_begin, T * i_end)
|
||||
: _mutex(m), first(i_begin), last(i_begin), begin(i_begin), end(i_end), size(0), maxsize(i_end - i_begin)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T * BlockingQueue<T>::operator ++(int)
|
||||
{
|
||||
++size;
|
||||
if (size > maxsize)
|
||||
{
|
||||
_mutex.leave();
|
||||
notFull.wait();
|
||||
_mutex.enter();
|
||||
}
|
||||
|
||||
T * oldlast = last;
|
||||
++last;
|
||||
if (last == end)
|
||||
{
|
||||
last = begin;
|
||||
}
|
||||
|
||||
if (size == 1)
|
||||
{
|
||||
notEmpty.signal();
|
||||
}
|
||||
|
||||
return oldlast;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T * BlockingQueue<T>::operator --()
|
||||
{
|
||||
--size;
|
||||
if (size == 0)
|
||||
{
|
||||
_mutex.leave();
|
||||
notEmpty.wait();
|
||||
_mutex.enter();
|
||||
}
|
||||
|
||||
++first;
|
||||
if (first == end)
|
||||
{
|
||||
first = begin;
|
||||
}
|
||||
|
||||
if (size == maxsize - 1)
|
||||
{
|
||||
notFull.signal();
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// CountingSemaphore.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_CountingSemaphore_h
|
||||
#define INCLUDED_CountingSemaphore_h
|
||||
|
||||
#include "sharedSynchronization/Semaphore.h"
|
||||
// this needs a little more thought
|
||||
|
||||
class CountingSemaphore
|
||||
{
|
||||
public:
|
||||
CountingSemaphore();
|
||||
~CountingSemaphore();
|
||||
|
||||
void wait() { ++waiters; sem.wait(); }
|
||||
void signal(int i_count=1)
|
||||
{
|
||||
if (i_count > waiters) i_count = waiters;
|
||||
sem.signal(i_count);
|
||||
}
|
||||
|
||||
int count() { return waiters; }
|
||||
private:
|
||||
CountingSemaphore(const CountingSemaphore &o);
|
||||
CountingSemaphore &operator =(const CountingSemaphore &o);
|
||||
Semaphore sem;
|
||||
int waiters;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FirstSynchronization.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_FirstSynchronization_H
|
||||
#define INCLUDED_FirstSynchronization_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedDebug/FirstSharedDebug.h"
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Guard.h
|
||||
//
|
||||
// Copyright 2003 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef _Guard_H_
|
||||
#define _Guard_H_
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedSynchronization/RecursiveMutex.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class Guard
|
||||
{
|
||||
public:
|
||||
Guard(RecursiveMutex &mutex) :
|
||||
m_mutex(mutex)
|
||||
{
|
||||
mutex.enter();
|
||||
}
|
||||
~Guard()
|
||||
{
|
||||
m_mutex.leave();
|
||||
}
|
||||
|
||||
private:
|
||||
Guard(Guard const &);
|
||||
Guard &operator=(Guard const &);
|
||||
|
||||
private:
|
||||
RecursiveMutex &m_mutex;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif // _Guard_H_
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// WriteOnce.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_WriteOnce_h
|
||||
#define INCLUDED_WriteOnce_h
|
||||
|
||||
#include "sharedSynchronization/Gate.h"
|
||||
|
||||
template <class T>
|
||||
class WriteOnce
|
||||
{
|
||||
public:
|
||||
WriteOnce(): gate(false) {}
|
||||
~WriteOnce() {}
|
||||
explicit WriteOnce(T &i_initial): gate(false), value(i_initial) {}
|
||||
T &operator =(const T &i_value) { value = i_value; gate.open(); return value; }
|
||||
operator T() { gate.wait(); return value; }
|
||||
private:
|
||||
WriteOnce(const WriteOnce &o);
|
||||
WriteOnce &operator =(const WriteOnce &o);
|
||||
Gate gate;
|
||||
T value;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,50 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConditionVariable.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedSynchronization/FirstSharedSynchronization.h"
|
||||
#include "sharedSynchronization/ConditionVariable.h"
|
||||
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
|
||||
ConditionVariable::ConditionVariable(Mutex &m)
|
||||
: sem(1), _mutex(m), count(0)
|
||||
{
|
||||
}
|
||||
|
||||
ConditionVariable::~ConditionVariable()
|
||||
{
|
||||
}
|
||||
|
||||
void ConditionVariable::wait()
|
||||
{
|
||||
++count;
|
||||
_mutex.leave();
|
||||
sem.wait();
|
||||
_mutex.enter();
|
||||
}
|
||||
|
||||
void ConditionVariable::signal()
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
--count;
|
||||
sem.signal();
|
||||
}
|
||||
}
|
||||
|
||||
void ConditionVariable::broadcast()
|
||||
{
|
||||
if (count)
|
||||
{
|
||||
int oldcount = count;
|
||||
count = 0;
|
||||
sem.signal(oldcount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// ConditionVariable.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_ConditionVariable_h
|
||||
#define INCLUDED_ConditionVariable_h
|
||||
|
||||
class Mutex;
|
||||
|
||||
#include "sharedSynchronization/Semaphore.h"
|
||||
|
||||
/* Condition variable semantics follow pthreads semantics. You
|
||||
must have the mutex locked before calling signal or broadcast.
|
||||
When wait returns, the mutex is locked and you must unlock it.
|
||||
*/
|
||||
|
||||
class ConditionVariable
|
||||
{
|
||||
public:
|
||||
ConditionVariable(Mutex &m);
|
||||
~ConditionVariable();
|
||||
void wait();
|
||||
// You must own the mutex before calling signal.
|
||||
void signal();
|
||||
void broadcast();
|
||||
Mutex &mutex() { return _mutex; }
|
||||
private:
|
||||
ConditionVariable(const ConditionVariable &o);
|
||||
ConditionVariable &operator =(const ConditionVariable &o);
|
||||
|
||||
Semaphore sem;
|
||||
Mutex &_mutex;
|
||||
int count;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,8 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FirstSynchronization.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedSynchronization/FirstSharedSynchronization.h"
|
||||
@@ -0,0 +1,60 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Gate.cpp
|
||||
//
|
||||
// Copyright 2001-2002 Sony Online Entertainment
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedSynchronization/FirstSharedSynchronization.h"
|
||||
#include "sharedSynchronization/Gate.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
Gate::Gate(bool open)
|
||||
{
|
||||
handle = CreateEvent(0, true, open, 0);
|
||||
DEBUG_FATAL(handle == NULL, ("CreateEvent failed"));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
Gate::~Gate()
|
||||
{
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Gate::wait()
|
||||
{
|
||||
int errors = 0;
|
||||
for (;;)
|
||||
{
|
||||
DWORD result = WaitForSingleObject(handle, INFINITE);
|
||||
if (result == WAIT_OBJECT_0)
|
||||
return;
|
||||
|
||||
++errors;
|
||||
FATAL(errors >= 3, ("WaitForSingleObject failed multiple times"));
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Gate::close()
|
||||
{
|
||||
const BOOL result = ResetEvent(handle);
|
||||
FATAL(result == 0, ("ResetEvent failed"));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Gate::open()
|
||||
{
|
||||
const BOOL result = SetEvent(handle);
|
||||
FATAL(result == 0, ("SetEvent failed"));
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,39 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Gate.h
|
||||
//
|
||||
// Copyright 2001-2002 Sony Online Entertainment
|
||||
// All Rights Reseved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Gate_h
|
||||
#define INCLUDED_Gate_h
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class Gate
|
||||
{
|
||||
public:
|
||||
|
||||
Gate(bool initiallyOpen);
|
||||
~Gate();
|
||||
|
||||
void wait();
|
||||
|
||||
void close();
|
||||
void open();
|
||||
|
||||
private:
|
||||
|
||||
Gate(const Gate &o);
|
||||
Gate &operator =(const Gate &o);
|
||||
|
||||
private:
|
||||
|
||||
HANDLE handle;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// InterlockedInteger.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_InterlockedInteger_h
|
||||
#define INCLUDED_InterlockedInteger_h
|
||||
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
class InterlockedInteger
|
||||
{
|
||||
public:
|
||||
explicit InterlockedInteger(int initialValue=0);
|
||||
int operator =(int); // returns prior value (exchange)
|
||||
int operator ++(); // returns new value
|
||||
int operator --(); // returns new value
|
||||
operator int() const { return static_cast<int>(value); }
|
||||
private:
|
||||
InterlockedInteger(const InterlockedInteger &o);
|
||||
InterlockedInteger &operator =(const InterlockedInteger &o);
|
||||
volatile int value;
|
||||
};
|
||||
|
||||
inline InterlockedInteger::InterlockedInteger(int i_value)
|
||||
: value(i_value)
|
||||
{
|
||||
}
|
||||
|
||||
inline int InterlockedInteger::operator =(int i_value)
|
||||
{
|
||||
long * ptr = (long *)&value;
|
||||
return static_cast<int>(InterlockedExchange(ptr, static_cast<long>(i_value)));
|
||||
}
|
||||
|
||||
inline int InterlockedInteger::operator ++()
|
||||
{
|
||||
long * ptr = (long *)&value;
|
||||
return static_cast<int>(InterlockedIncrement(ptr));
|
||||
}
|
||||
|
||||
inline int InterlockedInteger::operator --()
|
||||
{
|
||||
long * ptr = (long *)&value;
|
||||
return static_cast<int>(InterlockedDecrement(ptr));
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// InterlockedVoidPointer.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_InterlockedVoidPointer_h
|
||||
#define INCLUDED_InterlockedVoidPointer_h
|
||||
|
||||
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
class InterlockedVoidPointer
|
||||
{
|
||||
public:
|
||||
explicit InterlockedVoidPointer(void * initialValue=0);
|
||||
void * compareExchange(void * compare, void * exchange); // compare and exchange if same
|
||||
operator void * () const { return reinterpret_cast<void *>(value); }
|
||||
private:
|
||||
InterlockedVoidPointer(const InterlockedVoidPointer &o);
|
||||
InterlockedVoidPointer &operator =(const InterlockedVoidPointer &o);
|
||||
void * volatile value;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class InterlockedPointer: public InterlockedVoidPointer
|
||||
{
|
||||
public:
|
||||
explicit InterlockedPointer(T * initialValue): InterlockedVoidPointer(initialValue) {}
|
||||
operator T * () const { return static_cast<const T *>(value); }
|
||||
};
|
||||
|
||||
inline InterlockedVoidPointer::InterlockedVoidPointer(void * initialValue)
|
||||
{
|
||||
value = initialValue;
|
||||
}
|
||||
|
||||
inline void * InterlockedVoidPointer::compareExchange(void * compare, void * exchange)
|
||||
{
|
||||
return (void *)InterlockedCompareExchange((void **)&value, exchange, compare);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Mutex.cpp
|
||||
//
|
||||
// Copyright 2001-2002 Sony Online Entertainment
|
||||
// All Rights Reserved
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedSynchronization/FirstSharedSynchronization.h"
|
||||
#include "sharedSynchronization/Mutex.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void Mutex::install()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Mutex::remove()
|
||||
{
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
Mutex::Mutex()
|
||||
{
|
||||
InitializeCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
Mutex::~Mutex()
|
||||
{
|
||||
DeleteCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Mutex::enter()
|
||||
{
|
||||
EnterCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void Mutex::leave()
|
||||
{
|
||||
LeaveCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,41 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Mutex.h
|
||||
// Copyright 2001-2002 Sony Online Entertainment
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Mutex_H
|
||||
#define INCLUDED_Mutex_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class Mutex
|
||||
{
|
||||
public:
|
||||
|
||||
static void install();
|
||||
static void remove();
|
||||
|
||||
public:
|
||||
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
void enter();
|
||||
void leave();
|
||||
|
||||
private:
|
||||
|
||||
Mutex(const Mutex &);
|
||||
Mutex &operator =(const Mutex &);
|
||||
|
||||
private:
|
||||
|
||||
CRITICAL_SECTION m_criticalSection;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// RecursiveMutex.cpp
|
||||
//
|
||||
// Copyright 2001-2002 Sony Online Entertainment
|
||||
// All Rights Reserved
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedSynchronization/FirstSharedSynchronization.h"
|
||||
#include "sharedSynchronization/RecursiveMutex.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
void RecursiveMutex::install()
|
||||
{
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void RecursiveMutex::remove()
|
||||
{
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
RecursiveMutex::RecursiveMutex()
|
||||
{
|
||||
InitializeCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
RecursiveMutex::~RecursiveMutex()
|
||||
{
|
||||
DeleteCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void RecursiveMutex::enter()
|
||||
{
|
||||
EnterCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void RecursiveMutex::leave()
|
||||
{
|
||||
LeaveCriticalSection(&m_criticalSection);
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,41 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// RecursiveMutex.h
|
||||
// Copyright 2001-2002 Sony Online Entertainment
|
||||
// All Rights Reserved.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_RecursiveMutex_H
|
||||
#define INCLUDED_RecursiveMutex_H
|
||||
|
||||
// ======================================================================
|
||||
|
||||
class RecursiveMutex
|
||||
{
|
||||
public:
|
||||
|
||||
static void install();
|
||||
static void remove();
|
||||
|
||||
public:
|
||||
|
||||
RecursiveMutex();
|
||||
~RecursiveMutex();
|
||||
|
||||
void enter();
|
||||
void leave();
|
||||
|
||||
private:
|
||||
|
||||
RecursiveMutex(const RecursiveMutex &);
|
||||
RecursiveMutex &operator =(const RecursiveMutex &);
|
||||
|
||||
private:
|
||||
|
||||
CRITICAL_SECTION m_criticalSection;
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Semaphore.cpp
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "sharedSynchronization/FirstSharedSynchronization.h"
|
||||
#include "sharedSynchronization/Semaphore.h"
|
||||
|
||||
Semaphore::Semaphore(int count, int initial)
|
||||
{
|
||||
handle = CreateSemaphore(0, initial, count, 0);
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
void Semaphore::wait()
|
||||
{
|
||||
WaitForSingleObject(handle, INFINITE);
|
||||
}
|
||||
|
||||
void Semaphore::wait(unsigned int maxDurationMs)
|
||||
{
|
||||
WaitForSingleObject(handle, maxDurationMs);
|
||||
}
|
||||
|
||||
void Semaphore::signal(int count)
|
||||
{
|
||||
ReleaseSemaphore(handle, count, 0);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Semaphore.h
|
||||
// Acy Stapp
|
||||
//
|
||||
// Copyright 6/19/2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_Semaphore_h
|
||||
#define INCLUDED_Semaphore_h
|
||||
|
||||
class Semaphore
|
||||
{
|
||||
public:
|
||||
Semaphore(int count=0x7FFFFFFF, int initial=0);
|
||||
~Semaphore();
|
||||
|
||||
void wait();
|
||||
void wait(unsigned int maxDurationMs);
|
||||
void signal(int count=1);
|
||||
private:
|
||||
Semaphore(const Semaphore &o);
|
||||
Semaphore &operator =(const Semaphore &o);
|
||||
HANDLE handle;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user