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 */
|
||||
class Director {
|
||||
private:
|
||||
|
|
|
@ -14,25 +14,6 @@
|
|||
#include <vector>
|
||||
#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
|
||||
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 */
|
||||
class Director {
|
||||
|
@ -411,9 +303,7 @@ namespace Swig {
|
|||
private:
|
||||
typedef std::map<void *, GCItem_var> swig_ownership_map;
|
||||
mutable swig_ownership_map swig_owner;
|
||||
#ifdef __THREAD__
|
||||
static Mutex swig_mutex_own;
|
||||
#endif
|
||||
SWIG_GUARD_DECLARATION(swig_mutex_own);
|
||||
|
||||
public:
|
||||
template <typename Type>
|
||||
|
@ -463,9 +353,7 @@ namespace Swig {
|
|||
}
|
||||
};
|
||||
|
||||
#ifdef __THREAD__
|
||||
Mutex Director::swig_mutex_own;
|
||||
#endif
|
||||
SWIG_GUARD_DEFINITION(Director, swig_mutex_own);
|
||||
}
|
||||
|
||||
#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 */
|
||||
class Director {
|
||||
private:
|
||||
|
@ -266,9 +235,7 @@ namespace Swig {
|
|||
private:
|
||||
typedef std::map<void *, GCItem_var> swig_ownership_map;
|
||||
mutable swig_ownership_map swig_owner;
|
||||
#ifdef __PTHREAD__
|
||||
static pthread_mutex_t swig_mutex_own;
|
||||
#endif
|
||||
SWIG_GUARD_DECLARATION(swig_mutex_own);
|
||||
|
||||
public:
|
||||
template <typename Type>
|
||||
|
@ -307,5 +274,6 @@ namespace Swig {
|
|||
return own;
|
||||
}
|
||||
};
|
||||
SWIG_GUARD_DEFINITION(Director, swig_mutex_own);
|
||||
}
|
||||
|
||||
|
|
|
@ -808,6 +808,8 @@ public:
|
|||
if (Swig_directors_enabled()) {
|
||||
// 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_py_mutex.swg", f_runtime);
|
||||
Swig_insert_file("director_guard.swg", f_runtime);
|
||||
Swig_insert_file("director.swg", f_runtime);
|
||||
}
|
||||
|
||||
|
|
|
@ -1155,6 +1155,7 @@ public:
|
|||
if (Swig_directors_enabled()) {
|
||||
// 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_guard.swg", f_runtime);
|
||||
Swig_insert_file("director.swg", f_runtime);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue