Some more OpenSSL 1.1.0 compat APIs
[folly.git] / folly / portability / PThread.h
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <folly/portability/Config.h>
20
21 #if !FOLLY_HAVE_PTHREAD
22
23 #ifndef _WIN32
24 #error Building Folly without pthreads is only supported on Windows.
25 #endif
26
27 #include <folly/portability/Windows.h>
28 #include <cstdint>
29
30 namespace folly {
31 namespace portability {
32 namespace pthread {
33 using pthread_key_t = DWORD;
34
35 int pthread_key_create(pthread_key_t* key, void (*destructor)(void*));
36 int pthread_key_delete(pthread_key_t key);
37 void* pthread_getspecific(pthread_key_t key);
38 int pthread_setspecific(pthread_key_t key, const void* value);
39 }
40 }
41 }
42
43 /* using override */ using namespace folly::portability::pthread;
44
45 #else
46
47 #include <pthread.h>
48
49 #ifdef _WIN32
50 // We implement a sane comparison operand for
51 // pthread_t and an integer so that it may be
52 // compared against 0.
53
54 inline bool operator==(pthread_t ptA, unsigned int b) {
55   if (ptA.p == nullptr) {
56     return b == 0;
57   }
58   return pthread_getw32threadid_np(ptA) == b;
59 }
60
61 inline bool operator!=(pthread_t ptA, unsigned int b) {
62   if (ptA.p == nullptr) {
63     return b != 0;
64   }
65   return pthread_getw32threadid_np(ptA) != b;
66 }
67
68 inline bool operator==(pthread_t ptA, pthread_t ptB) {
69   return pthread_equal(ptA, ptB) != 0;
70 }
71
72 inline bool operator!=(pthread_t ptA, pthread_t ptB) {
73   return pthread_equal(ptA, ptB) == 0;
74 }
75
76 inline bool operator<(pthread_t ptA, pthread_t ptB) {
77   return ptA.p < ptB.p;
78 }
79
80 inline bool operator!(pthread_t ptA) {
81   return ptA == 0;
82 }
83
84 inline int pthread_attr_getstack(
85     pthread_attr_t* attr,
86     void** stackaddr,
87     size_t* stacksize) {
88   if (pthread_attr_getstackaddr(attr, stackaddr) != 0) {
89     return -1;
90   }
91   if (pthread_attr_getstacksize(attr, stacksize) != 0) {
92     return -1;
93   }
94   return 0;
95 }
96
97 inline int
98 pthread_attr_setstack(pthread_attr_t* attr, void* stackaddr, size_t stacksize) {
99   if (pthread_attr_setstackaddr(attr, stackaddr) != 0) {
100     return -1;
101   }
102   if (pthread_attr_setstacksize(attr, stacksize) != 0) {
103     return -1;
104   }
105   return 0;
106 }
107
108 inline int pthread_attr_getguardsize(
109     pthread_attr_t* /* attr */,
110     size_t* guardsize) {
111   *guardsize = 0;
112   return 0;
113 }
114
115 #include <functional>
116 namespace std {
117 template <>
118 struct hash<pthread_t> {
119   std::size_t operator()(const pthread_t& k) const {
120     return 0 ^ std::hash<decltype(k.p)>()(k.p) ^
121         std::hash<decltype(k.x)>()(k.x);
122   }
123 };
124 }
125 #endif
126 #endif