~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/wxWidgets3/include/wx/tls.h

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
///////////////////////////////////////////////////////////////////////////////
 
2
// Name:        wx/tls.h
 
3
// Purpose:     Implementation of thread local storage
 
4
// Author:      Vadim Zeitlin
 
5
// Created:     2008-08-08
 
6
// Copyright:   (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
 
7
// Licence:     wxWindows licence
 
8
///////////////////////////////////////////////////////////////////////////////
 
9
 
 
10
#ifndef _WX_TLS_H_
 
11
#define _WX_TLS_H_
 
12
 
 
13
#include "wx/defs.h"
 
14
 
 
15
// ----------------------------------------------------------------------------
 
16
// check for compiler support of thread-specific variables
 
17
// ----------------------------------------------------------------------------
 
18
 
 
19
// when not using threads at all, there is no need for thread-specific
 
20
// values to be really thread-specific
 
21
#if !wxUSE_THREADS
 
22
    #define wxHAS_COMPILER_TLS
 
23
    #define wxTHREAD_SPECIFIC_DECL
 
24
// otherwise try to find the compiler-specific way to handle TLS unless
 
25
// explicitly disabled by setting wxUSE_COMPILER_TLS to 0 (it is 1 by default).
 
26
#elif wxUSE_COMPILER_TLS
 
27
// __thread keyword is not supported correctly by MinGW, at least in some
 
28
// configurations, see http://sourceforge.net/support/tracker.php?aid=2837047
 
29
// and when in doubt we prefer to not use it at all.
 
30
#if defined(HAVE___THREAD_KEYWORD) && !defined(__MINGW32__)
 
31
    #define wxHAS_COMPILER_TLS
 
32
    #define wxTHREAD_SPECIFIC_DECL __thread
 
33
// MSVC has its own version which might be supported by some other Windows
 
34
// compilers, to be tested
 
35
#elif wxCHECK_VISUALC_VERSION(7)
 
36
    #define wxHAS_COMPILER_TLS
 
37
    #define wxTHREAD_SPECIFIC_DECL __declspec(thread)
 
38
#endif // compilers
 
39
#endif // wxUSE_COMPILER_TLS
 
40
 
 
41
// ----------------------------------------------------------------------------
 
42
// define wxTLS_TYPE()
 
43
// ----------------------------------------------------------------------------
 
44
 
 
45
#ifdef wxHAS_COMPILER_TLS
 
46
    #define wxTLS_TYPE(T) wxTHREAD_SPECIFIC_DECL T
 
47
    #define wxTLS_PTR(var) (&(var))
 
48
    #define wxTLS_VALUE(var) (var)
 
49
#else // !wxHAS_COMPILER_TLS
 
50
 
 
51
    extern "C"
 
52
    {
 
53
        typedef void (*wxTlsDestructorFunction)(void*);
 
54
    }
 
55
 
 
56
    #if defined(__WINDOWS__)
 
57
        #include "wx/msw/tls.h"
 
58
    #elif defined(__OS2__)
 
59
        #include "wx/os2/tls.h"
 
60
    #elif defined(__UNIX__)
 
61
        #include "wx/unix/tls.h"
 
62
    #else
 
63
        // TODO: we could emulate TLS for such platforms...
 
64
        #error Neither compiler nor OS support thread-specific variables.
 
65
    #endif
 
66
 
 
67
    #include <stdlib.h> // for calloc()
 
68
 
 
69
    // wxTlsValue<T> represents a thread-specific value of type T but, unlike
 
70
    // with native compiler thread-specific variables, it behaves like a
 
71
    // (never NULL) pointer to T and so needs to be dereferenced before use
 
72
    //
 
73
    // Note: T must be a POD!
 
74
    //
 
75
    // Note: On Unix, thread-specific T value is freed when the thread exits.
 
76
    //       On Windows, thread-specific values are freed later, when given
 
77
    //       wxTlsValue<T> is destroyed.  The only exception to this is the
 
78
    //       value for the main thread, which is always freed when
 
79
    //       wxTlsValue<T> is destroyed.
 
80
    template <typename T>
 
81
    class wxTlsValue
 
82
    {
 
83
    public:
 
84
        typedef T ValueType;
 
85
 
 
86
        // ctor doesn't do anything, the object is created on first access
 
87
        wxTlsValue() : m_key(free) {}
 
88
 
 
89
        // dtor is only called in the main thread context and so is not enough
 
90
        // to free memory allocated by us for the other threads, we use
 
91
        // destructor function when using Pthreads for this (which is not
 
92
        // called for the main thread as it doesn't call pthread_exit() but
 
93
        // just to be safe we also reset the key anyhow)
 
94
        ~wxTlsValue()
 
95
        {
 
96
            if ( m_key.Get() )
 
97
                m_key.Set(NULL); // this deletes the value
 
98
        }
 
99
 
 
100
        // access the object creating it on demand
 
101
        ValueType *Get()
 
102
        {
 
103
            void *value = m_key.Get();
 
104
            if ( !value )
 
105
            {
 
106
                // ValueType must be POD to be used in wxHAS_COMPILER_TLS case
 
107
                // anyhow (at least gcc doesn't accept non-POD values being
 
108
                // declared with __thread) so initialize it as a POD too
 
109
                value = calloc(1, sizeof(ValueType));
 
110
 
 
111
                if ( !m_key.Set(value) )
 
112
                {
 
113
                    free(value);
 
114
 
 
115
                    // this will probably result in a crash in the caller but
 
116
                    // it's arguably better to crash immediately instead of
 
117
                    // slowly dying from out-of-memory errors which would
 
118
                    // happen as the next access to this object would allocate
 
119
                    // another ValueType instance and so on forever
 
120
                    value = NULL;
 
121
                }
 
122
            }
 
123
 
 
124
            return static_cast<ValueType *>(value);
 
125
        }
 
126
 
 
127
        // pointer-like accessors
 
128
        ValueType *operator->() { return Get(); }
 
129
        ValueType& operator*() { return *Get(); }
 
130
 
 
131
    private:
 
132
        wxTlsKey m_key;
 
133
 
 
134
        DECLARE_NO_COPY_TEMPLATE_CLASS(wxTlsValue, T)
 
135
    };
 
136
 
 
137
    #define wxTLS_TYPE(T) wxTlsValue<T>
 
138
    #define wxTLS_PTR(var) ((var).Get())
 
139
    #define wxTLS_VALUE(var) (*(var))
 
140
#endif // wxHAS_COMPILER_TLS/!wxHAS_COMPILER_TLS
 
141
 
 
142
#endif // _WX_TLS_H_
 
143