mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 13:06:59 -04:00
Added some stuff for platforms without TLS
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@767 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
+91
-37
@@ -16,53 +16,107 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <wx/thread.h>
|
||||
|
||||
// ----------------------------------------------------------------------------- : Dynamic argument
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define THREAD_LOCAL __declspec(thread)
|
||||
#else
|
||||
# define HAVE_TLS 1
|
||||
#elseif defined __linux__
|
||||
# define THREAD_LOCAL __thread
|
||||
# define HAVE_TLS 1
|
||||
#else
|
||||
# define HAVE_TLS 0
|
||||
#endif
|
||||
|
||||
/// Declare a dynamic argument.
|
||||
/** The value of the argument can be got with: name()
|
||||
* To change the value use WITH_DYNAMIC_ARG(name, newValue)
|
||||
* To be used in a header file. Use IMPLEMENT_DYN_ARG in a source file
|
||||
*/
|
||||
#define DECLARE_DYNAMIC_ARG(Type, name) \
|
||||
extern THREAD_LOCAL Type name##_private; \
|
||||
inline Type name() { return name##_private; } \
|
||||
class name##_changer { \
|
||||
public: \
|
||||
inline name##_changer(Type const& newValue) \
|
||||
: oldValue(name##_private) { \
|
||||
name##_private = newValue; \
|
||||
} \
|
||||
inline ~name##_changer() { \
|
||||
name##_private = oldValue; \
|
||||
} \
|
||||
private: \
|
||||
Type oldValue; \
|
||||
}
|
||||
#if HAVE_TLS
|
||||
|
||||
/// Implementation of a dynamic argument
|
||||
#define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \
|
||||
THREAD_LOCAL Type name##_private = initial;
|
||||
/// Declare a dynamic argument.
|
||||
/** The value of the argument can be got with: name()
|
||||
* To change the value use WITH_DYNAMIC_ARG(name, newValue)
|
||||
* To be used in a header file. Use IMPLEMENT_DYN_ARG in a source file
|
||||
*/
|
||||
#define DECLARE_DYNAMIC_ARG(Type, name) \
|
||||
extern THREAD_LOCAL Type name##_private; \
|
||||
inline Type name() { return name##_private; } \
|
||||
class name##_changer { \
|
||||
public: \
|
||||
inline name##_changer(Type const& newValue) \
|
||||
: oldValue(name##_private) { \
|
||||
name##_private = newValue; \
|
||||
} \
|
||||
inline ~name##_changer() { \
|
||||
name##_private = oldValue; \
|
||||
} \
|
||||
private: \
|
||||
Type oldValue; \
|
||||
}
|
||||
|
||||
/// Implementation of a dynamic argument
|
||||
#define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \
|
||||
THREAD_LOCAL Type name##_private = initial;
|
||||
|
||||
/// Locally change the value of a dynamic argument
|
||||
/** Usage:
|
||||
* @code
|
||||
* // here name() == old value
|
||||
* {
|
||||
* WITH_DYNAMIC_ARG(name, newValue);
|
||||
* // here name() == newValue
|
||||
* }
|
||||
* // here name() == old value
|
||||
* @endcode
|
||||
*/
|
||||
#define WITH_DYNAMIC_ARG(name, value) \
|
||||
name##_changer name##_dummmy(value)
|
||||
/// Locally change the value of a dynamic argument
|
||||
/** Usage:
|
||||
* @code
|
||||
* // here name() == old value
|
||||
* {
|
||||
* WITH_DYNAMIC_ARG(name, newValue);
|
||||
* // here name() == newValue
|
||||
* }
|
||||
* // here name() == old value
|
||||
* @endcode
|
||||
*/
|
||||
#define WITH_DYNAMIC_ARG(name, value) \
|
||||
name##_changer name##_dummmy(value)
|
||||
|
||||
#else
|
||||
|
||||
template <typename T> struct ThreadLocalObject {
|
||||
map<int,T*> objects;
|
||||
T def;
|
||||
wxCriticalSection container_access;
|
||||
|
||||
inline T operator () () {
|
||||
wxCriticalSectionLocker lock(container_access);
|
||||
T*& p = objects[wxThread::GetCurrentId()];
|
||||
if (!p) {
|
||||
p = new T(def);
|
||||
}
|
||||
return *objects[wxThread::GetCurrentId()];
|
||||
}
|
||||
|
||||
inline void store (T value) {
|
||||
wxCriticalSectionLocker lock(container_access);
|
||||
T*& p = objects[wxThread::GetCurrentId()];
|
||||
if (!p) {
|
||||
p = new T(def);
|
||||
}
|
||||
*objects[wxThread::GetCurrentId()] = value;
|
||||
}
|
||||
|
||||
ThreadLocalObject (T def)
|
||||
: def(def)
|
||||
{}
|
||||
|
||||
~ThreadLocalObject () {
|
||||
for (typename map<int,T*>::iterator i = objects.begin(); i != objects.end(); ++i) {
|
||||
delete *i;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define DECLARE_DYNAMIC_ARG(Type, name) \
|
||||
extern ThreadLocalObject<Type> name;
|
||||
|
||||
#define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \
|
||||
ThreadLocalObject<Type> name (initial);
|
||||
|
||||
#define WITH_DYNAMIC_ARG(name, value) \
|
||||
name.store(value);
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user