Skip to content

Commit

Permalink
Complimentary to #3918 (std::*mutex wrapper) (#3954)
Browse files Browse the repository at this point in the history
* Complimentary to #3918
I think that we can use Poco::Mutex and Poco::FastMutex as wrappers for std::recursive_mutex and std::mutex instead of replacing

For using std::*mutexes switch on cmake-option POCO_ENABLE_STD_MUTEX

* add define POCO_ENABLE_STD_MUTEX to the Config.h
remove empty if-else from CMakeLists.txt
  • Loading branch information
bas524 authored May 5, 2023
1 parent 971a7cc commit c7ac857
Show file tree
Hide file tree
Showing 6 changed files with 272 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ if(POCO_NO_FORK_EXEC)
add_definitions(-DPOCO_NO_FORK_EXEC=1)
endif()

option(POCO_ENABLE_STD_MUTEX "Set to OFF|NO using mutex from standard library (default OFF)" OFF)

if (POCO_ENABLE_STD_MUTEX)
add_definitions(-DPOCO_ENABLE_STD_MUTEX)
endif ()
include(DefinePlatformSpecifc)

# Collect the built libraries and include dirs, the will be used to create the PocoConfig.cmake file
Expand Down
6 changes: 5 additions & 1 deletion Foundation/include/Poco/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,5 +208,9 @@
// Disarm POCO_DEPRECATED macro.
// #define POCO_NO_DEPRECATED


// Enable usage of Poco::Mutex and Poco::FastMutex
// as wrappers for std::recursive_mutex and std::mutex
#ifndef POCO_ENABLE_STD_MUTEX
// #define POCO_ENABLE_STD_MUTEX
#endif
#endif // Foundation_Config_INCLUDED
5 changes: 4 additions & 1 deletion Foundation/include/Poco/Mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
#include "Poco/Timestamp.h"
#include <atomic>


#ifdef POCO_ENABLE_STD_MUTEX
#include "Poco/Mutex_STD.h"
#else
#if defined(POCO_OS_FAMILY_WINDOWS)
#if defined(_WIN32_WCE)
#include "Poco/Mutex_WINCE.h"
Expand All @@ -36,6 +38,7 @@
#else
#include "Poco/Mutex_POSIX.h"
#endif
#endif


namespace Poco {
Expand Down
135 changes: 135 additions & 0 deletions Foundation/include/Poco/Mutex_STD.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
//
// Mutex_STD.h
//
// Library: Foundation
// Package: Threading
// Module: Mutex
//
// Definition of the MutexImpl and FastMutexImpl classes based on Standard library mutex and recursive mutes.
//
// Copyright (c) 2004-2023, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//


#ifndef Foundation_Mutex_STD_INCLUDED
#define Foundation_Mutex_STD_INCLUDED


#include "Poco/Foundation.h"
#include "Poco/Exception.h"
#include <mutex>


namespace Poco {


class Foundation_API MutexImpl
{
protected:
MutexImpl();
~MutexImpl();
void lockImpl();
bool tryLockImpl();
bool tryLockImpl(long milliseconds);
void unlockImpl();

private:
std::recursive_mutex _mutex;
};


class Foundation_API FastMutexImpl
{
protected:
FastMutexImpl();
~FastMutexImpl();
void lockImpl();
bool tryLockImpl();
bool tryLockImpl(long milliseconds);
void unlockImpl();
private:
std::mutex _mutex;
};


//
// inlines
//
inline void MutexImpl::lockImpl()
{
try
{
_mutex.lock();
}
catch (std::exception &ex) {
throw SystemException("cannot lock mutex", ex.what());
}
}


inline bool MutexImpl::tryLockImpl()
{
try
{
return _mutex.try_lock();
}
catch (std::exception &ex)
{
throw SystemException("cannot lock mutex", ex.what());
}
}


inline void MutexImpl::unlockImpl()
{
try
{
_mutex.unlock();
}
catch (std::exception &ex) {
throw SystemException("cannot unlock mutex");
}
}

inline void FastMutexImpl::lockImpl()
{
try
{
_mutex.lock();
}
catch (std::exception &ex) {
throw SystemException("cannot lock mutex", ex.what());
}
}


inline bool FastMutexImpl::tryLockImpl()
{
try
{
return _mutex.try_lock();
}
catch (std::exception &ex)
{
throw SystemException("cannot lock mutex", ex.what());
}
}


inline void FastMutexImpl::unlockImpl()
{
try
{
_mutex.unlock();
}
catch (std::exception &ex) {
throw SystemException("cannot unlock mutex");
}
}

} // namespace Poco

#endif //Foundation_Mutex_STD_INCLUDED
5 changes: 3 additions & 2 deletions Foundation/src/Mutex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@

#include "Poco/Mutex.h"


#if defined(POCO_OS_FAMILY_WINDOWS)
#if defined(POCO_ENABLE_STD_MUTEX)
#include "Mutex_STD.cpp"
#elif defined(POCO_OS_FAMILY_WINDOWS)
#if defined(_WIN32_WCE)
#include "Mutex_WINCE.cpp"
#else
Expand Down
120 changes: 120 additions & 0 deletions Foundation/src/Mutex_STD.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
//
// Mutex_STD.cpp
//
// Library: Foundation
// Package: Threading
// Module: Mutex
//
// Copyright (c) 2004-2023, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//


#include "Poco/Mutex_STD.h"
#include "Poco/Timestamp.h"
#if !defined(POCO_NO_SYS_SELECT_H)
#include <sys/select.h>
#endif
#include <unistd.h>
#if defined(POCO_VXWORKS)
#include <timers.h>
#include <cstring>
#else
#include <sys/time.h>
#endif


namespace Poco {


MutexImpl::MutexImpl() : _mutex()
{
}

MutexImpl::~MutexImpl()
{
}


bool MutexImpl::tryLockImpl(long milliseconds)
{
const int sleepMillis = 5;
Timestamp now;
Timestamp::TimeDiff diff(Timestamp::TimeDiff(milliseconds)*1000);
do
{
bool rc = false;
try
{
rc = _mutex.try_lock();
if (rc)
return true;
}
catch (std::exception &ex)
{
throw SystemException("cannot lock mutex", ex.what());
}
#if defined(POCO_VXWORKS)
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = sleepMillis*1000000;
nanosleep(&ts, NULL);
#else
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = sleepMillis * 1000;
select(0, nullptr, nullptr, nullptr, &tv);
#endif
}
while (!now.isElapsed(diff));
return false;

}


FastMutexImpl::FastMutexImpl(): _mutex()
{
}


FastMutexImpl::~FastMutexImpl()
{
}

bool FastMutexImpl::tryLockImpl(long milliseconds)
{
const int sleepMillis = 5;
Timestamp now;
Timestamp::TimeDiff diff(Timestamp::TimeDiff(milliseconds)*1000);
do
{
bool rc = false;
try
{
rc = _mutex.try_lock();
if (rc)
return true;
}
catch (std::exception &ex)
{
throw SystemException("cannot lock mutex", ex.what());
}
#if defined(POCO_VXWORKS)
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = sleepMillis*1000000;
nanosleep(&ts, NULL);
#else
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = sleepMillis * 1000;
select(0, NULL, NULL, NULL, &tv);
#endif
}
while (!now.isElapsed(diff));
return false;

}
} // namespace Poco

0 comments on commit c7ac857

Please sign in to comment.