1// trdlocal.cpp - written and placed in the public domain by Wei Dai 2 3#include "pch.h" 4 5#ifndef CRYPTOPP_IMPORTS 6#ifdef THREADS_AVAILABLE 7 8#include "trdlocal.h" 9 10#ifdef HAS_WINTHREADS 11#include <windows.h> 12#endif 13 14NAMESPACE_BEGIN(CryptoPP) 15 16ThreadLocalStorage::Err::Err(const std::string& operation, int error) 17 : OS_Error(OTHER_ERROR, "ThreadLocalStorage: " + operation + " operation failed with error 0x" + IntToString(error, 16), operation, error) 18{ 19} 20 21ThreadLocalStorage::ThreadLocalStorage() 22{ 23#ifdef HAS_WINTHREADS 24 m_index = TlsAlloc(); 25 if (m_index == TLS_OUT_OF_INDEXES) 26 throw Err("TlsAlloc", GetLastError()); 27#else 28 int error = pthread_key_create(&m_index, NULL); 29 if (error) 30 throw Err("pthread_key_create", error); 31#endif 32} 33 34ThreadLocalStorage::~ThreadLocalStorage() 35{ 36#ifdef HAS_WINTHREADS 37 if (!TlsFree(m_index)) 38 throw Err("TlsFree", GetLastError()); 39#else 40 int error = pthread_key_delete(m_index); 41 if (error) 42 throw Err("pthread_key_delete", error); 43#endif 44} 45 46void ThreadLocalStorage::SetValue(void *value) 47{ 48#ifdef HAS_WINTHREADS 49 if (!TlsSetValue(m_index, value)) 50 throw Err("TlsSetValue", GetLastError()); 51#else 52 int error = pthread_setspecific(m_index, value); 53 if (error) 54 throw Err("pthread_key_getspecific", error); 55#endif 56} 57 58void *ThreadLocalStorage::GetValue() const 59{ 60#ifdef HAS_WINTHREADS 61 void *result = TlsGetValue(m_index); 62 if (!result && GetLastError() != NO_ERROR) 63 throw Err("TlsGetValue", GetLastError()); 64#else 65 void *result = pthread_getspecific(m_index); 66#endif 67 return result; 68} 69 70NAMESPACE_END 71 72#endif // #ifdef THREADS_AVAILABLE 73#endif 74