# HG changeset patch # User Sebastien Jodogne # Date 1398166611 -7200 # Node ID b2a62f22fbe85c713956e0fedbc46f0ca91daec9 # Parent 40d09221077a8cbf94120f0e2e3ad6387cd61e5a lock abstraction diff -r 40d09221077a -r b2a62f22fbe8 CMakeLists.txt --- a/CMakeLists.txt Wed Apr 16 12:12:55 2014 +0200 +++ b/CMakeLists.txt Tue Apr 22 13:36:51 2014 +0200 @@ -166,10 +166,12 @@ Core/RestApi/RestApiPath.cpp Core/RestApi/RestApiOutput.cpp Core/RestApi/RestApi.cpp + Core/MultiThreading/ArrayFilledByThreads.cpp Core/MultiThreading/BagOfRunnablesBySteps.cpp + Core/MultiThreading/Mutex.cpp + Core/MultiThreading/ReaderWriterLock.cpp Core/MultiThreading/SharedMessageQueue.cpp Core/MultiThreading/ThreadedCommandProcessor.cpp - Core/MultiThreading/ArrayFilledByThreads.cpp Core/FileFormats/PngReader.cpp Core/FileFormats/PngWriter.cpp Core/SQLite/Connection.cpp diff -r 40d09221077a -r b2a62f22fbe8 Core/MultiThreading/ILockable.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/MultiThreading/ILockable.h Tue Apr 22 13:36:51 2014 +0200 @@ -0,0 +1,50 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include + +namespace Orthanc +{ + class ILockable : public boost::noncopyable + { + public: + virtual ~ILockable() + { + } + + virtual void Lock() = 0; + + virtual void Unlock() = 0; + }; +} diff -r 40d09221077a -r b2a62f22fbe8 Core/MultiThreading/Locker.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/MultiThreading/Locker.h Tue Apr 22 13:36:51 2014 +0200 @@ -0,0 +1,55 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "ILockable.h" + +namespace Orthanc +{ + class Locker + { + private: + ILockable& lockable_; + + public: + Locker(ILockable& lockable) : lockable_(lockable) + { + lockable_.Lock(); + } + + virtual ~Locker() + { + lockable_.Unlock(); + } + }; +} diff -r 40d09221077a -r b2a62f22fbe8 Core/MultiThreading/Mutex.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/MultiThreading/Mutex.cpp Tue Apr 22 13:36:51 2014 +0200 @@ -0,0 +1,120 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#include "Mutex.h" + +#include "../OrthancException.h" + +#if defined(_WIN32) +#include +#elif defined(__linux) +#include +#else +#error Support your platform here +#endif + +namespace Orthanc +{ +#if defined (_WIN32) + + struct Mutex::PImpl + { + CRITICAL_SECTION criticalSection_; + }; + + Mutex::Mutex() + { + pimpl_ = new PImpl; + ::InitializeCriticalSection(&pimpl_->criticalSection_); + } + + Mutex::~Mutex() + { + ::DeleteCriticalSection(&pimpl_->criticalSection_); + delete pimpl_; + } + + void Mutex::Lock() + { + ::EnterCriticalSection(&pimpl_->criticalSection_); + } + + void Mutex::Unlock() + { + ::LeaveCriticalSection(&pimpl_->criticalSection_); + } + + +#elif defined(__linux) + + struct Mutex::PImpl + { + pthread_mutex_t mutex_; + }; + + Mutex::Mutex() + { + pimpl_ = new PImpl; + + if (pthread_mutex_init(&pimpl_->mutex_, NULL) != 0) + { + delete pimpl_; + throw OrthancException(ErrorCode_InternalError); + } + } + + Mutex::~Mutex() + { + pthread_mutex_destroy(&pimpl_->mutex_); + delete pimpl_; + } + + void Mutex::Lock() + { + if (pthread_mutex_lock(&pimpl_->mutex_) != 0) + { + throw OrthancException(ErrorCode_InternalError); + } + } + + void Mutex::Unlock() + { + if (pthread_mutex_unlock(&pimpl_->mutex_) != 0) + { + throw OrthancException(ErrorCode_InternalError); + } + } + +#else +#error Support your plateform here +#endif +} diff -r 40d09221077a -r b2a62f22fbe8 Core/MultiThreading/Mutex.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/MultiThreading/Mutex.h Tue Apr 22 13:36:51 2014 +0200 @@ -0,0 +1,55 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "ILockable.h" + +namespace Orthanc +{ + class Mutex : public ILockable + { + private: + struct PImpl; + + PImpl *pimpl_; + + public: + Mutex(); + + ~Mutex(); + + virtual void Lock(); + + virtual void Unlock(); + }; +} diff -r 40d09221077a -r b2a62f22fbe8 Core/MultiThreading/ReaderWriterLock.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/MultiThreading/ReaderWriterLock.cpp Tue Apr 22 13:36:51 2014 +0200 @@ -0,0 +1,122 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#include "ReaderWriterLock.h" + +#include + +namespace Orthanc +{ + namespace + { + // Anonymous namespace to avoid clashes between compilation + // modules. + + class ReaderLockable : public ILockable + { + private: + boost::shared_mutex& lock_; + + public: + ReaderLockable(boost::shared_mutex& lock) : lock_(lock) + { + } + + virtual void Lock() + { + lock_.lock_shared(); + } + + virtual void Unlock() + { + lock_.unlock_shared(); + } + }; + + + class WriterLockable : public ILockable + { + private: + boost::shared_mutex& lock_; + + public: + WriterLockable(boost::shared_mutex& lock) : lock_(lock) + { + } + + virtual void Lock() + { + lock_.lock(); + } + + virtual void Unlock() + { + lock_.unlock(); + } + }; + } + + struct ReaderWriterLock::PImpl + { + boost::shared_mutex lock_; + ReaderLockable reader_; + WriterLockable writer_; + + PImpl() : reader_(lock_), writer_(lock_) + { + } + }; + + + ReaderWriterLock::ReaderWriterLock() + { + pimpl_ = new PImpl; + } + + + ReaderWriterLock::~ReaderWriterLock() + { + delete pimpl_; + } + + + ILockable& ReaderWriterLock::ForReader() + { + return pimpl_->reader_; + } + + + ILockable& ReaderWriterLock::ForWriter() + { + return pimpl_->writer_; + } +} diff -r 40d09221077a -r b2a62f22fbe8 Core/MultiThreading/ReaderWriterLock.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Core/MultiThreading/ReaderWriterLock.h Tue Apr 22 13:36:51 2014 +0200 @@ -0,0 +1,55 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege, + * Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * In addition, as a special exception, the copyright holders of this + * program give permission to link the code of its release with the + * OpenSSL project's "OpenSSL" library (or with modified versions of it + * that use the same license as the "OpenSSL" library), and distribute + * the linked executables. You must obey the GNU General Public License + * in all respects for all of the code used other than "OpenSSL". If you + * modify file(s) with this exception, you may extend this exception to + * your version of the file(s), but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. If you delete this exception statement from all source files + * in the program, then also delete it here. + * + * 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + **/ + + +#pragma once + +#include "ILockable.h" + +namespace Orthanc +{ + class ReaderWriterLock + { + private: + struct PImpl; + + PImpl *pimpl_; + + public: + ReaderWriterLock(); + + virtual ~ReaderWriterLock(); + + ILockable& ForReader(); + + ILockable& ForWriter(); + }; +} diff -r 40d09221077a -r b2a62f22fbe8 UnitTestsSources/MultiThreading.cpp --- a/UnitTestsSources/MultiThreading.cpp Wed Apr 16 12:12:55 2014 +0200 +++ b/UnitTestsSources/MultiThreading.cpp Tue Apr 22 13:36:51 2014 +0200 @@ -3,6 +3,9 @@ #include "../Core/OrthancException.h" #include "../Core/Toolbox.h" #include "../Core/MultiThreading/ArrayFilledByThreads.h" +#include "../Core/MultiThreading/Locker.h" +#include "../Core/MultiThreading/Mutex.h" +#include "../Core/MultiThreading/ReaderWriterLock.h" #include "../Core/MultiThreading/ThreadedCommandProcessor.h" using namespace Orthanc; @@ -185,3 +188,25 @@ ASSERT_TRUE(s.find(i) != s.end()); } } + + +TEST(MultiThreading, Mutex) +{ + Mutex mutex; + Locker locker(mutex); +} + + +TEST(MultiThreading, ReaderWriterLock) +{ + ReaderWriterLock lock; + + { + Locker locker1(lock.ForReader()); + Locker locker2(lock.ForReader()); + } + + { + Locker locker3(lock.ForWriter()); + } +} diff -r 40d09221077a -r b2a62f22fbe8 UnitTestsSources/UnitTestsMain.cpp --- a/UnitTestsSources/UnitTestsMain.cpp Wed Apr 16 12:12:55 2014 +0200 +++ b/UnitTestsSources/UnitTestsMain.cpp Tue Apr 22 13:36:51 2014 +0200 @@ -588,7 +588,6 @@ } - int main(int argc, char **argv) { // Initialize Google's logging library.