/* Check if we have any entries */ if (!LdrpNumberOfTlsEntries) return STATUS_SUCCESS;
/* Allocate the vector array */ TlsVector = RtlAllocateHeap(RtlGetProcessHeap(), 0, LdrpNumberOfTlsEntries * sizeof(PVOID)); if (!TlsVector) return STATUS_NO_MEMORY; Teb->ThreadLocalStoragePointer = TlsVector;
/* Loop the TLS Array */ ListHead = &LdrpTlsList; NextEntry = ListHead->Flink; while (NextEntry != ListHead) { /* Get the entry */ TlsData = CONTAINING_RECORD(NextEntry, LDRP_TLS_DATA, TlsLinks); NextEntry = NextEntry->Flink;
/* Allocate this vector */ TlsDataSize = TlsData->TlsDirectory.EndAddressOfRawData - TlsData->TlsDirectory.StartAddressOfRawData; TlsVector[TlsData->TlsDirectory.Characteristics] = RtlAllocateHeap(RtlGetProcessHeap(), 0, TlsDataSize); if (!TlsVector[TlsData->TlsDirectory.Characteristics]) { /* Out of memory */ return STATUS_NO_MEMORY; }
/* Show debug message */ if (ShowSnaps) { DPRINT1("LDR: TlsVector %x Index %d = %x copied from %x to %x\n", TlsVector, TlsData->TlsDirectory.Characteristics, &TlsVector[TlsData->TlsDirectory.Characteristics], TlsData->TlsDirectory.StartAddressOfRawData, TlsVector[TlsData->TlsDirectory.Characteristics]); }
/* Copy the data */ RtlCopyMemory(TlsVector[TlsData->TlsDirectory.Characteristics], (PVOID)TlsData->TlsDirectory.StartAddressOfRawData, TlsDataSize); }
Starting in C++11, a static local variable initialization is guaranteed to be thread-safe.This feature is sometimes called magic statics.However, in a multithreaded application all subsequent assignments must be synchronized.The thread-safe statics feature can be disabled by using the /Zc:threadSafeInit- flag to avoid taking a dependency on the CRT.