Merge pull request #601 from martin-osborne/issue_532-3

Issue #532 -  Changes to address `FastMutex` being non-recursive on Win32 platforms
This commit is contained in:
Aleksandar Fabijanic
2015-02-09 21:08:12 -06:00
52 changed files with 695 additions and 95 deletions

View File

@@ -43,7 +43,7 @@ public:
ActiveResultHolder():
_pData(0),
_pExc(0),
_event(false)
_event(Event::EVENT_MANUALRESET)
/// Creates an ActiveResultHolder.
{
}
@@ -149,7 +149,7 @@ class ActiveResultHolder<void>: public RefCountedObject
public:
ActiveResultHolder():
_pExc(0),
_event(false)
_event(Event::EVENT_MANUALRESET)
/// Creates an ActiveResultHolder.
{
}

View File

@@ -84,7 +84,7 @@ public:
_runnable(*pOwner, method),
_stopped(true),
_running(false),
_done(false)
_done(Event::EVENT_MANUALRESET)
/// Creates the activity. Call start() to
/// start it.
{

View File

@@ -46,11 +46,21 @@ class Foundation_API Event: private EventImpl
/// for an event to become signalled.
{
public:
Event(bool autoReset = true);
/// Creates the event. If autoReset is true,
enum EventType
{
EVENT_MANUALRESET = EVENT_MANUALRESET_IMPL, /// Manual reset event
EVENT_AUTORESET = EVENT_AUTORESET_IMPL, /// Auto-reset event
};
explicit Event(EventType type = EVENT_AUTORESET);
/// Creates the event. If type is EVENT_AUTORESET,
/// the event is automatically reset after
/// a wait() successfully returns.
//@ deprecated
explicit Event(bool autoReset);
/// Please use Event::Event(EventType) instead.
~Event();
/// Destroys the event.

View File

@@ -31,8 +31,15 @@ namespace Poco {
class Foundation_API EventImpl
{
public:
enum EventTypeImpl
{
EVENT_MANUALRESET_IMPL,
EVENT_AUTORESET_IMPL,
};
protected:
EventImpl(bool autoReset);
EventImpl(EventTypeImpl type);
~EventImpl();
void setImpl();
void waitImpl();

View File

@@ -30,8 +30,15 @@ namespace Poco {
class Foundation_API EventImpl
{
public:
enum EventTypeImpl
{
EVENT_MANUALRESET_IMPL,
EVENT_AUTORESET_IMPL,
};
protected:
EventImpl(bool autoReset);
EventImpl(EventTypeImpl type);
~EventImpl();
void setImpl();
void waitImpl();

View File

@@ -30,8 +30,15 @@ namespace Poco {
class Foundation_API EventImpl
{
public:
enum EventTypeImpl
{
EVENT_MANUALRESET_IMPL,
EVENT_AUTORESET_IMPL,
};
protected:
EventImpl(bool autoReset);
EventImpl(EventTypeImpl type);
~EventImpl();
void setImpl();
void waitImpl();

View File

@@ -45,20 +45,24 @@ class Foundation_API Mutex: private MutexImpl
/// A Mutex (mutual exclusion) is a synchronization
/// mechanism used to control access to a shared resource
/// in a concurrent (multithreaded) scenario.
/// Mutexes are recursive, that is, the same mutex can be
/// locked multiple times by the same thread (but, of course,
/// not by other threads).
/// Using the ScopedLock class is the preferred way to automatically
/// lock and unlock a mutex.
{
public:
enum MutexType
/// The type of a mutex.
{
MUTEX_RECURSIVE = MUTEX_RECURSIVE_IMPL, /// A recursive mutex
MUTEX_NONRECURSIVE = MUTEX_NONRECURSIVE_IMPL, /// A non-recursive mutex
};
typedef Poco::ScopedLock<Mutex> ScopedLock;
Mutex();
/// creates the Mutex.
explicit Mutex(MutexType type = MUTEX_RECURSIVE);
/// Creates the Mutex.
~Mutex();
/// destroys the Mutex.
/// Destroys the Mutex.
void lock();
/// Locks the mutex. Blocks if the mutex
@@ -99,10 +103,11 @@ private:
class Foundation_API FastMutex: private FastMutexImpl
/// A FastMutex (mutual exclusion) is similar to a Mutex.
/// Unlike a Mutex, however, a FastMutex is not recursive,
/// which means that a deadlock will occur if the same
/// thread tries to lock a mutex it has already locked again.
/// Locking a FastMutex is faster than locking a recursive Mutex.
/// Locking a FastMutex is guaranteed to be at least as
/// fast as locking a Mutex. However, a FastMutex is not
/// guaranteed to be either recursive or non-recursive.
/// It is best suited to thread safe components like pools,
/// caches and queues where locking is internal to the component.
/// Using the ScopedLock class is the preferred way to automatically
/// lock and unlock a mutex.
{

View File

@@ -31,9 +31,15 @@ namespace Poco {
class Foundation_API MutexImpl
{
public:
enum MutexTypeImpl
{
MUTEX_RECURSIVE_IMPL,
MUTEX_NONRECURSIVE_IMPL,
};
protected:
MutexImpl();
MutexImpl(bool fast);
explicit MutexImpl(MutexTypeImpl type);
~MutexImpl();
void lockImpl();
bool tryLockImpl();

View File

@@ -31,9 +31,15 @@ namespace Poco {
class Foundation_API MutexImpl
{
public:
enum MutexTypeImpl
{
MUTEX_RECURSIVE_IMPL,
MUTEX_NONRECURSIVE_IMPL,
};
protected:
MutexImpl();
MutexImpl(bool fast);
explicit MutexImpl(MutexTypeImpl type);
~MutexImpl();
void lockImpl();
bool tryLockImpl();

View File

@@ -30,26 +30,58 @@ namespace Poco {
class Foundation_API MutexImpl
{
public:
enum MutexTypeImpl
{
MUTEX_RECURSIVE_IMPL,
MUTEX_NONRECURSIVE_IMPL,
};
protected:
MutexImpl();
explicit MutexImpl(MutexTypeImpl type);
~MutexImpl();
void lockImpl();
bool tryLockImpl();
bool tryLockImpl(long milliseconds);
void unlockImpl();
private:
CRITICAL_SECTION _cs;
int _lockCount;
const bool _recursive;
private:
MutexImpl(const MutexImpl&);
MutexImpl& operator = (const MutexImpl&);
};
class Foundation_API FastMutexImpl
{
protected:
FastMutexImpl();
~FastMutexImpl();
void lockImpl();
bool tryLockImpl();
bool tryLockImpl(long milliseconds);
void unlockImpl();
private:
CRITICAL_SECTION _cs;
};
typedef MutexImpl FastMutexImpl;
//
// inlines
//
inline void MutexImpl::lockImpl()
inline void MutexImpl::unlockImpl()
{
--_lockCount;
LeaveCriticalSection(&_cs);
}
inline void FastMutexImpl::lockImpl()
{
try
{
@@ -62,7 +94,7 @@ inline void MutexImpl::lockImpl()
}
inline bool MutexImpl::tryLockImpl()
inline bool FastMutexImpl::tryLockImpl()
{
try
{
@@ -75,7 +107,7 @@ inline bool MutexImpl::tryLockImpl()
}
inline void MutexImpl::unlockImpl()
inline void FastMutexImpl::unlockImpl()
{
LeaveCriticalSection(&_cs);
}

View File

@@ -30,22 +30,47 @@ namespace Poco {
class Foundation_API MutexImpl
{
public:
enum MutexTypeImpl
{
MUTEX_RECURSIVE_IMPL,
MUTEX_NONRECURSIVE_IMPL,
};
protected:
MutexImpl();
explicit MutexImpl(MutexTypeImpl type);
~MutexImpl();
void lockImpl();
bool tryLockImpl();
bool tryLockImpl(long milliseconds);
void unlockImpl();
private:
HANDLE _mutex;
int _lockCount;
const bool _recursive;
private:
MutexImpl(const MutexImpl&);
MutexImpl& operator = (const MutexImpl&);
};
class Foundation_API FastMutexImpl
{
protected:
FastMutexImpl();
~FastMutexImpl();
void lockImpl();
bool tryLockImpl();
bool tryLockImpl(long milliseconds);
void unlockImpl();
private:
HANDLE _mutex;
};
typedef MutexImpl FastMutexImpl;
} // namespace Poco

View File

@@ -120,7 +120,7 @@ private:
thread(0),
prio(PRIO_NORMAL_IMPL),
policy(SCHED_OTHER),
done(false),
done(Event::EVENT_MANUALRESET),
stackSize(POCO_THREAD_STACK_SIZE),
started(false),
joined(false)