Thread safe map construction and destruction (#223)
authorBalazs Dezso <deba@inf.elte.hu>
Sun, 29 Jan 2012 11:28:41 +0100
changeset 113143a91b33f374
parent 1130 eb252f805431
child 1132 48e17328c155
Thread safe map construction and destruction (#223)

It currently support pthread and windows threads.
CMakeLists.txt
lemon/Makefile.am
lemon/bits/alteration_notifier.h
lemon/bits/lock.h
lemon/bits/windows.cc
lemon/bits/windows.h
lemon/config.h.cmake
lemon/config.h.in
     1.1 --- a/CMakeLists.txt	Fri Jan 20 19:08:00 2012 +0100
     1.2 +++ b/CMakeLists.txt	Sun Jan 29 11:28:41 2012 +0100
     1.3 @@ -114,6 +114,10 @@
     1.4  CHECK_TYPE_SIZE("long long" LONG_LONG)
     1.5  SET(LEMON_HAVE_LONG_LONG ${HAVE_LONG_LONG})
     1.6  
     1.7 +INCLUDE(FindThreads)
     1.8 +SET(LEMON_USE_PTHREAD ${CMAKE_USE_PTHREADS_INIT})
     1.9 +SET(LEMON_USE_WIN32_THREADS ${CMAKE_USE_WIN32_THREADS_INIT})
    1.10 +
    1.11  ENABLE_TESTING()
    1.12  
    1.13  IF(${CMAKE_BUILD_TYPE} STREQUAL "Maintainer")
     2.1 --- a/lemon/Makefile.am	Fri Jan 20 19:08:00 2012 +0100
     2.2 +++ b/lemon/Makefile.am	Sun Jan 29 11:28:41 2012 +0100
     2.3 @@ -138,6 +138,7 @@
     2.4  	lemon/bits/enable_if.h \
     2.5  	lemon/bits/graph_adaptor_extender.h \
     2.6  	lemon/bits/graph_extender.h \
     2.7 +	lemon/bits/lock.h \
     2.8  	lemon/bits/map_extender.h \
     2.9  	lemon/bits/path_dump.h \
    2.10  	lemon/bits/solver_bits.h \
     3.1 --- a/lemon/bits/alteration_notifier.h	Fri Jan 20 19:08:00 2012 +0100
     3.2 +++ b/lemon/bits/alteration_notifier.h	Sun Jan 29 11:28:41 2012 +0100
     3.3 @@ -23,6 +23,7 @@
     3.4  #include <list>
     3.5  
     3.6  #include <lemon/core.h>
     3.7 +#include <lemon/bits/lock.h>
     3.8  
     3.9  //\ingroup graphbits
    3.10  //\file
    3.11 @@ -251,7 +252,7 @@
    3.12  
    3.13      typedef std::list<ObserverBase*> Observers;
    3.14      Observers _observers;
    3.15 -
    3.16 +    lemon::bits::Lock _lock;
    3.17  
    3.18    public:
    3.19  
    3.20 @@ -332,14 +333,18 @@
    3.21    protected:
    3.22  
    3.23      void attach(ObserverBase& observer) {
    3.24 +      _lock.lock();
    3.25        observer._index = _observers.insert(_observers.begin(), &observer);
    3.26        observer._notifier = this;
    3.27 +      _lock.unlock();
    3.28      }
    3.29  
    3.30      void detach(ObserverBase& observer) {
    3.31 +      _lock.lock();
    3.32        _observers.erase(observer._index);
    3.33        observer._index = _observers.end();
    3.34        observer._notifier = 0;
    3.35 +      _lock.unlock();
    3.36      }
    3.37  
    3.38    public:
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/lemon/bits/lock.h	Sun Jan 29 11:28:41 2012 +0100
     4.3 @@ -0,0 +1,65 @@
     4.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
     4.5 + *
     4.6 + * This file is a part of LEMON, a generic C++ optimization library.
     4.7 + *
     4.8 + * Copyright (C) 2003-2012
     4.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    4.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    4.11 + *
    4.12 + * Permission to use, modify and distribute this software is granted
    4.13 + * provided that this copyright notice appears in all copies. For
    4.14 + * precise terms see the accompanying LICENSE file.
    4.15 + *
    4.16 + * This software is provided "AS IS" with no warranty of any kind,
    4.17 + * express or implied, and with no claim as to its suitability for any
    4.18 + * purpose.
    4.19 + *
    4.20 + */
    4.21 +
    4.22 +#ifndef LEMON_BITS_LOCK_H
    4.23 +#define LEMON_BITS_LOCK_H
    4.24 +
    4.25 +#include <lemon/config.h>
    4.26 +#if defined(LEMON_USE_PTHREAD)
    4.27 +#include <pthread.h>
    4.28 +#elif defined(LEMON_USE_WIN32_THREADS)
    4.29 +#include <lemon/bits/windows.h>
    4.30 +#endif
    4.31 +
    4.32 +namespace lemon {
    4.33 +  namespace bits {
    4.34 +
    4.35 +#if defined(LEMON_USE_PTHREAD)
    4.36 +    class Lock {
    4.37 +    public:
    4.38 +      Lock() {
    4.39 +	pthread_mutex_init(&_lock, 0);
    4.40 +      }
    4.41 +      ~Lock() {
    4.42 +	pthread_mutex_destroy(&_lock);
    4.43 +      }
    4.44 +      void lock() {
    4.45 +	pthread_mutex_lock(&_lock);
    4.46 +      }
    4.47 +      void unlock() {
    4.48 +	pthread_mutex_unlock(&_lock);
    4.49 +      }
    4.50 +
    4.51 +    private:
    4.52 +      pthread_mutex_t _lock;
    4.53 +    };
    4.54 +#elif defined(LEMON_USE_WIN32_THREADS)
    4.55 +    class Lock : public WinLock {};
    4.56 +#else
    4.57 +    class Lock {
    4.58 +    public:
    4.59 +      Lock() {}
    4.60 +      ~Lock() {}
    4.61 +      void lock() {}
    4.62 +      void unlock() {}
    4.63 +    };    
    4.64 +#endif
    4.65 +  }
    4.66 +}
    4.67 +
    4.68 +#endif
     5.1 --- a/lemon/bits/windows.cc	Fri Jan 20 19:08:00 2012 +0100
     5.2 +++ b/lemon/bits/windows.cc	Sun Jan 29 11:28:41 2012 +0100
     5.3 @@ -130,5 +130,35 @@
     5.4        return getpid() + tv.tv_sec + tv.tv_usec;
     5.5  #endif
     5.6      }
     5.7 +
     5.8 +    WinLock::WinLock() {
     5.9 +#ifdef WIN32
    5.10 +      CRITICAL_SECTION *lock = new CRITICAL_SECTION;
    5.11 +      InitializeCriticalSection(lock);
    5.12 +      _repr = lock;
    5.13 +#endif
    5.14 +    }
    5.15 +    
    5.16 +    WinLock::~WinLock() {
    5.17 +#ifdef WIN32
    5.18 +      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
    5.19 +      DeleteCriticalSection(lock);
    5.20 +      delete lock;
    5.21 +#endif
    5.22 +    }
    5.23 +
    5.24 +    void WinLock::lock() {
    5.25 +#ifdef WIN32
    5.26 +      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
    5.27 +      EnterCriticalSection(lock);
    5.28 +#endif
    5.29 +    }
    5.30 +
    5.31 +    void WinLock::unlock() {
    5.32 +#ifdef WIN32
    5.33 +      CRITICAL_SECTION *lock = static_cast<CRITICAL_SECTION*>(_repr);
    5.34 +      LeaveCriticalSection(lock);
    5.35 +#endif
    5.36 +    }
    5.37    }
    5.38  }
     6.1 --- a/lemon/bits/windows.h	Fri Jan 20 19:08:00 2012 +0100
     6.2 +++ b/lemon/bits/windows.h	Sun Jan 29 11:28:41 2012 +0100
     6.3 @@ -28,6 +28,16 @@
     6.4                           double &cutime, double &cstime);
     6.5      std::string getWinFormattedDate();
     6.6      int getWinRndSeed();
     6.7 +
     6.8 +    class WinLock {
     6.9 +    public:
    6.10 +      WinLock();
    6.11 +      ~WinLock();
    6.12 +      void lock();
    6.13 +      void unlock();
    6.14 +    private:
    6.15 +      void *_repr;
    6.16 +    };
    6.17    }
    6.18  }
    6.19  
     7.1 --- a/lemon/config.h.cmake	Fri Jan 20 19:08:00 2012 +0100
     7.2 +++ b/lemon/config.h.cmake	Sun Jan 29 11:28:41 2012 +0100
     7.3 @@ -6,3 +6,5 @@
     7.4  #cmakedefine LEMON_HAVE_CPLEX 1
     7.5  #cmakedefine LEMON_HAVE_CLP 1
     7.6  #cmakedefine LEMON_HAVE_CBC 1
     7.7 +#cmakedefine LEMON_USE_PTHREAD 1
     7.8 +#cmakedefine LEMON_USE_WIN32_THREADS 1
     8.1 --- a/lemon/config.h.in	Fri Jan 20 19:08:00 2012 +0100
     8.2 +++ b/lemon/config.h.in	Sun Jan 29 11:28:41 2012 +0100
     8.3 @@ -24,3 +24,9 @@
     8.4  
     8.5  /* Define to 1 if you have CBC */
     8.6  #undef LEMON_HAVE_CBC
     8.7 +
     8.8 +/* Define to 1 if you have pthread */
     8.9 +#undef LEMON_USE_PTHREAD
    8.10 +
    8.11 +/* Define to 1 if you have win32 threads */
    8.12 +#undef LEMON_USE_WIN32_THREADS