Commit | Line | Data |
---|---|---|
7217e0ca ML |
1 | /* |
2 | * Mesa 3-D graphics library | |
3 | * Version: 6.5.1 | |
4 | * | |
5 | * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. | |
6 | * | |
7 | * Permission is hereby granted, free of charge, to any person obtaining a | |
8 | * copy of this software and associated documentation files (the "Software"), | |
9 | * to deal in the Software without restriction, including without limitation | |
10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
11 | * and/or sell copies of the Software, and to permit persons to whom the | |
12 | * Software is furnished to do so, subject to the following conditions: | |
13 | * | |
14 | * The above copyright notice and this permission notice shall be included | |
15 | * in all copies or substantial portions of the Software. | |
16 | * | |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
20 | * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |
21 | * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |
22 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
23 | */ | |
24 | ||
25 | /* | |
26 | * XXX There's probably some work to do in order to make this file | |
27 | * truly reusable outside of Mesa. | |
28 | */ | |
29 | ||
30 | #ifdef HAVE_DIX_CONFIG_H | |
31 | #include <dix-config.h> | |
32 | #include <X11/Xfuncproto.h> | |
33 | #endif | |
34 | ||
35 | #include <stdlib.h> | |
36 | #include <stdio.h> | |
37 | #include "glthread.h" | |
38 | ||
39 | /* | |
40 | * This file should still compile even when THREADS is not defined. | |
41 | * This is to make things easier to deal with on the makefile scene.. | |
42 | */ | |
43 | #ifdef THREADS | |
44 | #include <errno.h> | |
45 | ||
46 | /* | |
47 | * Error messages | |
48 | */ | |
49 | #define INIT_TSD_ERROR "_glthread_: failed to allocate key for thread specific data" | |
50 | #define GET_TSD_ERROR "_glthread_: failed to get thread specific data" | |
51 | #define SET_TSD_ERROR "_glthread_: thread failed to set thread specific data" | |
52 | ||
53 | /* | |
54 | * Magic number to determine if a TSD object has been initialized. | |
55 | * Kind of a hack but there doesn't appear to be a better cross-platform | |
56 | * solution. | |
57 | */ | |
58 | #define INIT_MAGIC 0xff8adc98 | |
59 | ||
60 | /* | |
61 | * POSIX Threads -- The best way to go if your platform supports them. | |
62 | * Solaris >= 2.5 have POSIX threads, IRIX >= 6.4 reportedly | |
63 | * has them, and many of the free Unixes now have them. | |
64 | * Be sure to use appropriate -mt or -D_REENTRANT type | |
65 | * compile flags when building. | |
66 | */ | |
67 | #ifdef PTHREADS | |
68 | ||
69 | _X_EXPORT unsigned long | |
70 | _glthread_GetID(void) | |
71 | { | |
72 | return (unsigned long) pthread_self(); | |
73 | } | |
74 | ||
75 | void | |
76 | _glthread_InitTSD(_glthread_TSD * tsd) | |
77 | { | |
78 | if (pthread_key_create(&tsd->key, NULL /*free */ ) != 0) { | |
79 | perror(INIT_TSD_ERROR); | |
80 | exit(-1); | |
81 | } | |
82 | tsd->initMagic = INIT_MAGIC; | |
83 | } | |
84 | ||
85 | void * | |
86 | _glthread_GetTSD(_glthread_TSD * tsd) | |
87 | { | |
88 | if (tsd->initMagic != (int) INIT_MAGIC) { | |
89 | _glthread_InitTSD(tsd); | |
90 | } | |
91 | return pthread_getspecific(tsd->key); | |
92 | } | |
93 | ||
94 | void | |
95 | _glthread_SetTSD(_glthread_TSD * tsd, void *ptr) | |
96 | { | |
97 | if (tsd->initMagic != (int) INIT_MAGIC) { | |
98 | _glthread_InitTSD(tsd); | |
99 | } | |
100 | if (pthread_setspecific(tsd->key, ptr) != 0) { | |
101 | perror(SET_TSD_ERROR); | |
102 | exit(-1); | |
103 | } | |
104 | } | |
105 | ||
106 | #endif /* PTHREADS */ | |
107 | ||
108 | /* | |
109 | * Win32 Threads. The only available option for Windows 95/NT. | |
110 | * Be sure that you compile using the Multithreaded runtime, otherwise | |
111 | * bad things will happen. | |
112 | */ | |
113 | #ifdef WIN32_THREADS | |
114 | ||
115 | void | |
116 | FreeTSD(_glthread_TSD * p) | |
117 | { | |
118 | if (p->initMagic == INIT_MAGIC) { | |
119 | TlsFree(p->key); | |
120 | p->initMagic = 0; | |
121 | } | |
122 | } | |
123 | ||
124 | void | |
125 | InsteadOf_exit(int nCode) | |
126 | { | |
127 | DWORD dwErr = GetLastError(); | |
128 | } | |
129 | ||
130 | unsigned long | |
131 | _glthread_GetID(void) | |
132 | { | |
133 | return GetCurrentThreadId(); | |
134 | } | |
135 | ||
136 | void | |
137 | _glthread_InitTSD(_glthread_TSD * tsd) | |
138 | { | |
139 | tsd->key = TlsAlloc(); | |
140 | if (tsd->key == TLS_OUT_OF_INDEXES) { | |
141 | perror("Mesa:_glthread_InitTSD"); | |
142 | InsteadOf_exit(-1); | |
143 | } | |
144 | tsd->initMagic = INIT_MAGIC; | |
145 | } | |
146 | ||
147 | void * | |
148 | _glthread_GetTSD(_glthread_TSD * tsd) | |
149 | { | |
150 | if (tsd->initMagic != INIT_MAGIC) { | |
151 | _glthread_InitTSD(tsd); | |
152 | } | |
153 | return TlsGetValue(tsd->key); | |
154 | } | |
155 | ||
156 | void | |
157 | _glthread_SetTSD(_glthread_TSD * tsd, void *ptr) | |
158 | { | |
159 | /* the following code assumes that the _glthread_TSD has been initialized | |
160 | to zero at creation */ | |
161 | if (tsd->initMagic != INIT_MAGIC) { | |
162 | _glthread_InitTSD(tsd); | |
163 | } | |
164 | if (TlsSetValue(tsd->key, ptr) == 0) { | |
165 | perror("Mesa:_glthread_SetTSD"); | |
166 | InsteadOf_exit(-1); | |
167 | } | |
168 | } | |
169 | ||
170 | #endif /* WIN32_THREADS */ | |
171 | ||
172 | #else /* THREADS */ | |
173 | ||
174 | /* | |
175 | * no-op functions | |
176 | */ | |
177 | ||
178 | _X_EXPORT unsigned long | |
179 | _glthread_GetID(void) | |
180 | { | |
181 | return 0; | |
182 | } | |
183 | ||
184 | void | |
185 | _glthread_InitTSD(_glthread_TSD * tsd) | |
186 | { | |
187 | (void) tsd; | |
188 | } | |
189 | ||
190 | void * | |
191 | _glthread_GetTSD(_glthread_TSD * tsd) | |
192 | { | |
193 | (void) tsd; | |
194 | return NULL; | |
195 | } | |
196 | ||
197 | void | |
198 | _glthread_SetTSD(_glthread_TSD * tsd, void *ptr) | |
199 | { | |
200 | (void) tsd; | |
201 | (void) ptr; | |
202 | } | |
203 | ||
204 | #endif /* THREADS */ |