diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 39737368..23af0205 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -334,6 +334,15 @@ add_files( utility/solution/SolutionParserUtility.h utility/solution/SolutionParserVisualStudio.cpp utility/solution/SolutionParserVisualStudio.h + + utility/synchronization/ReaderWriterLock.cpp + utility/synchronization/ReaderWriterLock.h + utility/synchronization/ScopedReaderLock.cpp + utility/synchronization/ScopedReaderLock.h + utility/synchronization/ScopedWriterLock.cpp + utility/synchronization/ScopedWriterLock.h + utility/synchronization/Semaphore.cpp + utility/synchronization/Semaphore.h utility/text/TextAccess.cpp utility/text/TextAccess.h diff --git a/src/lib/utility/AppPath.h b/src/lib/utility/AppPath.h index b776b06d..c9903404 100644 --- a/src/lib/utility/AppPath.h +++ b/src/lib/utility/AppPath.h @@ -13,7 +13,6 @@ #include #endif // WINDOWS - class AppPath { public: @@ -26,4 +25,4 @@ private: static std::string m_appPath; }; -#endif // APP_PATH_H \ No newline at end of file +#endif // APP_PATH_H diff --git a/src/lib/utility/synchronization/ReaderWriterLock.cpp b/src/lib/utility/synchronization/ReaderWriterLock.cpp new file mode 100644 index 00000000..b385904d --- /dev/null +++ b/src/lib/utility/synchronization/ReaderWriterLock.cpp @@ -0,0 +1,54 @@ +#include "utility/synchronization/ReaderWriterLock.h" + +ReaderWriterLock::ReaderWriterLock() + : m_readerCount(0) + , m_allowedWriters(1) + , m_allowedReaders(1) +{ +} + +ReaderWriterLock::ReaderWriterLock(const ReaderWriterLock &lock) + : m_readerCount(0) + , m_allowedWriters(1) + , m_allowedReaders(1) +{ +} + +ReaderWriterLock::~ReaderWriterLock() +{ +} + +void ReaderWriterLock::readerLock() +{ + m_allowedReaders.wait(); + m_allowedReaders.post(); + + std::lock_guard lock(m_readerCountMutex); + m_readerCount++; + if (m_readerCount == 1) + { + m_allowedWriters.wait(); + } +} + +void ReaderWriterLock::readerUnlock() +{ + std::lock_guard lock(m_readerCountMutex); + m_readerCount--; + if (m_readerCount == 0) + { + m_allowedWriters.post(); + } +} + +void ReaderWriterLock::writerLock() +{ + m_allowedReaders.wait(); + m_allowedWriters.wait(); +} + +void ReaderWriterLock::writerUnlock() +{ + m_allowedWriters.post(); + m_allowedReaders.post(); +} diff --git a/src/lib/utility/synchronization/ReaderWriterLock.h b/src/lib/utility/synchronization/ReaderWriterLock.h new file mode 100644 index 00000000..369daeb5 --- /dev/null +++ b/src/lib/utility/synchronization/ReaderWriterLock.h @@ -0,0 +1,30 @@ +#ifndef READER_WRITER_LOCK_H +#define READER_WRITER_LOCK_H + +#include +#include "Semaphore.h" + +class ReaderWriterLock +{ +public: + ReaderWriterLock(); + +private: + ReaderWriterLock(const ReaderWriterLock &lock); + +public: + ~ReaderWriterLock(); + + void readerLock(); + void readerUnlock(); + void writerLock(); + void writerUnlock(); + +private: + int m_readerCount; + std::mutex m_readerCountMutex; + Semaphore m_allowedReaders, m_allowedWriters; +}; + +#endif // READER_WRITER_LOCK_H + diff --git a/src/lib/utility/synchronization/ScopedReaderLock.cpp b/src/lib/utility/synchronization/ScopedReaderLock.cpp new file mode 100644 index 00000000..ec91c8cf --- /dev/null +++ b/src/lib/utility/synchronization/ScopedReaderLock.cpp @@ -0,0 +1,12 @@ +#include "utility/synchronization/ScopedReaderLock.h" + +ScopedReaderLock::ScopedReaderLock(ReaderWriterLock& lock) + : m_lock(lock) +{ + m_lock.readerLock(); +} + +ScopedReaderLock::~ScopedReaderLock() +{ + m_lock.readerUnlock(); +} diff --git a/src/lib/utility/synchronization/ScopedReaderLock.h b/src/lib/utility/synchronization/ScopedReaderLock.h new file mode 100644 index 00000000..278e02aa --- /dev/null +++ b/src/lib/utility/synchronization/ScopedReaderLock.h @@ -0,0 +1,16 @@ +#ifndef SCOPED_READER_LOCK_H +#define SCOPED_READER_LOCK_H + +#include "utility/synchronization/ReaderWriterLock.h" + +class ScopedReaderLock +{ +public: + ScopedReaderLock(ReaderWriterLock& lock); + ~ScopedReaderLock(); + +private: + ReaderWriterLock& m_lock; +}; + +#endif // SCOPED_READER_LOCK_H diff --git a/src/lib/utility/synchronization/ScopedWriterLock.cpp b/src/lib/utility/synchronization/ScopedWriterLock.cpp new file mode 100644 index 00000000..953e30f6 --- /dev/null +++ b/src/lib/utility/synchronization/ScopedWriterLock.cpp @@ -0,0 +1,12 @@ +#include "utility/synchronization/ScopedWriterLock.h" + +ScopedWriterLock::ScopedWriterLock(ReaderWriterLock& lock) + : m_lock(lock) +{ + m_lock.writerLock(); +} + +ScopedWriterLock::~ScopedWriterLock() +{ + m_lock.writerUnlock(); +} diff --git a/src/lib/utility/synchronization/ScopedWriterLock.h b/src/lib/utility/synchronization/ScopedWriterLock.h new file mode 100644 index 00000000..fb27f59d --- /dev/null +++ b/src/lib/utility/synchronization/ScopedWriterLock.h @@ -0,0 +1,16 @@ +#ifndef SCOPED_WRITER_LOCK_H +#define SCOPED_WRITER_LOCK_H + +#include "utility/synchronization/ReaderWriterLock.h" + +class ScopedWriterLock +{ +public: + ScopedWriterLock(ReaderWriterLock& lock); + ~ScopedWriterLock(); + +private: + ReaderWriterLock& m_lock; +}; + +#endif // SCOPED_WRITER_LOCK_H diff --git a/src/lib/utility/synchronization/Semaphore.cpp b/src/lib/utility/synchronization/Semaphore.cpp new file mode 100644 index 00000000..b9918123 --- /dev/null +++ b/src/lib/utility/synchronization/Semaphore.cpp @@ -0,0 +1,27 @@ +#include "utility/synchronization/Semaphore.h" + +Semaphore::Semaphore(unsigned int counter) + : m_counter(counter) +{ +} + +Semaphore::~Semaphore() +{ +} + +void Semaphore::wait() +{ + std::unique_lock lock(m_counterMutex); + while(m_counter == 0) + { + m_conditionVariable.wait(lock); + } + m_counter--; +} + +void Semaphore::post() +{ + std::unique_lock lock(m_counterMutex); + m_counter++; + m_conditionVariable.notify_one(); +} diff --git a/src/lib/utility/synchronization/Semaphore.h b/src/lib/utility/synchronization/Semaphore.h new file mode 100644 index 00000000..e1701263 --- /dev/null +++ b/src/lib/utility/synchronization/Semaphore.h @@ -0,0 +1,22 @@ +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#include +#include + +class Semaphore +{ +public: + Semaphore(unsigned int counter); + ~Semaphore(); + + void wait(); + void post(); + +private: + unsigned int m_counter; + std::mutex m_counterMutex; + std::condition_variable m_conditionVariable; +}; + +#endif // SEMAPHORE_H