mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-11 21:27:01 -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
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
|
#include <wx/thread.h>
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Dynamic argument
|
// ----------------------------------------------------------------------------- : Dynamic argument
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# define THREAD_LOCAL __declspec(thread)
|
# define THREAD_LOCAL __declspec(thread)
|
||||||
#else
|
# define HAVE_TLS 1
|
||||||
|
#elseif defined __linux__
|
||||||
# define THREAD_LOCAL __thread
|
# define THREAD_LOCAL __thread
|
||||||
|
# define HAVE_TLS 1
|
||||||
|
#else
|
||||||
|
# define HAVE_TLS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Declare a dynamic argument.
|
#if HAVE_TLS
|
||||||
/** 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
|
/// Declare a dynamic argument.
|
||||||
#define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \
|
/** The value of the argument can be got with: name()
|
||||||
THREAD_LOCAL Type name##_private = initial;
|
* 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; \
|
||||||
|
}
|
||||||
|
|
||||||
/// Locally change the value of a dynamic argument
|
/// Implementation of a dynamic argument
|
||||||
/** Usage:
|
#define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \
|
||||||
* @code
|
THREAD_LOCAL Type name##_private = initial;
|
||||||
* // here name() == old value
|
|
||||||
* {
|
/// Locally change the value of a dynamic argument
|
||||||
* WITH_DYNAMIC_ARG(name, newValue);
|
/** Usage:
|
||||||
* // here name() == newValue
|
* @code
|
||||||
* }
|
* // here name() == old value
|
||||||
* // here name() == old value
|
* {
|
||||||
* @endcode
|
* WITH_DYNAMIC_ARG(name, newValue);
|
||||||
*/
|
* // here name() == newValue
|
||||||
#define WITH_DYNAMIC_ARG(name, value) \
|
* }
|
||||||
name##_changer name##_dummmy(value)
|
* // 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
|
// ----------------------------------------------------------------------------- : EOF
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user