Crypto++
trdlocal.cpp
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 
14 NAMESPACE_BEGIN(CryptoPP)
15 
16 ThreadLocalStorage::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 
21 ThreadLocalStorage::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 
34 ThreadLocalStorage::~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 
46 void 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 
58 void *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 
70 NAMESPACE_END
71 
72 #endif // #ifdef THREADS_AVAILABLE
73 #endif
error reported by the operating system
Definition: cryptlib.h:180
thread local storage
Definition: trdlocal.h:20