mirror of https://github.com/swig/swig
[python, ruby] Add Director guard file with C++ 11 std::mutex (#2870)
* Improve mutex for director use: - Use C++ 11 mutex and lock classes. Most compilers support C++ 11 by default. Leave Win32 and POSIX support for older compiler. - Use a single file for Python and Ruby. - Use macro also for guard definition instead of using '#ifdef'. - Rename old '__THREAD__' to 'SWIG_THREADS' to avoid collide with other libraries. - Remove the use of '__PTHREAD__' as it may collide with other libraries. - Remove mutex from OCaml, as it is not used in Director class. Signed-off-by: Erez Geva <ErezGeva2@gmail.com> * Fixes follow @wsfulton. Improve description of director_guard.swg. Remove duplicate line. Change to SWIG_GUARD_DEFINITION and SWIG_GUARD_DECLARATION as full English words are much more easily understood than abbreviations. Signed-off-by: Erez Geva <ErezGeva2@gmail.com> --------- Signed-off-by: Erez Geva <ErezGeva2@gmail.com>
This commit is contained in:
parent
a24461dbac
commit
2e9d570194
|
@ -0,0 +1,104 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* director_guard.swg
|
||||||
|
*
|
||||||
|
* Generic Mutex implementation
|
||||||
|
*
|
||||||
|
* Before calling the file, you may choose the following:
|
||||||
|
* - SWIG_THREADS:
|
||||||
|
* If set than we use mutexs.
|
||||||
|
* If not set we do not use mutexs.
|
||||||
|
* - SWIG_HAVE_MUTEX:
|
||||||
|
* If you have a language defined 'Mutex' class, set this flag.
|
||||||
|
* The language 'Mutex' class need to be a Basic Lockable.
|
||||||
|
* It must have public 'void lock()' and 'void unlock()' methods.
|
||||||
|
* See: https://en.cppreference.com/w/cpp/named_req/BasicLockable
|
||||||
|
* If the flag is unset, use one of the following in that order:
|
||||||
|
* - C++ 11 or above, use std::mutex.
|
||||||
|
* - Win32 use CRITICAL_SECTION.
|
||||||
|
* - Use POSIX Pthread mutex.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#ifdef SWIG_THREADS
|
||||||
|
|
||||||
|
#if __cplusplus >= 201103L
|
||||||
|
/*
|
||||||
|
* C++ 11 or above
|
||||||
|
* std::mutex https://en.cppreference.com/w/cpp/thread/mutex
|
||||||
|
* std::unique_lock https://en.cppreference.com/w/cpp/thread/unique_lock
|
||||||
|
*/
|
||||||
|
#include <mutex>
|
||||||
|
#ifdef SWIG_HAVE_MUTEX
|
||||||
|
/* Use Language defined Mutex class */
|
||||||
|
#define SWIG_GUARD(_mutex) std::unique_lock<Mutex> _guard(_mutex)
|
||||||
|
#define SWIG_GUARD_DEFINITION(_cls, _mutex) Mutex _cls::_mutex
|
||||||
|
#define SWIG_GUARD_DECLARATION(_mutex) static Mutex _mutex
|
||||||
|
#else
|
||||||
|
#define SWIG_GUARD(_mutex) std::unique_lock<std::mutex> _guard(_mutex)
|
||||||
|
#define SWIG_GUARD_DEFINITION(_cls, _mutex) std::mutex _cls::_mutex
|
||||||
|
#define SWIG_GUARD_DECLARATION(_mutex) static std::mutex _mutex
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* __cplusplus */
|
||||||
|
|
||||||
|
#ifdef SWIG_HAVE_MUTEX
|
||||||
|
/* Use Language defined Mutex class */
|
||||||
|
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
/*
|
||||||
|
* Windows Critical Section Objects
|
||||||
|
* https://learn.microsoft.com/en-us/windows/win32/Sync/critical-section-objects
|
||||||
|
*/
|
||||||
|
#include <windows.h>
|
||||||
|
#include <synchapi.h>
|
||||||
|
namespace Swig {
|
||||||
|
class Mutex {
|
||||||
|
CRITICAL_SECTION mutex_;
|
||||||
|
public:
|
||||||
|
Mutex() { InitializeCriticalSection(&mutex_); }
|
||||||
|
~Mutex() { DeleteCriticalSection(&mutex_); }
|
||||||
|
void lock() { EnterCriticalSection(&mutex_); }
|
||||||
|
void unlock() { LeaveCriticalSection(&mutex_); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* _WIN32 */
|
||||||
|
/*
|
||||||
|
* POSIX Thread mutex
|
||||||
|
* https://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html
|
||||||
|
*/
|
||||||
|
#include <pthread.h>
|
||||||
|
namespace Swig {
|
||||||
|
class Mutex {
|
||||||
|
pthread_mutex_t mutex_;
|
||||||
|
public:
|
||||||
|
Mutex() { pthread_mutex_init(&mutex_, NULL); }
|
||||||
|
~Mutex() { pthread_mutex_destroy(&mutex_); }
|
||||||
|
void lock() { pthread_mutex_lock(&mutex_); }
|
||||||
|
void unlock() { pthread_mutex_unlock(&mutex_); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
namespace Swig {
|
||||||
|
class Unique_lock {
|
||||||
|
Mutex &mutex_;
|
||||||
|
public:
|
||||||
|
Unique_lock(Mutex &_mutex) : mutex_(_mutex) { mutex_.lock(); }
|
||||||
|
~Unique_lock() { mutex_.unlock(); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#define SWIG_GUARD(_mutex) Unique_lock _guard(_mutex)
|
||||||
|
#define SWIG_GUARD_DEFINITION(_cls, _mutex) Mutex _cls::_mutex
|
||||||
|
#define SWIG_GUARD_DECLARATION(_mutex) static Mutex _mutex
|
||||||
|
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#else /* SWIG_THREADS */
|
||||||
|
|
||||||
|
#define SWIG_GUARD(_mutex)
|
||||||
|
#define SWIG_GUARD_DEFINITION(_cls, _mutex)
|
||||||
|
#define SWIG_GUARD_DECLARATION(_mutex)
|
||||||
|
|
||||||
|
#endif /* SWIG_THREADS */
|
|
@ -49,20 +49,6 @@ namespace Swig {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* simple thread abstraction for pthreads on win32 */
|
|
||||||
#ifdef __THREAD__
|
|
||||||
#define __PTHREAD__
|
|
||||||
#if defined(_WIN32) || defined(__WIN32__)
|
|
||||||
#define pthread_mutex_lock EnterCriticalSection
|
|
||||||
#define pthread_mutex_unlock LeaveCriticalSection
|
|
||||||
#define pthread_mutex_t CRITICAL_SECTION
|
|
||||||
#define MUTEX_INIT(var) CRITICAL_SECTION var
|
|
||||||
#else
|
|
||||||
#include <pthread.h>
|
|
||||||
#define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* director base class */
|
/* director base class */
|
||||||
class Director {
|
class Director {
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -14,25 +14,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#if defined(SWIG_PYTHON_THREADS)
|
|
||||||
/* __THREAD__ is the old macro to activate some thread support */
|
|
||||||
# if !defined(__THREAD__)
|
|
||||||
# define __THREAD__ 1
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __THREAD__
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
# include "pythread.h"
|
|
||||||
#else
|
|
||||||
# if defined(_WIN32)
|
|
||||||
# include <windows.h>
|
|
||||||
# else
|
|
||||||
# include <pthread.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Use -DSWIG_PYTHON_DIRECTOR_NO_VTABLE if you don't want to generate a 'virtual
|
Use -DSWIG_PYTHON_DIRECTOR_NO_VTABLE if you don't want to generate a 'virtual
|
||||||
table', and avoid multiple GetAttr calls to retrieve the python
|
table', and avoid multiple GetAttr calls to retrieve the python
|
||||||
|
@ -262,95 +243,6 @@ namespace Swig {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef __THREAD__
|
|
||||||
#ifndef Py_LIMITED_API
|
|
||||||
class Mutex
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Mutex() {
|
|
||||||
mutex_ = PyThread_allocate_lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
~Mutex() {
|
|
||||||
PyThread_release_lock(mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Lock() {
|
|
||||||
PyThread_acquire_lock(mutex_, WAIT_LOCK);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Unlock() {
|
|
||||||
PyThread_free_lock(mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
PyThread_type_lock mutex_;
|
|
||||||
|
|
||||||
friend class Guard;
|
|
||||||
};
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
class Mutex : private CRITICAL_SECTION {
|
|
||||||
public:
|
|
||||||
Mutex() {
|
|
||||||
InitializeCriticalSection(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Mutex() {
|
|
||||||
DeleteCriticalSection(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Lock() {
|
|
||||||
EnterCriticalSection(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Unlock() {
|
|
||||||
LeaveCriticalSection(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
friend class Guard;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
class Mutex {
|
|
||||||
public:
|
|
||||||
Mutex() {
|
|
||||||
pthread_mutex_init(&mutex_, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Mutex() {
|
|
||||||
pthread_mutex_destroy(&mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Lock() {
|
|
||||||
pthread_mutex_lock(&mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Unlock() {
|
|
||||||
pthread_mutex_unlock(&mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
friend class Guard;
|
|
||||||
|
|
||||||
pthread_mutex_t mutex_;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
class Guard {
|
|
||||||
Mutex &mutex_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Guard(Mutex & mutex) : mutex_(mutex) {
|
|
||||||
mutex_.Lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
~Guard() {
|
|
||||||
mutex_.Unlock();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
# define SWIG_GUARD(mutex) Guard _guard(mutex)
|
|
||||||
#else
|
|
||||||
# define SWIG_GUARD(mutex)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* director base class */
|
/* director base class */
|
||||||
class Director {
|
class Director {
|
||||||
|
@ -411,9 +303,7 @@ namespace Swig {
|
||||||
private:
|
private:
|
||||||
typedef std::map<void *, GCItem_var> swig_ownership_map;
|
typedef std::map<void *, GCItem_var> swig_ownership_map;
|
||||||
mutable swig_ownership_map swig_owner;
|
mutable swig_ownership_map swig_owner;
|
||||||
#ifdef __THREAD__
|
SWIG_GUARD_DECLARATION(swig_mutex_own);
|
||||||
static Mutex swig_mutex_own;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
|
@ -463,9 +353,7 @@ namespace Swig {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __THREAD__
|
SWIG_GUARD_DEFINITION(Director, swig_mutex_own);
|
||||||
Mutex Director::swig_mutex_own;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
* director_py_mutex.swg
|
||||||
|
*
|
||||||
|
* contains python mutex for threads
|
||||||
|
* ----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if defined(SWIG_PYTHON_THREADS) && !defined(SWIG_THREADS)
|
||||||
|
#define SWIG_THREADS 1
|
||||||
|
#endif
|
||||||
|
#if defined(SWIG_THREADS) && !defined(Py_LIMITED_API)
|
||||||
|
#include "pythread.h"
|
||||||
|
#define SWIG_HAVE_MUTEX
|
||||||
|
namespace Swig {
|
||||||
|
class Mutex
|
||||||
|
{
|
||||||
|
PyThread_type_lock mutex_;
|
||||||
|
public:
|
||||||
|
Mutex() : mutex_(PyThread_allocate_lock()) {}
|
||||||
|
~Mutex() { PyThread_release_lock(mutex_); }
|
||||||
|
void lock() { PyThread_acquire_lock(mutex_, WAIT_LOCK); }
|
||||||
|
void unlock() { PyThread_free_lock(mutex_); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -202,37 +202,6 @@ namespace Swig {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Simple thread abstraction for pthreads on win32 */
|
|
||||||
#ifdef __THREAD__
|
|
||||||
# define __PTHREAD__
|
|
||||||
# if defined(_WIN32) || defined(__WIN32__)
|
|
||||||
# define pthread_mutex_lock EnterCriticalSection
|
|
||||||
# define pthread_mutex_unlock LeaveCriticalSection
|
|
||||||
# define pthread_mutex_t CRITICAL_SECTION
|
|
||||||
# define SWIG_MUTEX_INIT(var) var
|
|
||||||
# else
|
|
||||||
# include <pthread.h>
|
|
||||||
# define SWIG_MUTEX_INIT(var) var = PTHREAD_MUTEX_INITIALIZER
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __PTHREAD__
|
|
||||||
struct Guard {
|
|
||||||
pthread_mutex_t *_mutex;
|
|
||||||
|
|
||||||
Guard(pthread_mutex_t &mutex) : _mutex(&mutex) {
|
|
||||||
pthread_mutex_lock(_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Guard() {
|
|
||||||
pthread_mutex_unlock(_mutex);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
# define SWIG_GUARD(mutex) Guard _guard(mutex)
|
|
||||||
#else
|
|
||||||
# define SWIG_GUARD(mutex)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* director base class */
|
/* director base class */
|
||||||
class Director {
|
class Director {
|
||||||
private:
|
private:
|
||||||
|
@ -266,9 +235,7 @@ namespace Swig {
|
||||||
private:
|
private:
|
||||||
typedef std::map<void *, GCItem_var> swig_ownership_map;
|
typedef std::map<void *, GCItem_var> swig_ownership_map;
|
||||||
mutable swig_ownership_map swig_owner;
|
mutable swig_ownership_map swig_owner;
|
||||||
#ifdef __PTHREAD__
|
SWIG_GUARD_DECLARATION(swig_mutex_own);
|
||||||
static pthread_mutex_t swig_mutex_own;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
|
@ -307,5 +274,6 @@ namespace Swig {
|
||||||
return own;
|
return own;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
SWIG_GUARD_DEFINITION(Director, swig_mutex_own);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -808,6 +808,8 @@ public:
|
||||||
if (Swig_directors_enabled()) {
|
if (Swig_directors_enabled()) {
|
||||||
// Insert director runtime into the f_runtime file (make it occur before %header section)
|
// Insert director runtime into the f_runtime file (make it occur before %header section)
|
||||||
Swig_insert_file("director_common.swg", f_runtime);
|
Swig_insert_file("director_common.swg", f_runtime);
|
||||||
|
Swig_insert_file("director_py_mutex.swg", f_runtime);
|
||||||
|
Swig_insert_file("director_guard.swg", f_runtime);
|
||||||
Swig_insert_file("director.swg", f_runtime);
|
Swig_insert_file("director.swg", f_runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1155,6 +1155,7 @@ public:
|
||||||
if (Swig_directors_enabled()) {
|
if (Swig_directors_enabled()) {
|
||||||
// Insert director runtime into the f_runtime file (make it occur before %header section)
|
// Insert director runtime into the f_runtime file (make it occur before %header section)
|
||||||
Swig_insert_file("director_common.swg", f_runtime);
|
Swig_insert_file("director_common.swg", f_runtime);
|
||||||
|
Swig_insert_file("director_guard.swg", f_runtime);
|
||||||
Swig_insert_file("director.swg", f_runtime);
|
Swig_insert_file("director.swg", f_runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue