From 833ecbf035d548fa3a631c7191cc4ec23b738d05 Mon Sep 17 00:00:00 2001 From: Christopher Dykes Date: Fri, 14 Apr 2017 17:05:09 -0700 Subject: [PATCH] Add portability support for PThread's TLS API Summary: This is the last piece needed to get Folly working on Windows without PThreads. Updating Folly's test suite to support compiling without PThreads will come next. Reviewed By: yfeldblum Differential Revision: D4894048 fbshipit-source-id: 6076317e1364aef82a5d3cb306bea7c2226b3cdc --- folly/Makefile.am | 1 + folly/portability/PThread.cpp | 89 +++++++++++++++++++++++++++++++++++ folly/portability/PThread.h | 29 ++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 folly/portability/PThread.cpp diff --git a/folly/Makefile.am b/folly/Makefile.am index b2dbcfaf..4bde2ae3 100644 --- a/folly/Makefile.am +++ b/folly/Makefile.am @@ -489,6 +489,7 @@ libfolly_la_SOURCES = \ portability/Malloc.cpp \ portability/Memory.cpp \ portability/OpenSSL.cpp \ + portability/PThread.cpp \ portability/Sockets.cpp \ portability/Stdio.cpp \ portability/Stdlib.cpp \ diff --git a/folly/portability/PThread.cpp b/folly/portability/PThread.cpp new file mode 100644 index 00000000..aba122a7 --- /dev/null +++ b/folly/portability/PThread.cpp @@ -0,0 +1,89 @@ +/* + * Copyright 2017 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#if !FOLLY_HAVE_PTHREAD && _WIN32 +#include +#include + +namespace folly { +namespace portability { +namespace pthread { +static thread_local struct PThreadLocalMap { + PThreadLocalMap() = default; + ~PThreadLocalMap() { + for (auto kv : keyMap) { + // Call destruction callbacks if they exist. + if (kv.second.second != nullptr) { + kv.second.second(kv.second.first); + } + } + } + + int createKey(pthread_key_t* key, void (*destructor)(void*)) { + auto ret = TlsAlloc(); + if (ret == TLS_OUT_OF_INDEXES) { + return -1; + } + *key = ret; + keyMap.emplace(*key, std::make_pair(nullptr, destructor)); + return 0; + } + + int deleteKey(pthread_key_t key) { + if (!TlsFree(key)) { + return -1; + } + keyMap.erase(key); + return 0; + } + + void* getKey(pthread_key_t key) { + return TlsGetValue(key); + } + + int setKey(pthread_key_t key, void* value) { + if (!TlsSetValue(key, value)) { + return -1; + } + keyMap[key].first = value; + return 0; + } + + std::unordered_map> keyMap{}; +} s_tls_key_map; + +int pthread_key_create(pthread_key_t* key, void (*destructor)(void*)) { + return s_tls_key_map.createKey(key, destructor); +} + +int pthread_key_delete(pthread_key_t key) { + return s_tls_key_map.deleteKey(key); +} + +void* pthread_getspecific(pthread_key_t key) { + return s_tls_key_map.getKey(key); +} + +int pthread_setspecific(pthread_key_t key, const void* value) { + // Yes, the PThread API really is this bad -_-... + return s_tls_key_map.setKey(key, const_cast(value)); +} +} +} +} +#endif diff --git a/folly/portability/PThread.h b/folly/portability/PThread.h index 2ddf9805..e6324581 100755 --- a/folly/portability/PThread.h +++ b/folly/portability/PThread.h @@ -16,6 +16,34 @@ #pragma once +#include + +#if !FOLLY_HAVE_PTHREAD + +#ifndef _WIN32 +#error Building Folly without pthreads is only supported on Windows. +#endif + +#include +#include + +namespace folly { +namespace portability { +namespace pthread { +using pthread_key_t = DWORD; + +int pthread_key_create(pthread_key_t* key, void (*destructor)(void*)); +int pthread_key_delete(pthread_key_t key); +void* pthread_getspecific(pthread_key_t key); +int pthread_setspecific(pthread_key_t key, const void* value); +} +} +} + +/* using override */ using namespace folly::portability::pthread; + +#else + #include #ifdef _WIN32 @@ -95,3 +123,4 @@ struct hash { }; } #endif +#endif -- 2.34.1