Crypto++  5.6.3
Free C++ class library of cryptographic schemes
trdlocal.cpp
1 // trdlocal.cpp - written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 #include "config.h"
5 
6 // TODO: fix this when more complete C++11 support is cut-in
7 #if CRYPTOPP_MSC_VERSION
8 # pragma warning(disable: 4297)
9 #endif
10 
11 #ifndef CRYPTOPP_IMPORTS
12 #ifdef THREADS_AVAILABLE
13 
14 #include "trdlocal.h"
15 
16 #ifdef HAS_WINTHREADS
17 #include <windows.h>
18 #endif
19 
20 NAMESPACE_BEGIN(CryptoPP)
21 
22 ThreadLocalStorage::Err::Err(const std::string& operation, int error)
23  : OS_Error(OTHER_ERROR, "ThreadLocalStorage: " + operation + " operation failed with error 0x" + IntToString(error, 16), operation, error)
24 {
25 }
26 
27 ThreadLocalStorage::ThreadLocalStorage()
28 {
29 #ifdef HAS_WINTHREADS
30  m_index = TlsAlloc();
31  assert(m_index != TLS_OUT_OF_INDEXES);
32  if (m_index == TLS_OUT_OF_INDEXES)
33  throw Err("TlsAlloc", GetLastError());
34 #else
35  m_index = 0;
36  int error = pthread_key_create(&m_index, NULL);
37  assert(!error);
38  if (error)
39  throw Err("pthread_key_create", error);
40 #endif
41 }
42 
43 ThreadLocalStorage::~ThreadLocalStorage() CRYPTOPP_THROW
44 {
45 #ifdef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE
46  if (!std::uncaught_exception())
47 #else
48  try
49 #endif
50 #ifdef HAS_WINTHREADS
51  {
52  int rc = TlsFree(m_index);
53  assert(rc);
54  if (!rc)
55  throw Err("TlsFree", GetLastError());
56  }
57 #else
58  {
59  int error = pthread_key_delete(m_index);
60  assert(!error);
61  if (error)
62  throw Err("pthread_key_delete", error);
63  }
64 #endif
65 #ifndef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE
66  catch(const Exception&)
67  {
68  }
69 #endif
70 }
71 
72 void ThreadLocalStorage::SetValue(void *value)
73 {
74 #ifdef HAS_WINTHREADS
75  if (!TlsSetValue(m_index, value))
76  throw Err("TlsSetValue", GetLastError());
77 #else
78  int error = pthread_setspecific(m_index, value);
79  if (error)
80  throw Err("pthread_key_getspecific", error);
81 #endif
82 }
83 
84 void *ThreadLocalStorage::GetValue() const
85 {
86 #ifdef HAS_WINTHREADS
87  void *result = TlsGetValue(m_index);
88  const DWORD dwRet = GetLastError();
89 
90  assert(result || (!result && (dwRet == NO_ERROR)));
91  if (!result && dwRet != NO_ERROR)
92  throw Err("TlsGetValue", dwRet);
93 #else
94  // Null is a valid return value. Posix does not provide a way to
95  // check for a "good" Null vs a "bad" Null (errno is not set).
96  void *result = pthread_getspecific(m_index);
97 #endif
98  return result;
99 }
100 
101 NAMESPACE_END
102 
103 #endif // #ifdef THREADS_AVAILABLE
104 #endif
Base class for all exceptions thrown by the library.
Definition: cryptlib.h:139
The operating system reported an error.
Definition: cryptlib.h:217
Library configuration file.
STL namespace.
thread local storage
Definition: trdlocal.h:20
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:460
Crypto++ library namespace.