File: | src/locking.c |
Location: | line 419, column 14 |
Description: | Assigned value is garbage or undefined |
1 | /* | |||
2 | ||||
3 | Copyright 1992, 1998 The Open Group | |||
4 | ||||
5 | Permission to use, copy, modify, distribute, and sell this software and its | |||
6 | documentation for any purpose is hereby granted without fee, provided that | |||
7 | the above copyright notice appear in all copies and that both that | |||
8 | copyright notice and this permission notice appear in supporting | |||
9 | documentation. | |||
10 | ||||
11 | The above copyright notice and this permission notice shall be included in | |||
12 | all copies or substantial portions of the Software. | |||
13 | ||||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
17 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
18 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
20 | ||||
21 | Except as contained in this notice, the name of The Open Group shall not be | |||
22 | used in advertising or otherwise to promote the sale, use or other dealings | |||
23 | in this Software without prior written authorization from The Open Group. | |||
24 | ||||
25 | */ | |||
26 | ||||
27 | /* | |||
28 | * Author: Stephen Gildea, MIT X Consortium | |||
29 | * | |||
30 | * locking.c - multi-thread locking routines implemented in C Threads | |||
31 | */ | |||
32 | ||||
33 | #ifdef HAVE_CONFIG_H1 | |||
34 | #include <config.h> | |||
35 | #endif | |||
36 | #include "Xlibint.h" | |||
37 | #undef _XLockMutex | |||
38 | #undef _XUnlockMutex | |||
39 | #undef _XCreateMutex | |||
40 | #undef _XFreeMutex | |||
41 | ||||
42 | #ifdef XTHREADS1 | |||
43 | ||||
44 | #ifdef __UNIXWARE__ | |||
45 | #include <dlfcn.h> | |||
46 | #endif | |||
47 | ||||
48 | #include "Xprivate.h" | |||
49 | #include "locking.h" | |||
50 | #ifdef XTHREADS_WARN | |||
51 | #include <stdio.h> /* for warn/debug stuff */ | |||
52 | #endif | |||
53 | ||||
54 | /* Additional arguments for source code location lock call was made from */ | |||
55 | #if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) | |||
56 | # define XTHREADS_FILE_LINE_ARGS \ | |||
57 | , \ | |||
58 | char* file, /* source file, from macro */ \ | |||
59 | int line | |||
60 | #else | |||
61 | # define XTHREADS_FILE_LINE_ARGS /* None */ | |||
62 | #endif | |||
63 | ||||
64 | ||||
65 | #define NUM_FREE_CVLS4 4 | |||
66 | ||||
67 | /* in lcWrap.c */ | |||
68 | extern LockInfoPtr _Xi18n_lock; | |||
69 | ||||
70 | #ifdef WIN32 | |||
71 | static DWORD _X_TlsIndex = (DWORD)-1; | |||
72 | ||||
73 | void _Xthread_init(void) | |||
74 | { | |||
75 | if (_X_TlsIndex == (DWORD)-1) | |||
76 | _X_TlsIndex = TlsAlloc(); | |||
77 | } | |||
78 | ||||
79 | struct _xthread_waiter * | |||
80 | _Xthread_waiter(void) | |||
81 | { | |||
82 | struct _xthread_waiter *me; | |||
83 | ||||
84 | if (!(me = TlsGetValue(_X_TlsIndex))) { | |||
85 | me = xmalloc(sizeof(struct _xthread_waiter))malloc(((sizeof(struct _xthread_waiter)) == 0 ? 1 : (sizeof(struct _xthread_waiter)))); | |||
86 | me->sem = CreateSemaphore(NULL((void*)0), 0, 1, NULL((void*)0)); | |||
87 | me->next = NULL((void*)0); | |||
88 | TlsSetValue(_X_TlsIndex, me); | |||
89 | } | |||
90 | return me; | |||
91 | } | |||
92 | #endif /* WIN32 */ | |||
93 | ||||
94 | static xthread_t _Xthread_self(void) | |||
95 | { | |||
96 | return xthread_selfpthread_self(); | |||
97 | } | |||
98 | ||||
99 | static LockInfoRec global_lock; | |||
100 | static LockInfoRec i18n_lock; | |||
101 | ||||
102 | static void _XLockMutex( | |||
103 | LockInfoPtr lip | |||
104 | XTHREADS_FILE_LINE_ARGS | |||
105 | ) | |||
106 | { | |||
107 | xmutex_lock(lip->lock)pthread_mutex_lock(lip->lock); | |||
108 | } | |||
109 | ||||
110 | static void _XUnlockMutex( | |||
111 | LockInfoPtr lip | |||
112 | XTHREADS_FILE_LINE_ARGS | |||
113 | ) | |||
114 | { | |||
115 | xmutex_unlock(lip->lock)pthread_mutex_unlock(lip->lock); | |||
116 | } | |||
117 | ||||
118 | static void _XCreateMutex( | |||
119 | LockInfoPtr lip) | |||
120 | { | |||
121 | lip->lock = xmutex_malloc()(xmutex_t)malloc(((sizeof(xmutex_rec)) == 0 ? 1 : (sizeof(xmutex_rec )))); | |||
122 | if (lip->lock) { | |||
123 | xmutex_init(lip->lock)pthread_mutex_init(lip->lock, ((void*)0)); | |||
124 | xmutex_set_name(lip->lock, "Xlib"); | |||
125 | } | |||
126 | } | |||
127 | ||||
128 | static void _XFreeMutex( | |||
129 | LockInfoPtr lip) | |||
130 | { | |||
131 | xmutex_clear(lip->lock)pthread_mutex_destroy(lip->lock); | |||
132 | xmutex_free(lip->lock)free(((char *)lip->lock)); | |||
133 | } | |||
134 | ||||
135 | #ifdef XTHREADS_WARN | |||
136 | static char *locking_file; | |||
137 | static int locking_line; | |||
138 | static xthread_t locking_thread; | |||
139 | static Boolint xlibint_unlock = False0; /* XlibInt.c may Unlock and re-Lock */ | |||
140 | ||||
141 | /* history that is useful to examine in a debugger */ | |||
142 | #define LOCK_HIST_SIZE 21 | |||
143 | ||||
144 | static struct { | |||
145 | Boolint lockp; /* True for lock, False for unlock */ | |||
146 | xthread_t thread; | |||
147 | char *file; | |||
148 | int line; | |||
149 | } locking_history[LOCK_HIST_SIZE]; | |||
150 | ||||
151 | int lock_hist_loc = 0; /* next slot to fill */ | |||
152 | ||||
153 | static void _XLockDisplayWarn( | |||
154 | Display *dpy, | |||
155 | char *file, /* source file, from macro */ | |||
156 | int line) | |||
157 | { | |||
158 | xthread_t self; | |||
159 | xthread_t old_locker; | |||
160 | ||||
161 | self = xthread_selfpthread_self(); | |||
162 | old_locker = locking_thread; | |||
163 | if (xthread_have_id(old_locker)old_locker) { | |||
164 | if (xthread_equal(old_locker, self)((old_locker) == (self))) | |||
165 | printf("Xlib ERROR: %s line %d thread %x: locking display already locked at %s line %d\n", | |||
166 | file, line, self, locking_file, locking_line); | |||
167 | #ifdef XTHREADS_DEBUG | |||
168 | else | |||
169 | printf("%s line %d: thread %x waiting on lock held by %s line %d thread %x\n", | |||
170 | file, line, self, | |||
171 | locking_file, locking_line, old_locker); | |||
172 | #endif /* XTHREADS_DEBUG */ | |||
173 | } | |||
174 | ||||
175 | xmutex_lock(dpy->lock->mutex)pthread_mutex_lock(dpy->lock->mutex); | |||
176 | ||||
177 | if (strcmp(file, "XlibInt.c") == 0) { | |||
178 | if (!xlibint_unlock) | |||
179 | printf("Xlib ERROR: XlibInt.c line %d thread %x locking display it did not unlock\n", | |||
180 | line, self); | |||
181 | xlibint_unlock = False0; | |||
182 | } | |||
183 | ||||
184 | #ifdef XTHREADS_DEBUG | |||
185 | /* if (old_locker && old_locker != self) */ | |||
186 | if (strcmp("XClearArea.c", file) && strcmp("XDrSegs.c", file)) /* ico */ | |||
187 | printf("%s line %d: thread %x got display lock\n", file, line, self); | |||
188 | #endif /* XTHREADS_DEBUG */ | |||
189 | ||||
190 | locking_thread = self; | |||
191 | if (strcmp(file, "XlibInt.c") != 0) { | |||
192 | locking_file = file; | |||
193 | locking_line = line; | |||
194 | } | |||
195 | locking_history[lock_hist_loc].file = file; | |||
196 | locking_history[lock_hist_loc].line = line; | |||
197 | locking_history[lock_hist_loc].thread = self; | |||
198 | locking_history[lock_hist_loc].lockp = True1; | |||
199 | lock_hist_loc++; | |||
200 | if (lock_hist_loc >= LOCK_HIST_SIZE) | |||
201 | lock_hist_loc = 0; | |||
202 | } | |||
203 | #endif /* XTHREADS_WARN */ | |||
204 | ||||
205 | static void _XUnlockDisplay( | |||
206 | Display *dpy | |||
207 | XTHREADS_FILE_LINE_ARGS | |||
208 | ) | |||
209 | { | |||
210 | #ifdef XTHREADS_WARN | |||
211 | xthread_t self = xthread_selfpthread_self(); | |||
212 | ||||
213 | #ifdef XTHREADS_DEBUG | |||
214 | if (strcmp("XClearArea.c", file) && strcmp("XDrSegs.c", file)) /* ico */ | |||
215 | printf("%s line %d: thread %x unlocking display\n", file, line, self); | |||
216 | #endif /* XTHREADS_DEBUG */ | |||
217 | ||||
218 | if (!xthread_have_id(locking_thread)locking_thread) | |||
219 | printf("Xlib ERROR: %s line %d thread %x: unlocking display that is not locked\n", | |||
220 | file, line, self); | |||
221 | else if (strcmp(file, "XlibInt.c") == 0) | |||
222 | xlibint_unlock = True1; | |||
223 | #ifdef XTHREADS_DEBUG | |||
224 | else if (strcmp(file, locking_file) != 0) | |||
225 | /* not always an error because locking_file is not per-thread */ | |||
226 | printf("%s line %d: unlocking display locked from %s line %d (probably okay)\n", | |||
227 | file, line, locking_file, locking_line); | |||
228 | #endif /* XTHREADS_DEBUG */ | |||
229 | xthread_clear_id(locking_thread)locking_thread = 0; | |||
230 | ||||
231 | locking_history[lock_hist_loc].file = file; | |||
232 | locking_history[lock_hist_loc].line = line; | |||
233 | locking_history[lock_hist_loc].thread = self; | |||
234 | locking_history[lock_hist_loc].lockp = False0; | |||
235 | lock_hist_loc++; | |||
236 | if (lock_hist_loc >= LOCK_HIST_SIZE) | |||
237 | lock_hist_loc = 0; | |||
238 | #endif /* XTHREADS_WARN */ | |||
239 | xmutex_unlock(dpy->lock->mutex)pthread_mutex_unlock(dpy->lock->mutex); | |||
240 | } | |||
241 | ||||
242 | ||||
243 | static struct _XCVList *_XCreateCVL( | |||
244 | Display *dpy) | |||
245 | { | |||
246 | struct _XCVList *cvl; | |||
247 | ||||
248 | if ((cvl = dpy->lock->free_cvls) != NULL((void*)0)) { | |||
249 | dpy->lock->free_cvls = cvl->next; | |||
250 | dpy->lock->num_free_cvls--; | |||
251 | } else { | |||
252 | cvl = Xmalloc(sizeof(struct _XCVList))malloc(((sizeof(struct _XCVList)) == 0 ? 1 : (sizeof(struct _XCVList )))); | |||
253 | if (!cvl) | |||
254 | return NULL((void*)0); | |||
255 | cvl->cv = xcondition_malloc()(xcondition_t)malloc(((sizeof(xcondition_rec)) == 0 ? 1 : (sizeof (xcondition_rec)))); | |||
256 | if (!cvl->cv) { | |||
257 | Xfree(cvl)free((cvl)); | |||
258 | return NULL((void*)0); | |||
259 | } | |||
260 | xcondition_init(cvl->cv)pthread_cond_init(cvl->cv, ((void*)0)); | |||
261 | xcondition_set_name(cvl->cv, "Xlib read queue"); | |||
262 | } | |||
263 | cvl->next = NULL((void*)0); | |||
264 | return cvl; | |||
265 | } | |||
266 | ||||
267 | /* Put ourselves on the queue to read the connection. | |||
268 | Allocates and returns a queue element. */ | |||
269 | ||||
270 | static struct _XCVList * | |||
271 | _XPushReader( | |||
272 | Display *dpy, | |||
273 | struct _XCVList ***tail) | |||
274 | { | |||
275 | struct _XCVList *cvl; | |||
276 | ||||
277 | cvl = _XCreateCVL(dpy); | |||
278 | #ifdef XTHREADS_DEBUG | |||
279 | printf("_XPushReader called in thread %x, pushing %x\n", | |||
280 | xthread_selfpthread_self(), cvl); | |||
281 | #endif | |||
282 | **tail = cvl; | |||
283 | *tail = &cvl->next; | |||
284 | return cvl; | |||
285 | } | |||
286 | ||||
287 | /* signal the next thread waiting to read the connection */ | |||
288 | ||||
289 | static void _XPopReader( | |||
290 | Display *dpy, | |||
291 | struct _XCVList **list, | |||
292 | struct _XCVList ***tail) | |||
293 | { | |||
294 | register struct _XCVList *front = *list; | |||
295 | ||||
296 | #ifdef XTHREADS_DEBUG | |||
297 | printf("_XPopReader called in thread %x, popping %x\n", | |||
298 | xthread_selfpthread_self(), front); | |||
299 | #endif | |||
300 | ||||
301 | if (dpy->flags & XlibDisplayProcConni(1L << 4)) | |||
302 | /* we never added ourself in the first place */ | |||
303 | return; | |||
304 | ||||
305 | if (front) { /* check "front" for paranoia */ | |||
306 | *list = front->next; | |||
307 | if (*tail == &front->next) /* did we free the last elt? */ | |||
308 | *tail = list; | |||
309 | if (dpy->lock->num_free_cvls < NUM_FREE_CVLS4) { | |||
310 | front->next = dpy->lock->free_cvls; | |||
311 | dpy->lock->free_cvls = front; | |||
312 | dpy->lock->num_free_cvls++; | |||
313 | } else { | |||
314 | xcondition_clear(front->cv)pthread_cond_destroy(front->cv); | |||
315 | Xfree(front->cv)free((front->cv)); | |||
316 | Xfree(front)free((front)); | |||
317 | } | |||
318 | } | |||
319 | ||||
320 | /* signal new front after it is in place */ | |||
321 | if ((dpy->lock->reply_first = (dpy->lock->reply_awaiters != NULL((void*)0)))) { | |||
322 | ConditionSignal(dpy, dpy->lock->reply_awaiters->cv)if ((dpy)->lock) (*(dpy)->lock->condition_signal)(dpy ->lock->reply_awaiters->cv); | |||
323 | } else if (dpy->lock->event_awaiters) { | |||
324 | ConditionSignal(dpy, dpy->lock->event_awaiters->cv)if ((dpy)->lock) (*(dpy)->lock->condition_signal)(dpy ->lock->event_awaiters->cv); | |||
325 | } | |||
326 | } | |||
327 | ||||
328 | static void _XConditionWait( | |||
329 | xcondition_t cv, | |||
330 | xmutex_t mutex | |||
331 | XTHREADS_FILE_LINE_ARGS | |||
332 | ) | |||
333 | { | |||
334 | #ifdef XTHREADS_WARN | |||
335 | xthread_t self = xthread_selfpthread_self(); | |||
336 | char *old_file = locking_file; | |||
337 | int old_line = locking_line; | |||
338 | ||||
339 | #ifdef XTHREADS_DEBUG | |||
340 | printf("line %d thread %x in condition wait\n", line, self); | |||
341 | #endif | |||
342 | xthread_clear_id(locking_thread)locking_thread = 0; | |||
343 | ||||
344 | locking_history[lock_hist_loc].file = file; | |||
345 | locking_history[lock_hist_loc].line = line; | |||
346 | locking_history[lock_hist_loc].thread = self; | |||
347 | locking_history[lock_hist_loc].lockp = False0; | |||
348 | lock_hist_loc++; | |||
349 | if (lock_hist_loc >= LOCK_HIST_SIZE) | |||
350 | lock_hist_loc = 0; | |||
351 | #endif /* XTHREADS_WARN */ | |||
352 | ||||
353 | xcondition_wait(cv, mutex)pthread_cond_wait(cv,mutex); | |||
354 | ||||
355 | #ifdef XTHREADS_WARN | |||
356 | locking_thread = self; | |||
357 | locking_file = old_file; | |||
358 | locking_line = old_line; | |||
359 | ||||
360 | locking_history[lock_hist_loc].file = file; | |||
361 | locking_history[lock_hist_loc].line = line; | |||
362 | locking_history[lock_hist_loc].thread = self; | |||
363 | locking_history[lock_hist_loc].lockp = True1; | |||
364 | lock_hist_loc++; | |||
365 | if (lock_hist_loc >= LOCK_HIST_SIZE) | |||
366 | lock_hist_loc = 0; | |||
367 | #ifdef XTHREADS_DEBUG | |||
368 | printf("line %d thread %x was signaled\n", line, self); | |||
369 | #endif /* XTHREADS_DEBUG */ | |||
370 | #endif /* XTHREADS_WARN */ | |||
371 | } | |||
372 | ||||
373 | static void _XConditionSignal( | |||
374 | xcondition_t cv | |||
375 | XTHREADS_FILE_LINE_ARGS | |||
376 | ) | |||
377 | { | |||
378 | #ifdef XTHREADS_WARN | |||
379 | #ifdef XTHREADS_DEBUG | |||
380 | printf("line %d thread %x is signalling\n", line, xthread_selfpthread_self()); | |||
381 | #endif | |||
382 | #endif | |||
383 | xcondition_signal(cv)pthread_cond_signal(cv); | |||
384 | } | |||
385 | ||||
386 | ||||
387 | static void _XConditionBroadcast( | |||
388 | xcondition_t cv | |||
389 | XTHREADS_FILE_LINE_ARGS | |||
390 | ) | |||
391 | { | |||
392 | #ifdef XTHREADS_WARN | |||
393 | #ifdef XTHREADS_DEBUG | |||
394 | printf("line %d thread %x is broadcasting\n", line, xthread_selfpthread_self()); | |||
395 | #endif | |||
396 | #endif | |||
397 | xcondition_broadcast(cv)pthread_cond_broadcast(cv); | |||
398 | } | |||
399 | ||||
400 | ||||
401 | static void _XFreeDisplayLock( | |||
402 | Display *dpy) | |||
403 | { | |||
404 | struct _XCVList *cvl; | |||
405 | ||||
406 | if (dpy->lock != NULL((void*)0)) { | |||
407 | if (dpy->lock->mutex != NULL((void*)0)) { | |||
408 | xmutex_clear(dpy->lock->mutex)pthread_mutex_destroy(dpy->lock->mutex); | |||
409 | xmutex_free(dpy->lock->mutex)free(((char *)dpy->lock->mutex)); | |||
410 | } | |||
411 | if (dpy->lock->cv != NULL((void*)0)) { | |||
412 | xcondition_clear(dpy->lock->cv)pthread_cond_destroy(dpy->lock->cv); | |||
413 | xcondition_free(dpy->lock->cv)free(((char *)dpy->lock->cv)); | |||
414 | } | |||
415 | if (dpy->lock->writers != NULL((void*)0)) { | |||
416 | xcondition_clear(dpy->lock->writers)pthread_cond_destroy(dpy->lock->writers); | |||
417 | xcondition_free(dpy->lock->writers)free(((char *)dpy->lock->writers)); | |||
418 | } | |||
419 | while ((cvl = dpy->lock->free_cvls)) { | |||
| ||||
420 | dpy->lock->free_cvls = cvl->next; | |||
421 | xcondition_clear(cvl->cv)pthread_cond_destroy(cvl->cv); | |||
422 | Xfree(cvl->cv)free((cvl->cv)); | |||
423 | Xfree(cvl)free((cvl)); | |||
424 | } | |||
425 | Xfree(dpy->lock)free((dpy->lock)); | |||
426 | dpy->lock = NULL((void*)0); | |||
427 | } | |||
428 | if (dpy->lock_fns != NULL((void*)0)) { | |||
429 | Xfree(dpy->lock_fns)free((dpy->lock_fns)); | |||
430 | dpy->lock_fns = NULL((void*)0); | |||
431 | } | |||
432 | } | |||
433 | ||||
434 | /* | |||
435 | * wait for thread with user-level display lock to release it. | |||
436 | */ | |||
437 | ||||
438 | static void _XDisplayLockWait( | |||
439 | Display *dpy) | |||
440 | { | |||
441 | xthread_t self; | |||
442 | ||||
443 | while (dpy->lock->locking_level > 0) { | |||
444 | self = xthread_selfpthread_self(); | |||
445 | if (xthread_equal(dpy->lock->locking_thread, self)((dpy->lock->locking_thread) == (self))) | |||
446 | break; | |||
447 | ConditionWait(dpy, dpy->lock->cv)if ((dpy)->lock) (*(dpy)->lock->condition_wait)(dpy-> lock->cv, (dpy)->lock->mutex); | |||
448 | } | |||
449 | } | |||
450 | ||||
451 | static void _XLockDisplay( | |||
452 | Display *dpy | |||
453 | XTHREADS_FILE_LINE_ARGS | |||
454 | ) | |||
455 | { | |||
456 | #ifdef XTHREADS_WARN | |||
457 | _XLockDisplayWarn(dpy, file, line); | |||
458 | #else | |||
459 | xmutex_lock(dpy->lock->mutex)pthread_mutex_lock(dpy->lock->mutex); | |||
460 | #endif | |||
461 | if (dpy->lock->locking_level > 0) | |||
462 | _XDisplayLockWait(dpy); | |||
463 | _XIDHandler(dpy); | |||
464 | _XSeqSyncFunction(dpy); | |||
465 | } | |||
466 | ||||
467 | /* | |||
468 | * _XReply is allowed to exit from select/poll and clean up even if a | |||
469 | * user-level lock is in force, so it uses this instead of _XFancyLockDisplay. | |||
470 | */ | |||
471 | static void _XInternalLockDisplay( | |||
472 | Display *dpy, | |||
473 | Boolint wskip | |||
474 | XTHREADS_FILE_LINE_ARGS | |||
475 | ) | |||
476 | { | |||
477 | #ifdef XTHREADS_WARN | |||
478 | _XLockDisplayWarn(dpy, file, line); | |||
479 | #else | |||
480 | xmutex_lock(dpy->lock->mutex)pthread_mutex_lock(dpy->lock->mutex); | |||
481 | #endif | |||
482 | if (!wskip && dpy->lock->locking_level > 0) | |||
483 | _XDisplayLockWait(dpy); | |||
484 | } | |||
485 | ||||
486 | static void _XUserLockDisplay( | |||
487 | register Display* dpy) | |||
488 | { | |||
489 | _XDisplayLockWait(dpy); | |||
490 | ||||
491 | if (++dpy->lock->locking_level == 1) { | |||
492 | dpy->lock->lock_wait = _XDisplayLockWait; | |||
493 | dpy->lock->locking_thread = xthread_selfpthread_self(); | |||
494 | } | |||
495 | } | |||
496 | ||||
497 | static | |||
498 | void _XUserUnlockDisplay( | |||
499 | register Display* dpy) | |||
500 | { | |||
501 | if (dpy->lock->locking_level > 0 && --dpy->lock->locking_level == 0) { | |||
502 | /* signal other threads that might be waiting in XLockDisplay */ | |||
503 | ConditionBroadcast(dpy, dpy->lock->cv)if ((dpy)->lock) (*(dpy)->lock->condition_broadcast) (dpy->lock->cv); | |||
504 | dpy->lock->lock_wait = NULL((void*)0); | |||
505 | xthread_clear_id(dpy->lock->locking_thread)dpy->lock->locking_thread = 0; | |||
506 | } | |||
507 | } | |||
508 | ||||
509 | /* returns 0 if initialized ok, -1 if unable to allocate | |||
510 | a mutex or other memory */ | |||
511 | ||||
512 | static int _XInitDisplayLock( | |||
513 | Display *dpy) | |||
514 | { | |||
515 | dpy->lock_fns = Xmalloc(sizeof(struct _XLockPtrs))malloc(((sizeof(struct _XLockPtrs)) == 0 ? 1 : (sizeof(struct _XLockPtrs)))); | |||
516 | if (dpy->lock_fns == NULL((void*)0)) | |||
| ||||
517 | return -1; | |||
518 | dpy->lock = Xmalloc(sizeof(struct _XLockInfo))malloc(((sizeof(struct _XLockInfo)) == 0 ? 1 : (sizeof(struct _XLockInfo)))); | |||
519 | if (dpy->lock == NULL((void*)0)) { | |||
520 | _XFreeDisplayLock(dpy); | |||
521 | return -1; | |||
522 | } | |||
523 | dpy->lock->cv = xcondition_malloc()(xcondition_t)malloc(((sizeof(xcondition_rec)) == 0 ? 1 : (sizeof (xcondition_rec)))); | |||
524 | dpy->lock->mutex = xmutex_malloc()(xmutex_t)malloc(((sizeof(xmutex_rec)) == 0 ? 1 : (sizeof(xmutex_rec )))); | |||
525 | dpy->lock->writers = xcondition_malloc()(xcondition_t)malloc(((sizeof(xcondition_rec)) == 0 ? 1 : (sizeof (xcondition_rec)))); | |||
526 | if (!dpy->lock->cv || !dpy->lock->mutex || !dpy->lock->writers) { | |||
527 | _XFreeDisplayLock(dpy); | |||
528 | return -1; | |||
529 | } | |||
530 | ||||
531 | dpy->lock->reply_bytes_left = 0; | |||
532 | dpy->lock->reply_was_read = False0; | |||
533 | dpy->lock->reply_awaiters = NULL((void*)0); | |||
534 | dpy->lock->reply_awaiters_tail = &dpy->lock->reply_awaiters; | |||
535 | dpy->lock->event_awaiters = NULL((void*)0); | |||
536 | dpy->lock->event_awaiters_tail = &dpy->lock->event_awaiters; | |||
537 | dpy->lock->reply_first = False0; | |||
538 | dpy->lock->locking_level = 0; | |||
539 | dpy->lock->num_free_cvls = 0; | |||
540 | dpy->lock->free_cvls = NULL((void*)0); | |||
541 | xthread_clear_id(dpy->lock->locking_thread)dpy->lock->locking_thread = 0; | |||
542 | xthread_clear_id(dpy->lock->reading_thread)dpy->lock->reading_thread = 0; | |||
543 | xthread_clear_id(dpy->lock->conni_thread)dpy->lock->conni_thread = 0; | |||
544 | xmutex_init(dpy->lock->mutex)pthread_mutex_init(dpy->lock->mutex, ((void*)0)); | |||
545 | xmutex_set_name(dpy->lock->mutex, "Xlib Display"); | |||
546 | xcondition_init(dpy->lock->cv)pthread_cond_init(dpy->lock->cv, ((void*)0)); | |||
547 | xcondition_set_name(dpy->lock->cv, "XLockDisplay"); | |||
548 | xcondition_init(dpy->lock->writers)pthread_cond_init(dpy->lock->writers, ((void*)0)); | |||
549 | xcondition_set_name(dpy->lock->writers, "Xlib wait for writable"); | |||
550 | dpy->lock_fns->lock_display = _XLockDisplay; | |||
551 | dpy->lock->internal_lock_display = _XInternalLockDisplay; | |||
552 | dpy->lock_fns->unlock_display = _XUnlockDisplay; | |||
553 | dpy->lock->user_lock_display = _XUserLockDisplay; | |||
554 | dpy->lock->user_unlock_display = _XUserUnlockDisplay; | |||
555 | dpy->lock->pop_reader = _XPopReader; | |||
556 | dpy->lock->push_reader = _XPushReader; | |||
557 | dpy->lock->condition_wait = _XConditionWait; | |||
558 | dpy->lock->condition_signal = _XConditionSignal; | |||
559 | dpy->lock->condition_broadcast = _XConditionBroadcast; | |||
560 | dpy->lock->create_cvl = _XCreateCVL; | |||
561 | dpy->lock->lock_wait = NULL((void*)0); /* filled in by XLockDisplay() */ | |||
562 | ||||
563 | return 0; | |||
564 | } | |||
565 | ||||
566 | #ifdef __UNIXWARE__ | |||
567 | xthread_t __x11_thr_self() { return 0; } | |||
568 | xthread_t (*_x11_thr_self)() = __x11_thr_self; | |||
569 | #endif | |||
570 | ||||
571 | ||||
572 | Statusint XInitThreads(void) | |||
573 | { | |||
574 | if (_Xglobal_lock) | |||
575 | return 1; | |||
576 | #ifdef __UNIXWARE__ | |||
577 | else { | |||
578 | void *dl_handle = dlopen(NULL((void*)0), RTLD_LAZY); | |||
579 | if (!dl_handle || | |||
580 | ((_x11_thr_self = (xthread_t(*)())dlsym(dl_handle,"thr_self")) == 0)) { | |||
581 | _x11_thr_self = __x11_thr_self; | |||
582 | (void) fprintf (stderr, | |||
583 | "XInitThreads called, but no libthread in the calling program!\n" ); | |||
584 | } | |||
585 | } | |||
586 | #endif /* __UNIXWARE__ */ | |||
587 | #ifdef xthread_init | |||
588 | xthread_init(); /* return value? */ | |||
589 | #endif | |||
590 | if (!(global_lock.lock = xmutex_malloc()(xmutex_t)malloc(((sizeof(xmutex_rec)) == 0 ? 1 : (sizeof(xmutex_rec )))))) | |||
591 | return 0; | |||
592 | if (!(i18n_lock.lock = xmutex_malloc()(xmutex_t)malloc(((sizeof(xmutex_rec)) == 0 ? 1 : (sizeof(xmutex_rec )))))) { | |||
593 | xmutex_free(global_lock.lock)free(((char *)global_lock.lock)); | |||
594 | global_lock.lock = NULL((void*)0); | |||
595 | return 0; | |||
596 | } | |||
597 | _Xglobal_lock = &global_lock; | |||
598 | xmutex_init(_Xglobal_lock->lock)pthread_mutex_init(_Xglobal_lock->lock, ((void*)0)); | |||
599 | xmutex_set_name(_Xglobal_lock->lock, "Xlib global"); | |||
600 | _Xi18n_lock = &i18n_lock; | |||
601 | xmutex_init(_Xi18n_lock->lock)pthread_mutex_init(_Xi18n_lock->lock, ((void*)0)); | |||
602 | xmutex_set_name(_Xi18n_lock->lock, "Xlib i18n"); | |||
603 | _XLockMutex_fn = _XLockMutex; | |||
604 | _XUnlockMutex_fn = _XUnlockMutex; | |||
605 | _XCreateMutex_fn = _XCreateMutex; | |||
606 | _XFreeMutex_fn = _XFreeMutex; | |||
607 | _XInitDisplayLock_fn = _XInitDisplayLock; | |||
608 | _XFreeDisplayLock_fn = _XFreeDisplayLock; | |||
609 | _Xthread_self_fn = _Xthread_self; | |||
610 | ||||
611 | #ifdef XTHREADS_WARN | |||
612 | #ifdef XTHREADS_DEBUG | |||
613 | setlinebuf(stdout); /* for debugging messages */ | |||
614 | #endif | |||
615 | #endif | |||
616 | ||||
617 | return 1; | |||
618 | } | |||
619 | ||||
620 | #else /* XTHREADS */ | |||
621 | Statusint XInitThreads(void) | |||
622 | { | |||
623 | return 0; | |||
624 | } | |||
625 | #endif /* XTHREADS */ |