00001
00002
00003 #include "pch.h"
00004 #include "config.h"
00005
00006
00007 #if CRYPTOPP_MSC_VERSION
00008 # pragma warning(disable: 4297)
00009 #endif
00010
00011 #ifndef CRYPTOPP_IMPORTS
00012 #ifdef THREADS_AVAILABLE
00013
00014 #include "trdlocal.h"
00015
00016 #ifdef HAS_WINTHREADS
00017 #include <windows.h>
00018 #endif
00019
00020 NAMESPACE_BEGIN(CryptoPP)
00021
00022 ThreadLocalStorage::Err::Err(const std::string& operation, int error)
00023 : OS_Error(OTHER_ERROR, "ThreadLocalStorage: " + operation + " operation failed with error 0x" + IntToString(error, 16), operation, error)
00024 {
00025 }
00026
00027 ThreadLocalStorage::ThreadLocalStorage()
00028 {
00029 #ifdef HAS_WINTHREADS
00030 m_index = TlsAlloc();
00031 assert(m_index != TLS_OUT_OF_INDEXES);
00032 if (m_index == TLS_OUT_OF_INDEXES)
00033 throw Err("TlsAlloc", GetLastError());
00034 #else
00035 m_index = 0;
00036 int error = pthread_key_create(&m_index, NULL);
00037 assert(!error);
00038 if (error)
00039 throw Err("pthread_key_create", error);
00040 #endif
00041 }
00042
00043 ThreadLocalStorage::~ThreadLocalStorage() CRYPTOPP_THROW
00044 {
00045 #ifdef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE
00046 if (!std::uncaught_exception())
00047 #else
00048 try
00049 #endif
00050 #ifdef HAS_WINTHREADS
00051 {
00052 int rc = TlsFree(m_index);
00053 assert(rc);
00054 if (!rc)
00055 throw Err("TlsFree", GetLastError());
00056 }
00057 #else
00058 {
00059 int error = pthread_key_delete(m_index);
00060 assert(!error);
00061 if (error)
00062 throw Err("pthread_key_delete", error);
00063 }
00064 #endif
00065 #ifndef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE
00066 catch(const Exception&)
00067 {
00068 }
00069 #endif
00070 }
00071
00072 void ThreadLocalStorage::SetValue(void *value)
00073 {
00074 #ifdef HAS_WINTHREADS
00075 if (!TlsSetValue(m_index, value))
00076 throw Err("TlsSetValue", GetLastError());
00077 #else
00078 int error = pthread_setspecific(m_index, value);
00079 if (error)
00080 throw Err("pthread_key_getspecific", error);
00081 #endif
00082 }
00083
00084 void *ThreadLocalStorage::GetValue() const
00085 {
00086 #ifdef HAS_WINTHREADS
00087 void *result = TlsGetValue(m_index);
00088 const DWORD dwRet = GetLastError();
00089
00090 assert(result || (!result && (dwRet == NO_ERROR)));
00091 if (!result && dwRet != NO_ERROR)
00092 throw Err("TlsGetValue", dwRet);
00093 #else
00094
00095
00096 void *result = pthread_getspecific(m_index);
00097 #endif
00098 return result;
00099 }
00100
00101 NAMESPACE_END
00102
00103 #endif // #ifdef THREADS_AVAILABLE
00104 #endif