]> git.saurik.com Git - wxWidgets.git/blame_incremental - include/wx/msw/tls.h
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / include / wx / msw / tls.h
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: wx/msw/tls.h
3// Purpose: Win32 implementation of wxTlsValue<>
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_MSW_TLS_H_
11#define _WX_MSW_TLS_H_
12
13#include "wx/msw/wrapwin.h"
14#include "wx/thread.h"
15#include "wx/vector.h"
16
17// ----------------------------------------------------------------------------
18// wxTlsKey is a helper class encapsulating a TLS slot
19// ----------------------------------------------------------------------------
20
21class wxTlsKey
22{
23public:
24 // ctor allocates a new key
25 wxTlsKey(wxTlsDestructorFunction destructor)
26 {
27 m_destructor = destructor;
28 m_slot = ::TlsAlloc();
29 }
30
31 // return true if the key was successfully allocated
32 bool IsOk() const { return m_slot != TLS_OUT_OF_INDEXES; }
33
34 // get the key value, there is no error return
35 void *Get() const
36 {
37 return ::TlsGetValue(m_slot);
38 }
39
40 // change the key value, return true if ok
41 bool Set(void *value)
42 {
43 void *old = Get();
44
45 if ( ::TlsSetValue(m_slot, value) == 0 )
46 return false;
47
48 if ( old )
49 m_destructor(old);
50
51 // update m_allValues list of all values - remove old, add new
52 wxCriticalSectionLocker lock(m_csAllValues);
53 if ( old )
54 {
55 for ( wxVector<void*>::iterator i = m_allValues.begin();
56 i != m_allValues.end();
57 ++i )
58 {
59 if ( *i == old )
60 {
61 if ( value )
62 *i = value;
63 else
64 m_allValues.erase(i);
65 return true;
66 }
67 }
68 wxFAIL_MSG( "previous wxTlsKey value not recorded in m_allValues" );
69 }
70
71 if ( value )
72 m_allValues.push_back(value);
73
74 return true;
75 }
76
77 // free the key
78 ~wxTlsKey()
79 {
80 if ( !IsOk() )
81 return;
82
83 // Win32 API doesn't have the equivalent of pthread's destructor, so we
84 // have to keep track of all allocated values and destroy them manually;
85 // ideally we'd do that at thread exit time, but since we could only
86 // do that with wxThread and not otherwise created threads, we do it
87 // here.
88 //
89 // TODO: We should still call destructors for wxTlsKey used in the
90 // thread from wxThread's thread shutdown code, *in addition*
91 // to doing it in ~wxTlsKey.
92 //
93 // NB: No need to lock m_csAllValues, by the time this code is called,
94 // no other thread can be using this key.
95 for ( wxVector<void*>::iterator i = m_allValues.begin();
96 i != m_allValues.end();
97 ++i )
98 {
99 m_destructor(*i);
100 }
101
102 ::TlsFree(m_slot);
103 }
104
105private:
106 wxTlsDestructorFunction m_destructor;
107 DWORD m_slot;
108
109 wxVector<void*> m_allValues;
110 wxCriticalSection m_csAllValues;
111
112 wxDECLARE_NO_COPY_CLASS(wxTlsKey);
113};
114
115#endif // _WX_MSW_TLS_H_
116