ObjFW
OFTLSKey.h
1 /*
2  * Copyright (c) 2008-2023 Jonathan Schleifer <js@nil.im>
3  *
4  * All rights reserved.
5  *
6  * This file is part of ObjFW. It may be distributed under the terms of the
7  * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
8  * the packaging of this file.
9  *
10  * Alternatively, it may be distributed under the terms of the GNU General
11  * Public License, either version 2 or 3, which can be found in the file
12  * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
13  * file.
14  */
15 
16 #include "objfw-defs.h"
17 
18 #include <errno.h>
19 
20 #include "platform.h"
21 
22 #if !defined(OF_HAVE_THREADS) || \
23  (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS))
24 # error No thread-local storage available!
25 #endif
26 
27 #import "macros.h"
28 
29 #if defined(OF_HAVE_PTHREADS)
30 # include <pthread.h>
31 typedef pthread_key_t OFTLSKey;
32 #elif defined(OF_WINDOWS)
33 # include <windows.h>
34 typedef DWORD OFTLSKey;
35 #elif defined(OF_MORPHOS)
36 # include <proto/exec.h>
37 typedef ULONG OFTLSKey;
38 #elif defined(OF_AMIGAOS)
39 typedef struct _OFTLSKey {
40  struct objc_hashtable *table;
41  struct _OFTLSKey *next, *previous;
42 } *OFTLSKey;
43 #endif
44 
45 #ifdef __cplusplus
46 extern "C" {
47 #endif
48 extern int OFTLSKeyNew(OFTLSKey *key);
49 extern int OFTLSKeyFree(OFTLSKey key);
50 #ifdef __cplusplus
51 }
52 #endif
53 
54 /* TLS keys are inlined for performance. */
55 
56 #if defined(OF_HAVE_PTHREADS)
57 static OF_INLINE void *
58 OFTLSKeyGet(OFTLSKey key)
59 {
60  return pthread_getspecific(key);
61 }
62 
63 static OF_INLINE int
64 OFTLSKeySet(OFTLSKey key, void *ptr)
65 {
66  return pthread_setspecific(key, ptr);
67 }
68 #elif defined(OF_WINDOWS)
69 static OF_INLINE void *
70 OFTLSKeyGet(OFTLSKey key)
71 {
72  return TlsGetValue(key);
73 }
74 
75 static OF_INLINE int
76 OFTLSKeySet(OFTLSKey key, void *ptr)
77 {
78  return (TlsSetValue(key, ptr) ? 0 : EINVAL);
79 }
80 #elif defined(OF_MORPHOS)
81 static OF_INLINE void *
82 OFTLSKeyGet(OFTLSKey key)
83 {
84  return (void *)TLSGetValue(key);
85 }
86 
87 static OF_INLINE int
88 OFTLSKeySet(OFTLSKey key, void *ptr)
89 {
90  return (TLSSetValue(key, (APTR)ptr) ? 0 : EINVAL);
91 }
92 #elif defined(OF_AMIGAOS)
93 /* Those are too big too inline. */
94 # ifdef __cplusplus
95 extern "C" {
96 # endif
97 extern void *OFTLSKeyGet(OFTLSKey key);
98 extern int OFTLSKeySet(OFTLSKey key, void *ptr);
99 # ifdef __cplusplus
100 }
101 # endif
102 #endif