--- /dev/null
+/*\r
+ * Copyright 2017 Facebook, Inc.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <folly/portability/PThread.h>\r
+\r
+#if !FOLLY_HAVE_PTHREAD && _WIN32\r
+#include <unordered_map>\r
+#include <utility>\r
+\r
+namespace folly {\r
+namespace portability {\r
+namespace pthread {\r
+static thread_local struct PThreadLocalMap {\r
+ PThreadLocalMap() = default;\r
+ ~PThreadLocalMap() {\r
+ for (auto kv : keyMap) {\r
+ // Call destruction callbacks if they exist.\r
+ if (kv.second.second != nullptr) {\r
+ kv.second.second(kv.second.first);\r
+ }\r
+ }\r
+ }\r
+\r
+ int createKey(pthread_key_t* key, void (*destructor)(void*)) {\r
+ auto ret = TlsAlloc();\r
+ if (ret == TLS_OUT_OF_INDEXES) {\r
+ return -1;\r
+ }\r
+ *key = ret;\r
+ keyMap.emplace(*key, std::make_pair(nullptr, destructor));\r
+ return 0;\r
+ }\r
+\r
+ int deleteKey(pthread_key_t key) {\r
+ if (!TlsFree(key)) {\r
+ return -1;\r
+ }\r
+ keyMap.erase(key);\r
+ return 0;\r
+ }\r
+\r
+ void* getKey(pthread_key_t key) {\r
+ return TlsGetValue(key);\r
+ }\r
+\r
+ int setKey(pthread_key_t key, void* value) {\r
+ if (!TlsSetValue(key, value)) {\r
+ return -1;\r
+ }\r
+ keyMap[key].first = value;\r
+ return 0;\r
+ }\r
+\r
+ std::unordered_map<pthread_key_t, std::pair<void*, void (*)(void*)>> keyMap{};\r
+} s_tls_key_map;\r
+\r
+int pthread_key_create(pthread_key_t* key, void (*destructor)(void*)) {\r
+ return s_tls_key_map.createKey(key, destructor);\r
+}\r
+\r
+int pthread_key_delete(pthread_key_t key) {\r
+ return s_tls_key_map.deleteKey(key);\r
+}\r
+\r
+void* pthread_getspecific(pthread_key_t key) {\r
+ return s_tls_key_map.getKey(key);\r
+}\r
+\r
+int pthread_setspecific(pthread_key_t key, const void* value) {\r
+ // Yes, the PThread API really is this bad -_-...\r
+ return s_tls_key_map.setKey(key, const_cast<void*>(value));\r
+}\r
+}\r
+}\r
+}\r
+#endif\r
#pragma once
+#include <folly/portability/Config.h>
+
+#if !FOLLY_HAVE_PTHREAD
+
+#ifndef _WIN32
+#error Building Folly without pthreads is only supported on Windows.
+#endif
+
+#include <folly/portability/Windows.h>
+#include <cstdint>
+
+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 <pthread.h>
#ifdef _WIN32
};
}
#endif
+#endif