Bug Summary

File:src/locking.c
Location:line 419, column 14
Description:Assigned value is garbage or undefined

Annotated Source Code

1/*
2
3Copyright 1992, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in 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 */
68extern LockInfoPtr _Xi18n_lock;
69
70#ifdef WIN32
71static DWORD _X_TlsIndex = (DWORD)-1;
72
73void _Xthread_init(void)
74{
75 if (_X_TlsIndex == (DWORD)-1)
76 _X_TlsIndex = TlsAlloc();
77}
78
79struct _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
94static xthread_t _Xthread_self(void)
95{
96 return xthread_selfpthread_self();
97}
98
99static LockInfoRec global_lock;
100static LockInfoRec i18n_lock;
101
102static void _XLockMutex(
103 LockInfoPtr lip
104 XTHREADS_FILE_LINE_ARGS
105 )
106{
107 xmutex_lock(lip->lock)pthread_mutex_lock(lip->lock);
108}
109
110static void _XUnlockMutex(
111 LockInfoPtr lip
112 XTHREADS_FILE_LINE_ARGS
113 )
114{
115 xmutex_unlock(lip->lock)pthread_mutex_unlock(lip->lock);
116}
117
118static 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
128static 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
136static char *locking_file;
137static int locking_line;
138static xthread_t locking_thread;
139static 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
144static 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
151int lock_hist_loc = 0; /* next slot to fill */
152
153static 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
205static 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
243static 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
270static 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
289static 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
328static 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
373static 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
387static 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
401static void _XFreeDisplayLock(
402 Display *dpy)
403{
404 struct _XCVList *cvl;
405
406 if (dpy->lock != NULL((void*)0)) {
5
Taking true branch
407 if (dpy->lock->mutex != NULL((void*)0)) {
6
Taking false branch
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)) {
7
Taking false branch
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)) {
8
Taking false branch
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)) {
9
Assigned value is garbage or undefined
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
438static 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
451static 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 */
471static 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
486static 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
497static
498void _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
512static 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))
1
Taking false branch
517 return -1;
518 dpy->lock = Xmalloc(sizeof(struct _XLockInfo))malloc(((sizeof(struct _XLockInfo)) == 0 ? 1 : (sizeof(struct
_XLockInfo))))
;
2
Within the expansion of the macro 'Xmalloc':
a
Uninitialized value stored to field 'free_cvls'
519 if (dpy->lock == NULL((void*)0)) {
3
Taking false branch
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);
4
Calling '_XFreeDisplayLock'
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__
567xthread_t __x11_thr_self() { return 0; }
568xthread_t (*_x11_thr_self)() = __x11_thr_self;
569#endif
570
571
572Statusint 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 */
621Statusint XInitThreads(void)
622{
623 return 0;
624}
625#endif /* XTHREADS */