Changeset 83101 in vbox for trunk/src/VBox/Runtime/r3
- Timestamp:
- Feb 17, 2020 7:46:52 PM (5 years ago)
- svn:sync-xref-src-repo-rev:
- 136162
- Location:
- trunk/src/VBox/Runtime/r3/win
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/dllmain-win.cpp
r82968 r83101 82 82 83 83 case DLL_THREAD_DETACH: 84 rtTlsWinDetachThread(); 84 85 rtThreadNativeDetach(); 85 86 break; -
trunk/src/VBox/Runtime/r3/win/tls-dllmain-win.cpp
r83074 r83101 33 33 34 34 #include <iprt/thread.h> 35 #include <iprt/assert.h> 36 #include <iprt/critsect.h> 37 #include <iprt/errcore.h> 35 38 #include <iprt/log.h> 36 #include <iprt/ assert.h>37 #include <iprt/ errcore.h>39 #include <iprt/mem.h> 40 #include <iprt/once.h> 38 41 #include "internal/thread.h" 39 42 40 43 41 AssertCompile(sizeof(RTTLS) >= sizeof(DWORD)); 44 /********************************************************************************************************************************* 45 * Structures and Typedefs * 46 *********************************************************************************************************************************/ 47 typedef struct RTTLSWINDTOR 48 { 49 RTLISTNODE ListEntry; 50 DWORD iTls; 51 PFNRTTLSDTOR pfnDestructor; 52 } RTTLSWINDTOR; 53 typedef RTTLSWINDTOR *PRTTLSWINDTOR; 54 55 56 /********************************************************************************************************************************* 57 * Global Variables * 58 *********************************************************************************************************************************/ 59 /** Init once for the list and critical section. */ 60 static RTONCE g_Once = RTONCE_INITIALIZER; 61 /** Critical section protecting the TLS destructor list. */ 62 static RTCRITSECTRW g_CritSect; 63 /** List of TLS destrictors (RTTLSWINDTOR). */ 64 static RTLISTANCHOR g_TlsDtorHead; 65 /** Number of desturctors in the list (helps putting of initialization). */ 66 static uint32_t volatile g_cTlsDtors = 0; 67 68 69 /** 70 * @callback_method_impl{FNRTONCE} 71 */ 72 static DECLCALLBACK(int32_t) rtTlsWinInitLock(void *pvUser) 73 { 74 RT_NOREF(pvUser); 75 RTListInit(&g_TlsDtorHead); 76 return RTCritSectRwInit(&g_CritSect); 77 } 42 78 43 79 44 80 RTR3DECL(RTTLS) RTTlsAlloc(void) 45 81 { 82 AssertCompile(sizeof(RTTLS) >= sizeof(DWORD)); 46 83 DWORD iTls = TlsAlloc(); 47 84 return iTls != TLS_OUT_OF_INDEXES ? (RTTLS)iTls : NIL_RTTLS; … … 51 88 RTR3DECL(int) RTTlsAllocEx(PRTTLS piTls, PFNRTTLSDTOR pfnDestructor) 52 89 { 53 AssertReturn(!pfnDestructor, VERR_NOT_SUPPORTED); 54 DWORD iTls = TlsAlloc(); 55 if (iTls != TLS_OUT_OF_INDEXES) 56 { 57 Assert((RTTLS)iTls != NIL_RTTLS); 58 *piTls = (RTTLS)iTls; 59 Assert((DWORD)*piTls == iTls); 60 return VINF_SUCCESS; 61 } 62 63 return VERR_NO_MEMORY; 90 int rc; 91 if (!pfnDestructor) 92 { 93 DWORD iTls = TlsAlloc(); 94 if (iTls != TLS_OUT_OF_INDEXES) 95 { 96 Assert((RTTLS)iTls != NIL_RTTLS); 97 *piTls = (RTTLS)iTls; 98 Assert((DWORD)*piTls == iTls); 99 rc = VINF_SUCCESS; 100 } 101 else 102 rc = VERR_NO_MEMORY; 103 } 104 else 105 { 106 rc = RTOnce(&g_Once, rtTlsWinInitLock, NULL); 107 if (RT_SUCCESS(rc)) 108 { 109 PRTTLSWINDTOR pDtor = (PRTTLSWINDTOR)RTMemAlloc(sizeof(*pDtor)); 110 if (pDtor) 111 { 112 DWORD iTls = TlsAlloc(); 113 if (iTls != TLS_OUT_OF_INDEXES) 114 { 115 Assert((RTTLS)iTls != NIL_RTTLS); 116 *piTls = (RTTLS)iTls; 117 Assert((DWORD)*piTls == iTls); 118 119 /* 120 * Add the destructor to the list. We keep it sorted. 121 */ 122 pDtor->iTls = iTls; 123 pDtor->pfnDestructor = pfnDestructor; 124 RTCritSectRwEnterExcl(&g_CritSect); 125 RTListAppend(&g_TlsDtorHead, &pDtor->ListEntry); 126 ASMAtomicIncU32(&g_cTlsDtors); 127 RTCritSectRwLeaveExcl(&g_CritSect); 128 129 rc = VINF_SUCCESS; 130 } 131 else 132 rc = VERR_NO_MEMORY; 133 } 134 else 135 rc = VERR_NO_MEMORY; 136 } 137 } 138 return rc; 64 139 } 65 140 … … 70 145 return VINF_SUCCESS; 71 146 if (TlsFree((DWORD)iTls)) 72 return VINF_SUCCESS; 147 { 148 if (ASMAtomicReadU32(&g_cTlsDtors) > 0) 149 { 150 RTCritSectRwEnterExcl(&g_CritSect); 151 PRTTLSWINDTOR pDtor; 152 RTListForEach(&g_TlsDtorHead, pDtor, RTTLSWINDTOR, ListEntry) 153 { 154 if (pDtor->iTls == (DWORD)iTls) 155 { 156 RTListNodeRemove(&pDtor->ListEntry); 157 ASMAtomicDecU32(&g_cTlsDtors); 158 RTMemFree(pDtor); 159 break; 160 } 161 } 162 RTCritSectRwLeaveExcl(&g_CritSect); 163 } 164 return VINF_SUCCESS; 165 } 73 166 return RTErrConvertFromWin32(GetLastError()); 74 167 } … … 103 196 } 104 197 198 199 /** 200 * Called by dllmain-win.cpp when a thread detaches. 201 */ 202 DECLHIDDEN(void) rtTlsWinDetachThread(void) 203 { 204 if (ASMAtomicReadU32(&g_cTlsDtors) > 0) 205 { 206 RTCritSectRwEnterShared(&g_CritSect); 207 PRTTLSWINDTOR pDtor; 208 RTListForEach(&g_TlsDtorHead, pDtor, RTTLSWINDTOR, ListEntry) 209 { 210 void *pvValue = TlsGetValue(pDtor->iTls); 211 if (pvValue != NULL) 212 { 213 pDtor->pfnDestructor(pvValue); 214 TlsSetValue(pDtor->iTls, NULL); 215 } 216 } 217 RTCritSectRwLeaveShared(&g_CritSect); 218 } 219 } 220
Note:
See TracChangeset
for help on using the changeset viewer.