diff --git a/doc/dox/jkqtcommon.dox b/doc/dox/jkqtcommon.dox index 6a3a9d4d4b..d02f89931f 100644 --- a/doc/dox/jkqtcommon.dox +++ b/doc/dox/jkqtcommon.dox @@ -23,6 +23,9 @@ Offers diverse function to convert different datatypes (e.g. double, int, divers \defgroup jkqtptools_qt Tools around Qt's clasess \ingroup jkqtptools_jkqtcommon +\defgroup jkqtptools_concurrency Tools, Templates and Classes for Concurrency +\ingroup jkqtptools_jkqtcommon + \defgroup jkqtptools_icons Special QIcon generation \ingroup jkqtptools_jkqtcommon diff --git a/lib/jkqtcommon/jkqtpconcurrencytools.cpp b/lib/jkqtcommon/jkqtpconcurrencytools.cpp new file mode 100644 index 0000000000..cdf98ade2b --- /dev/null +++ b/lib/jkqtcommon/jkqtpconcurrencytools.cpp @@ -0,0 +1,22 @@ +/* + Copyright (c) 2008-2023 Jan W. Krieger () + + last modification: $LastChangedDate$ (revision $Rev$) + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program 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 (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + +#include "jkqtpconcurrencytools.h" diff --git a/lib/jkqtcommon/jkqtpconcurrencytools.h b/lib/jkqtcommon/jkqtpconcurrencytools.h new file mode 100644 index 0000000000..c84989ef8a --- /dev/null +++ b/lib/jkqtcommon/jkqtpconcurrencytools.h @@ -0,0 +1,147 @@ +/* + Copyright (c) 2008-2023 Jan W. Krieger () + + last modification: $LastChangedDate$ (revision $Rev$) + + This software is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License (LGPL) as published by + the Free Software Foundation, either version 2.1 of the License, or + (at your option) any later version. + + This program 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 (LGPL) for more details. + + You should have received a copy of the GNU Lesser General Public License (LGPL) + along with this program. If not, see . +*/ + + + + + +#ifndef JKQTPCONCURRENCYTOOLS_H +#define JKQTPCONCURRENCYTOOLS_H + +#include "jkqtcommon/jkqtcommon_imexport.h" +#include + +/** \brief template class that wraps any datatype and combines it with a mutex, exposes the lock()/unlock() + * interface, so access to the contained data can be synchronized + * \ingroup jkqtptools_concurrency + * + * + */ +template +class JKQTPSynchronized { +public: + /** \brief Mutex used by this temmplate */ + typedef std::mutex MutexType; + /** \brief type of a lock_guard for a JKQTPSynchronized */ + typedef std::lock_guard > Locker; + /** \brief contained data type T */ + typedef T data_type; + /** \brief default constructor, the internal data is default-initialized */ + inline JKQTPSynchronized(): m_data() {} + /** \brief initializing constructor, the internal data is initialized with \a d */ + inline JKQTPSynchronized(const T& d): m_data(d) {} + /** \brief initializing constructor, the internal data is initialized with \a d */ + inline JKQTPSynchronized(T&& d): m_data(std::forward(d)) {} + /** \brief locks \a other and copies its contents to this new class */ + inline JKQTPSynchronized(const JKQTPSynchronized& other): m_data() { + Locker lock(other); + m_data=other.m_data; + } + /** \brief locks \a other and moves its contents to this new class. The mutex in \a other is NOT moved! */ + inline JKQTPSynchronized(JKQTPSynchronized&& other): m_data() { + Locker lock(other); + m_data=std::move(other.m_data); + } + + /** \brief creates and returns a Locker-Object for this class, which is already locked */ + inline Locker get_lock() { + return Locker(*this); + } + /** \brief locks the internal mutex until unlock() is called, + * + * \note Use Locker instances to actually lock, using a RAII-idiom, as this is safer than doing this by hand! + */ + inline void lock() { + m_mutex.lock(); + } + /** \brief unlocks the internal mutex from a previous lock() call + * + * \note Use Locker instances to actually lock, using a RAII-idiom, as this is safer than doing this by hand! + */ + inline void unlock() { + m_mutex.unlock(); + } + /** \brief assign a value to the internal data storage, not thread-safe. + * + * \note You need to lock this object before calling this function. + */ + inline void set(const T& d) { + m_data=d; + } + /** \brief assign a value to the internal data storage, not thread-safe. + * + * \note You need to lock this object before calling this function. + */ + inline void set(T&& d) { + m_data=std::forward(d); + } + /** \brief assign a value to the internal data storage, thread-safe. + */ + inline void set_safe(const T& d) { + Locker lck(m_mutex); + m_data=d; + } + /** \brief assign a value to the internal data storage, \b thread-safe. + */ + inline void set_safe(T&& d) { + Locker lck(m_mutex); + m_data=std::forward(d); + } + /** \brief returns the internal data as a mutable reference, not thread-safe. + * + * \note You need to lock this object before calling this function. + */ + inline T& get() { + return m_data; + } + /** \brief returns the internal data as a mutable reference, not thread-safe. + * + * \note You need to lock this object before calling this function. + */ + inline const T& get() const { + return m_data; + } + /** \brief gives access to the internal data, not thread-safe. + * + * \note You need to lock this object before calling this function. + */ + inline const T* operator->() const { + return &m_data; + } + /** \brief gives access to the internal data, not thread-safe. + * + * \note You need to lock this object before calling this function. + */ + inline T* operator->() { + return &m_data; + } + /** \brief returns the value in the internal data storage, thread-safe. + */ + inline T get_safe() const { + Locker lck(m_mutex); + return m_data; + } + +private: + T m_data; + mutable MutexType m_mutex; + +}; + +#endif // JKQTPCONCURRENCYTOOLS_H