# HG changeset patch # User Balazs Dezso # Date 2012-01-29 11:28:41 # Node ID 43a91b33f3747428f70be1da8dbdf9da4edb3d2a # Parent eb252f805431c5ec10c258ef603cf1c8460ba977 Thread safe map construction and destruction (#223) It currently support pthread and windows threads. diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,6 +114,10 @@ CHECK_TYPE_SIZE("long long" LONG_LONG) SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG}) +INCLUDE(FindThreads) +SET(LEMON_USE_PTHREAD ${CMAKE_USE_PTHREADS_INIT}) +SET(LEMON_USE_WIN32_THREADS ${CMAKE_USE_WIN32_THREADS_INIT}) + ENABLE_TESTING() IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer") diff --git a/lemon/Makefile.am b/lemon/Makefile.am --- a/lemon/Makefile.am +++ b/lemon/Makefile.am @@ -138,6 +138,7 @@ lemon/bits/enable_if.h \ lemon/bits/graph_adaptor_extender.h \ lemon/bits/graph_extender.h \ + lemon/bits/lock.h \ lemon/bits/map_extender.h \ lemon/bits/path_dump.h \ lemon/bits/solver_bits.h \ diff --git a/lemon/bits/alteration_notifier.h b/lemon/bits/alteration_notifier.h --- a/lemon/bits/alteration_notifier.h +++ b/lemon/bits/alteration_notifier.h @@ -23,6 +23,7 @@ #include #include +#include //\ingroup graphbits //\file @@ -251,7 +252,7 @@ typedef std::list Observers; Observers _observers; - + lemon::bits::Lock _lock; public: @@ -332,14 +333,18 @@ protected: void attach(ObserverBase& observer) { + _lock.lock(); observer._index = _observers.insert(_observers.begin(), &observer); observer._notifier = this; + _lock.unlock(); } void detach(ObserverBase& observer) { + _lock.lock(); _observers.erase(observer._index); observer._index = _observers.end(); observer._notifier = 0; + _lock.unlock(); } public: diff --git a/lemon/bits/lock.h b/lemon/bits/lock.h new file mode 100644 --- /dev/null +++ b/lemon/bits/lock.h @@ -0,0 +1,65 @@ +/* -*- mode: C++; indent-tabs-mode: nil; -*- + * + * This file is a part of LEMON, a generic C++ optimization library. + * + * Copyright (C) 2003-2012 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_BITS_LOCK_H +#define LEMON_BITS_LOCK_H + +#include +#if defined(LEMON_USE_PTHREAD) +#include +#elif defined(LEMON_USE_WIN32_THREADS) +#include +#endif + +namespace lemon { + namespace bits { + +#if defined(LEMON_USE_PTHREAD) + class Lock { + public: + Lock() { + pthread_mutex_init(&_lock, 0); + } + ~Lock() { + pthread_mutex_destroy(&_lock); + } + void lock() { + pthread_mutex_lock(&_lock); + } + void unlock() { + pthread_mutex_unlock(&_lock); + } + + private: + pthread_mutex_t _lock; + }; +#elif defined(LEMON_USE_WIN32_THREADS) + class Lock : public WinLock {}; +#else + class Lock { + public: + Lock() {} + ~Lock() {} + void lock() {} + void unlock() {} + }; +#endif + } +} + +#endif diff --git a/lemon/bits/windows.cc b/lemon/bits/windows.cc --- a/lemon/bits/windows.cc +++ b/lemon/bits/windows.cc @@ -130,5 +130,35 @@ return getpid() + tv.tv_sec + tv.tv_usec; #endif } + + WinLock::WinLock() { +#ifdef WIN32 + CRITICAL_SECTION *lock = new CRITICAL_SECTION; + InitializeCriticalSection(lock); + _repr = lock; +#endif + } + + WinLock::~WinLock() { +#ifdef WIN32 + CRITICAL_SECTION *lock = static_cast(_repr); + DeleteCriticalSection(lock); + delete lock; +#endif + } + + void WinLock::lock() { +#ifdef WIN32 + CRITICAL_SECTION *lock = static_cast(_repr); + EnterCriticalSection(lock); +#endif + } + + void WinLock::unlock() { +#ifdef WIN32 + CRITICAL_SECTION *lock = static_cast(_repr); + LeaveCriticalSection(lock); +#endif + } } } diff --git a/lemon/bits/windows.h b/lemon/bits/windows.h --- a/lemon/bits/windows.h +++ b/lemon/bits/windows.h @@ -28,6 +28,16 @@ double &cutime, double &cstime); std::string getWinFormattedDate(); int getWinRndSeed(); + + class WinLock { + public: + WinLock(); + ~WinLock(); + void lock(); + void unlock(); + private: + void *_repr; + }; } } diff --git a/lemon/config.h.cmake b/lemon/config.h.cmake --- a/lemon/config.h.cmake +++ b/lemon/config.h.cmake @@ -6,3 +6,5 @@ #cmakedefine LEMON_HAVE_CPLEX 1 #cmakedefine LEMON_HAVE_CLP 1 #cmakedefine LEMON_HAVE_CBC 1 +#cmakedefine LEMON_USE_PTHREAD 1 +#cmakedefine LEMON_USE_WIN32_THREADS 1 diff --git a/lemon/config.h.in b/lemon/config.h.in --- a/lemon/config.h.in +++ b/lemon/config.h.in @@ -24,3 +24,9 @@ /* Define to 1 if you have CBC */ #undef LEMON_HAVE_CBC + +/* Define to 1 if you have pthread */ +#undef LEMON_USE_PTHREAD + +/* Define to 1 if you have win32 threads */ +#undef LEMON_USE_WIN32_THREADS