ObjFW
OFTLSKey.h
1 /*
2  * Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
3  *
4  * All rights reserved.
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License version 3.0 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13  * version 3.0 for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * version 3.0 along with this program. If not, see
17  * <https://www.gnu.org/licenses/>.
18  */
19 
20 #include "objfw-defs.h"
21 
22 #include <errno.h>
23 
24 #include "platform.h"
25 
26 #if !defined(OF_HAVE_THREADS) || \
27  (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS))
28 # error No thread-local storage available!
29 #endif
30 
31 #import "macros.h"
32 
33 #if defined(OF_HAVE_PTHREADS)
34 # include <pthread.h>
35 typedef pthread_key_t OFTLSKey;
36 #elif defined(OF_WINDOWS)
37 # include <windows.h>
38 typedef DWORD OFTLSKey;
39 #elif defined(OF_MORPHOS)
40 # include <proto/exec.h>
41 typedef ULONG OFTLSKey;
42 #elif defined(OF_AMIGAOS)
43 typedef struct _OFTLSKey {
44  struct objc_hashtable *table;
45  struct _OFTLSKey *next, *previous;
46 } *OFTLSKey;
47 #endif
48 
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52 extern int OFTLSKeyNew(OFTLSKey *key);
53 extern int OFTLSKeyFree(OFTLSKey key);
54 #ifdef __cplusplus
55 }
56 #endif
57 
58 /* TLS keys are inlined for performance. */
59 
60 #if defined(OF_HAVE_PTHREADS)
61 static OF_INLINE void *
62 OFTLSKeyGet(OFTLSKey key)
63 {
64  return pthread_getspecific(key);
65 }
66 
67 static OF_INLINE int
68 OFTLSKeySet(OFTLSKey key, void *ptr)
69 {
70  return pthread_setspecific(key, ptr);
71 }
72 #elif defined(OF_WINDOWS)
73 static OF_INLINE void *
74 OFTLSKeyGet(OFTLSKey key)
75 {
76  return TlsGetValue(key);
77 }
78 
79 static OF_INLINE int
80 OFTLSKeySet(OFTLSKey key, void *ptr)
81 {
82  return (TlsSetValue(key, ptr) ? 0 : EINVAL);
83 }
84 #elif defined(OF_MORPHOS)
85 static OF_INLINE void *
86 OFTLSKeyGet(OFTLSKey key)
87 {
88  return (void *)TLSGetValue(key);
89 }
90 
91 static OF_INLINE int
92 OFTLSKeySet(OFTLSKey key, void *ptr)
93 {
94  return (TLSSetValue(key, (APTR)ptr) ? 0 : EINVAL);
95 }
96 #elif defined(OF_AMIGAOS)
97 /* Those are too big too inline. */
98 # ifdef __cplusplus
99 extern "C" {
100 # endif
101 extern void *OFTLSKeyGet(OFTLSKey key);
102 extern int OFTLSKeySet(OFTLSKey key, void *ptr);
103 # ifdef __cplusplus
104 }
105 # endif
106 #endif