Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in tip

fogcreek shellext: fixed TLS-related crash on Windows XP

Changeset 339764f94377

Parent 0882bf027ed0

by David Golub

Changes to 5 files · Browse files at 339764f94377 Showing diff from parent 0882bf027ed0 Diff from another changeset...

 
258
259
260
 
261
262
263
 
258
259
260
261
262
263
264
@@ -258,6 +258,7 @@
  <ClInclude Include="SysInfo.h" />   <ClInclude Include="THgStatus.h" />   <ClInclude Include="THgVersion.h" /> + <ClInclude Include="TlsPtr.h" />   <ClInclude Include="TortoiseHgCmenu.h" />   <ClInclude Include="TortoiseHgDropHandler.h" />   <ClInclude Include="TortoiseHgKeyboard.h" />
 
167
168
169
 
 
 
170
171
172
 
167
168
169
170
171
172
173
174
175
@@ -167,6 +167,9 @@
  <ClInclude Include="GlobalData.h">   <Filter>Header Files</Filter>   </ClInclude> + <ClInclude Include="TlsPtr.h"> + <Filter>Header Files</Filter> + </ClInclude>   </ItemGroup>   <ItemGroup>   <None Include="THgShell.def">
Change 1 of 1 Show Entire File win32/​shellext/​TlsPtr.h Stacked
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
@@ -0,0 +1,55 @@
+// Copyright (C) 2011 Fog Creek Software +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +#pragma once + +template <class T> +class CTlsPtr +{ +private: + DWORD m_dwTlsIndex; + +public: + CTlsPtr() + { + m_dwTlsIndex = ::TlsAlloc(); + } + + ~CTlsPtr() + { + ::TlsFree(m_dwTlsIndex); + } + T* operator=(T* p) + { + ::TlsSetValue(m_dwTlsIndex, p); + return p; + } + operator T*() + { + return (T*)::TlsGetValue(m_dwTlsIndex); + } + operator const T*() const + { + return (const T*)::TlsGetValue(m_dwTlsIndex); + } + T* operator->() + { + return (T*)::TlsGetValue(m_dwTlsIndex); + } + const T* operator->() const + { + return (const T*)::TlsGetValue(m_dwTlsIndex); + } +};
 
23
24
25
26
 
27
28
29
 
34
35
36
 
 
 
 
 
 
37
38
39
 
23
24
25
 
26
27
28
29
 
34
35
36
37
38
39
40
41
42
43
44
45
@@ -23,7 +23,7 @@
   // Each Windows Explorer window is launched in a separate thread. Therefore, use thread  // local storage so that each thread can have its own hook. -__declspec(thread) CTortoiseHgKeyboard* CTortoiseHgKeyboard::g_pObject = NULL; +CTlsPtr<CTortoiseHgKeyboard> CTortoiseHgKeyboard::g_pObject;    STDMETHODIMP CTortoiseHgKeyboard::SetSite(IUnknown* pUnkSite)  { @@ -34,6 +34,12 @@
  m_hHook = ::SetWindowsHookEx(WH_KEYBOARD, HookProc, NULL,   ::GetCurrentThreadId());   } + else if (pUnkSite == NULL && g_pObject == this) + { + ::UnhookWindowsHookEx(m_hHook); + m_hHook = NULL; + g_pObject = NULL; + }     return IObjectWithSiteImpl<CTortoiseHgKeyboard>::SetSite(pUnkSite);  }
 
14
15
16
 
17
18
19
 
21
22
23
24
 
25
26
27
 
14
15
16
17
18
19
20
 
22
23
24
 
25
26
27
28
@@ -14,6 +14,7 @@
 // along with this program. If not, see <http://www.gnu.org/licenses/>.    #pragma once +#include "TlsPtr.h"    class CTortoiseHgKeyboard :   public CComObjectRootEx<CComMultiThreadModel>, @@ -21,7 +22,7 @@
  public IObjectWithSiteImpl<CTortoiseHgKeyboard>  {  private: - static __declspec(thread) CTortoiseHgKeyboard* g_pObject; + static CTlsPtr<CTortoiseHgKeyboard> g_pObject;   HHOOK m_hHook;    public: