76
37
# if !defined PTHREAD_RWLOCK_INITIALIZER
79
glthread_rwlock_init (gl_rwlock_t *lock)
40
glthread_rwlock_init_multithreaded (gl_rwlock_t *lock)
81
if (pthread_rwlock_init (&lock->rwlock, NULL) != 0)
44
err = pthread_rwlock_init (&lock->rwlock, NULL);
83
47
lock->initialized = 1;
87
glthread_rwlock_rdlock (gl_rwlock_t *lock)
89
if (!lock->initialized)
91
if (pthread_mutex_lock (&lock->guard) != 0)
93
if (!lock->initialized)
94
glthread_rwlock_init (lock);
95
if (pthread_mutex_unlock (&lock->guard) != 0)
98
if (pthread_rwlock_rdlock (&lock->rwlock) != 0)
103
glthread_rwlock_wrlock (gl_rwlock_t *lock)
105
if (!lock->initialized)
107
if (pthread_mutex_lock (&lock->guard) != 0)
109
if (!lock->initialized)
110
glthread_rwlock_init (lock);
111
if (pthread_mutex_unlock (&lock->guard) != 0)
114
if (pthread_rwlock_wrlock (&lock->rwlock) != 0)
119
glthread_rwlock_unlock (gl_rwlock_t *lock)
121
if (!lock->initialized)
123
if (pthread_rwlock_unlock (&lock->rwlock) != 0)
128
glthread_rwlock_destroy (gl_rwlock_t *lock)
130
if (!lock->initialized)
132
if (pthread_rwlock_destroy (&lock->rwlock) != 0)
52
glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock)
54
if (!lock->initialized)
58
err = pthread_mutex_lock (&lock->guard);
61
if (!lock->initialized)
63
err = glthread_rwlock_init_multithreaded (lock);
66
pthread_mutex_unlock (&lock->guard);
70
err = pthread_mutex_unlock (&lock->guard);
74
return pthread_rwlock_rdlock (&lock->rwlock);
78
glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock)
80
if (!lock->initialized)
84
err = pthread_mutex_lock (&lock->guard);
87
if (!lock->initialized)
89
err = glthread_rwlock_init_multithreaded (lock);
92
pthread_mutex_unlock (&lock->guard);
96
err = pthread_mutex_unlock (&lock->guard);
100
return pthread_rwlock_wrlock (&lock->rwlock);
104
glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock)
106
if (!lock->initialized)
108
return pthread_rwlock_unlock (&lock->rwlock);
112
glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock)
116
if (!lock->initialized)
118
err = pthread_rwlock_destroy (&lock->rwlock);
134
121
lock->initialized = 0;
142
glthread_rwlock_init (gl_rwlock_t *lock)
130
glthread_rwlock_init_multithreaded (gl_rwlock_t *lock)
144
if (pthread_mutex_init (&lock->lock, NULL) != 0)
146
if (pthread_cond_init (&lock->waiting_readers, NULL) != 0)
148
if (pthread_cond_init (&lock->waiting_writers, NULL) != 0)
134
err = pthread_mutex_init (&lock->lock, NULL);
137
err = pthread_cond_init (&lock->waiting_readers, NULL);
140
err = pthread_cond_init (&lock->waiting_writers, NULL);
150
143
lock->waiting_writers_count = 0;
151
144
lock->runcount = 0;
155
glthread_rwlock_rdlock (gl_rwlock_t *lock)
149
glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock)
157
if (pthread_mutex_lock (&lock->lock) != 0)
153
err = pthread_mutex_lock (&lock->lock);
159
156
/* Test whether only readers are currently running, and whether the runcount
160
157
field will not overflow. */
161
158
/* POSIX says: "It is implementation-defined whether the calling thread
165
162
while (!(lock->runcount + 1 > 0 && lock->waiting_writers_count == 0))
167
164
/* This thread has to wait for a while. Enqueue it among the
169
if (pthread_cond_wait (&lock->waiting_readers, &lock->lock) != 0)
166
err = pthread_cond_wait (&lock->waiting_readers, &lock->lock);
169
pthread_mutex_unlock (&lock->lock);
172
173
lock->runcount++;
173
if (pthread_mutex_unlock (&lock->lock) != 0)
174
return pthread_mutex_unlock (&lock->lock);
178
glthread_rwlock_wrlock (gl_rwlock_t *lock)
178
glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock)
180
if (pthread_mutex_lock (&lock->lock) != 0)
182
err = pthread_mutex_lock (&lock->lock);
182
185
/* Test whether no readers or writers are currently running. */
183
186
while (!(lock->runcount == 0))
185
188
/* This thread has to wait for a while. Enqueue it among the
187
190
lock->waiting_writers_count++;
188
if (pthread_cond_wait (&lock->waiting_writers, &lock->lock) != 0)
191
err = pthread_cond_wait (&lock->waiting_writers, &lock->lock);
194
lock->waiting_writers_count--;
195
pthread_mutex_unlock (&lock->lock);
190
198
lock->waiting_writers_count--;
192
200
lock->runcount--; /* runcount becomes -1 */
193
if (pthread_mutex_unlock (&lock->lock) != 0)
201
return pthread_mutex_unlock (&lock->lock);
198
glthread_rwlock_unlock (gl_rwlock_t *lock)
205
glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock)
200
if (pthread_mutex_lock (&lock->lock) != 0)
209
err = pthread_mutex_lock (&lock->lock);
202
212
if (lock->runcount < 0)
204
214
/* Drop a writer lock. */
205
215
if (!(lock->runcount == -1))
217
pthread_mutex_unlock (&lock->lock);
207
220
lock->runcount = 0;
211
224
/* Drop a reader lock. */
212
225
if (!(lock->runcount > 0))
227
pthread_mutex_unlock (&lock->lock);
214
230
lock->runcount--;
216
232
if (lock->runcount == 0)
218
234
/* POSIX recommends that "write locks shall take precedence over read
219
locks", to avoid "writer starvation". */
235
locks", to avoid "writer starvation". */
220
236
if (lock->waiting_writers_count > 0)
222
/* Wake up one of the waiting writers. */
223
if (pthread_cond_signal (&lock->waiting_writers) != 0)
238
/* Wake up one of the waiting writers. */
239
err = pthread_cond_signal (&lock->waiting_writers);
242
pthread_mutex_unlock (&lock->lock);
228
/* Wake up all waiting readers. */
229
if (pthread_cond_broadcast (&lock->waiting_readers) != 0)
248
/* Wake up all waiting readers. */
249
err = pthread_cond_broadcast (&lock->waiting_readers);
252
pthread_mutex_unlock (&lock->lock);
233
if (pthread_mutex_unlock (&lock->lock) != 0)
257
return pthread_mutex_unlock (&lock->lock);
238
glthread_rwlock_destroy (gl_rwlock_t *lock)
261
glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock)
240
if (pthread_mutex_destroy (&lock->lock) != 0)
242
if (pthread_cond_destroy (&lock->waiting_readers) != 0)
244
if (pthread_cond_destroy (&lock->waiting_writers) != 0)
265
err = pthread_mutex_destroy (&lock->lock);
268
err = pthread_cond_destroy (&lock->waiting_readers);
271
err = pthread_cond_destroy (&lock->waiting_writers);
252
281
# if HAVE_PTHREAD_MUTEX_RECURSIVE
254
# if !(defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
257
glthread_recursive_lock_init (gl_recursive_lock_t *lock)
259
pthread_mutexattr_t attributes;
261
if (pthread_mutexattr_init (&attributes) != 0)
263
if (pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE) != 0)
265
if (pthread_mutex_init (&lock->recmutex, &attributes) != 0)
267
if (pthread_mutexattr_destroy (&attributes) != 0)
283
# if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
286
glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
288
pthread_mutexattr_t attributes;
291
err = pthread_mutexattr_init (&attributes);
294
err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);
297
pthread_mutexattr_destroy (&attributes);
300
err = pthread_mutex_init (lock, &attributes);
303
pthread_mutexattr_destroy (&attributes);
306
err = pthread_mutexattr_destroy (&attributes);
315
glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
317
pthread_mutexattr_t attributes;
320
err = pthread_mutexattr_init (&attributes);
323
err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE);
326
pthread_mutexattr_destroy (&attributes);
329
err = pthread_mutex_init (&lock->recmutex, &attributes);
332
pthread_mutexattr_destroy (&attributes);
335
err = pthread_mutexattr_destroy (&attributes);
269
338
lock->initialized = 1;
273
glthread_recursive_lock_lock (gl_recursive_lock_t *lock)
343
glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
275
345
if (!lock->initialized)
277
if (pthread_mutex_lock (&lock->guard) != 0)
349
err = pthread_mutex_lock (&lock->guard);
279
352
if (!lock->initialized)
280
glthread_recursive_lock_init (lock);
281
if (pthread_mutex_unlock (&lock->guard) != 0)
354
err = glthread_recursive_lock_init_multithreaded (lock);
357
pthread_mutex_unlock (&lock->guard);
361
err = pthread_mutex_unlock (&lock->guard);
284
if (pthread_mutex_lock (&lock->recmutex) != 0)
289
glthread_recursive_lock_unlock (gl_recursive_lock_t *lock)
291
if (!lock->initialized)
293
if (pthread_mutex_unlock (&lock->recmutex) != 0)
298
glthread_recursive_lock_destroy (gl_recursive_lock_t *lock)
300
if (!lock->initialized)
302
if (pthread_mutex_destroy (&lock->recmutex) != 0)
365
return pthread_mutex_lock (&lock->recmutex);
369
glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
371
if (!lock->initialized)
373
return pthread_mutex_unlock (&lock->recmutex);
377
glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
381
if (!lock->initialized)
383
err = pthread_mutex_destroy (&lock->recmutex);
304
386
lock->initialized = 0;
312
glthread_recursive_lock_init (gl_recursive_lock_t *lock)
395
glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
314
if (pthread_mutex_init (&lock->mutex, NULL) != 0)
399
err = pthread_mutex_init (&lock->mutex, NULL);
316
402
lock->owner = (pthread_t) 0;
321
glthread_recursive_lock_lock (gl_recursive_lock_t *lock)
408
glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
323
410
pthread_t self = pthread_self ();
324
411
if (lock->owner != self)
326
if (pthread_mutex_lock (&lock->mutex) != 0)
415
err = pthread_mutex_lock (&lock->mutex);
328
418
lock->owner = self;
330
420
if (++(lock->depth) == 0) /* wraparound? */
335
glthread_recursive_lock_unlock (gl_recursive_lock_t *lock)
429
glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
337
431
if (lock->owner != pthread_self ())
339
433
if (lock->depth == 0)
341
435
if (--(lock->depth) == 0)
343
437
lock->owner = (pthread_t) 0;
344
if (pthread_mutex_unlock (&lock->mutex) != 0)
438
return pthread_mutex_unlock (&lock->mutex);
350
glthread_recursive_lock_destroy (gl_recursive_lock_t *lock)
445
glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
352
447
if (lock->owner != (pthread_t) 0)
354
if (pthread_mutex_destroy (&lock->mutex) != 0)
449
return pthread_mutex_destroy (&lock->mutex);
430
531
/* --------------------- gl_recursive_lock_t datatype --------------------- */
433
glthread_recursive_lock_init (gl_recursive_lock_t *lock)
534
glthread_recursive_lock_init_multithreaded (gl_recursive_lock_t *lock)
435
if (mutex_init (&lock->mutex, USYNC_THREAD, NULL) != 0)
538
err = mutex_init (&lock->mutex, USYNC_THREAD, NULL);
437
541
lock->owner = (thread_t) 0;
442
glthread_recursive_lock_lock (gl_recursive_lock_t *lock)
547
glthread_recursive_lock_lock_multithreaded (gl_recursive_lock_t *lock)
444
549
thread_t self = thr_self ();
445
550
if (lock->owner != self)
447
if (mutex_lock (&lock->mutex) != 0)
554
err = mutex_lock (&lock->mutex);
449
557
lock->owner = self;
451
559
if (++(lock->depth) == 0) /* wraparound? */
456
glthread_recursive_lock_unlock (gl_recursive_lock_t *lock)
568
glthread_recursive_lock_unlock_multithreaded (gl_recursive_lock_t *lock)
458
570
if (lock->owner != thr_self ())
460
572
if (lock->depth == 0)
462
574
if (--(lock->depth) == 0)
464
576
lock->owner = (thread_t) 0;
465
if (mutex_unlock (&lock->mutex) != 0)
577
return mutex_unlock (&lock->mutex);
471
glthread_recursive_lock_destroy (gl_recursive_lock_t *lock)
584
glthread_recursive_lock_destroy_multithreaded (gl_recursive_lock_t *lock)
473
586
if (lock->owner != (thread_t) 0)
475
if (mutex_destroy (&lock->mutex) != 0)
588
return mutex_destroy (&lock->mutex);
479
591
/* -------------------------- gl_once_t datatype -------------------------- */
482
glthread_once (gl_once_t *once_control, void (*initfunction) (void))
594
glthread_once_multithreaded (gl_once_t *once_control, void (*initfunction) (void))
484
596
if (!once_control->inited)
486
600
/* Use the mutex to guarantee that if another thread is already calling
487
the initfunction, this thread waits until it's finished. */
488
if (mutex_lock (&once_control->mutex) != 0)
601
the initfunction, this thread waits until it's finished. */
602
err = mutex_lock (&once_control->mutex);
490
605
if (!once_control->inited)
492
once_control->inited = 1;
495
if (mutex_unlock (&once_control->mutex) != 0)
607
once_control->inited = 1;
610
return mutex_unlock (&once_control->mutex);
520
636
/* -------------------------- gl_lock_t datatype -------------------------- */
523
glthread_lock_init (gl_lock_t *lock)
639
glthread_lock_init_func (gl_lock_t *lock)
525
641
InitializeCriticalSection (&lock->lock);
526
642
lock->guard.done = 1;
530
glthread_lock_lock (gl_lock_t *lock)
646
glthread_lock_lock_func (gl_lock_t *lock)
532
648
if (!lock->guard.done)
534
650
if (InterlockedIncrement (&lock->guard.started) == 0)
535
/* This thread is the first one to need this lock. Initialize it. */
536
glthread_lock_init (lock);
651
/* This thread is the first one to need this lock. Initialize it. */
652
glthread_lock_init (lock);
538
/* Yield the CPU while waiting for another thread to finish
539
initializing this lock. */
540
while (!lock->guard.done)
654
/* Yield the CPU while waiting for another thread to finish
655
initializing this lock. */
656
while (!lock->guard.done)
543
659
EnterCriticalSection (&lock->lock);
547
glthread_lock_unlock (gl_lock_t *lock)
664
glthread_lock_unlock_func (gl_lock_t *lock)
549
666
if (!lock->guard.done)
551
668
LeaveCriticalSection (&lock->lock);
555
glthread_lock_destroy (gl_lock_t *lock)
673
glthread_lock_destroy_func (gl_lock_t *lock)
557
675
if (!lock->guard.done)
559
677
DeleteCriticalSection (&lock->lock);
560
678
lock->guard.done = 0;
563
682
/* ------------------------- gl_rwlock_t datatype ------------------------- */
684
/* In this file, the waitqueues are implemented as circular arrays. */
685
#define gl_waitqueue_t gl_carray_waitqueue_t
565
687
static inline void
566
688
gl_waitqueue_init (gl_waitqueue_t *wq)
584
706
unsigned int new_alloc = 2 * wq->alloc + 1;
585
707
HANDLE *new_array =
586
(HANDLE *) realloc (wq->array, new_alloc * sizeof (HANDLE));
708
(HANDLE *) realloc (wq->array, new_alloc * sizeof (HANDLE));
587
709
if (new_array == NULL)
588
/* No more memory. */
589
return INVALID_HANDLE_VALUE;
710
/* No more memory. */
711
return INVALID_HANDLE_VALUE;
590
712
/* Now is a good opportunity to rotate the array so that its contents
591
starts at offset 0. */
713
starts at offset 0. */
592
714
if (wq->offset > 0)
594
unsigned int old_count = wq->count;
595
unsigned int old_alloc = wq->alloc;
596
unsigned int old_offset = wq->offset;
598
if (old_offset + old_count > old_alloc)
600
unsigned int limit = old_offset + old_count - old_alloc;
601
for (i = 0; i < limit; i++)
602
new_array[old_alloc + i] = new_array[i];
604
for (i = 0; i < old_count; i++)
605
new_array[i] = new_array[old_offset + i];
716
unsigned int old_count = wq->count;
717
unsigned int old_alloc = wq->alloc;
718
unsigned int old_offset = wq->offset;
720
if (old_offset + old_count > old_alloc)
722
unsigned int limit = old_offset + old_count - old_alloc;
723
for (i = 0; i < limit; i++)
724
new_array[old_alloc + i] = new_array[i];
726
for (i = 0; i < old_count; i++)
727
new_array[i] = new_array[old_offset + i];
608
730
wq->array = new_array;
609
731
wq->alloc = new_alloc;
733
/* Whether the created event is a manual-reset one or an auto-reset one,
734
does not matter, since we will wait on it only once. */
611
735
event = CreateEvent (NULL, TRUE, FALSE, NULL);
612
736
if (event == INVALID_HANDLE_VALUE)
613
737
/* No way to allocate an event. */
678
802
if (!(lock->runcount + 1 > 0))
680
804
/* This thread has to wait for a while. Enqueue it among the
682
806
HANDLE event = gl_waitqueue_add (&lock->waiting_readers);
683
807
if (event != INVALID_HANDLE_VALUE)
686
LeaveCriticalSection (&lock->lock);
687
/* Wait until another thread signals this event. */
688
result = WaitForSingleObject (event, INFINITE);
689
if (result == WAIT_FAILED || result == WAIT_TIMEOUT)
692
/* The thread which signalled the event already did the bookkeeping:
693
removed us from the waiting_readers, incremented lock->runcount. */
694
if (!(lock->runcount > 0))
810
LeaveCriticalSection (&lock->lock);
811
/* Wait until another thread signals this event. */
812
result = WaitForSingleObject (event, INFINITE);
813
if (result == WAIT_FAILED || result == WAIT_TIMEOUT)
816
/* The thread which signalled the event already did the bookkeeping:
817
removed us from the waiting_readers, incremented lock->runcount. */
818
if (!(lock->runcount > 0))
700
/* Allocation failure. Weird. */
703
LeaveCriticalSection (&lock->lock);
705
EnterCriticalSection (&lock->lock);
707
while (!(lock->runcount + 1 > 0));
824
/* Allocation failure. Weird. */
827
LeaveCriticalSection (&lock->lock);
829
EnterCriticalSection (&lock->lock);
831
while (!(lock->runcount + 1 > 0));
710
834
lock->runcount++;
711
835
LeaveCriticalSection (&lock->lock);
715
glthread_rwlock_wrlock (gl_rwlock_t *lock)
840
glthread_rwlock_wrlock_func (gl_rwlock_t *lock)
717
842
if (!lock->guard.done)
719
844
if (InterlockedIncrement (&lock->guard.started) == 0)
720
/* This thread is the first one to need this lock. Initialize it. */
721
glthread_rwlock_init (lock);
845
/* This thread is the first one to need this lock. Initialize it. */
846
glthread_rwlock_init (lock);
723
/* Yield the CPU while waiting for another thread to finish
724
initializing this lock. */
725
while (!lock->guard.done)
848
/* Yield the CPU while waiting for another thread to finish
849
initializing this lock. */
850
while (!lock->guard.done)
728
853
EnterCriticalSection (&lock->lock);
729
854
/* Test whether no readers or writers are currently running. */
730
855
if (!(lock->runcount == 0))
732
857
/* This thread has to wait for a while. Enqueue it among the
734
859
HANDLE event = gl_waitqueue_add (&lock->waiting_writers);
735
860
if (event != INVALID_HANDLE_VALUE)
738
LeaveCriticalSection (&lock->lock);
739
/* Wait until another thread signals this event. */
740
result = WaitForSingleObject (event, INFINITE);
741
if (result == WAIT_FAILED || result == WAIT_TIMEOUT)
744
/* The thread which signalled the event already did the bookkeeping:
745
removed us from the waiting_writers, set lock->runcount = -1. */
746
if (!(lock->runcount == -1))
863
LeaveCriticalSection (&lock->lock);
864
/* Wait until another thread signals this event. */
865
result = WaitForSingleObject (event, INFINITE);
866
if (result == WAIT_FAILED || result == WAIT_TIMEOUT)
869
/* The thread which signalled the event already did the bookkeeping:
870
removed us from the waiting_writers, set lock->runcount = -1. */
871
if (!(lock->runcount == -1))
752
/* Allocation failure. Weird. */
755
LeaveCriticalSection (&lock->lock);
757
EnterCriticalSection (&lock->lock);
759
while (!(lock->runcount == 0));
877
/* Allocation failure. Weird. */
880
LeaveCriticalSection (&lock->lock);
882
EnterCriticalSection (&lock->lock);
884
while (!(lock->runcount == 0));
762
887
lock->runcount--; /* runcount becomes -1 */
763
888
LeaveCriticalSection (&lock->lock);
767
glthread_rwlock_unlock (gl_rwlock_t *lock)
893
glthread_rwlock_unlock_func (gl_rwlock_t *lock)
769
895
if (!lock->guard.done)
771
897
EnterCriticalSection (&lock->lock);
772
898
if (lock->runcount < 0)
774
900
/* Drop a writer lock. */
775
901
if (!(lock->runcount == -1))
777
903
lock->runcount = 0;
781
907
/* Drop a reader lock. */
782
908
if (!(lock->runcount > 0))
910
LeaveCriticalSection (&lock->lock);
784
913
lock->runcount--;
786
915
if (lock->runcount == 0)
788
917
/* POSIX recommends that "write locks shall take precedence over read
789
locks", to avoid "writer starvation". */
918
locks", to avoid "writer starvation". */
790
919
if (lock->waiting_writers.count > 0)
792
/* Wake up one of the waiting writers. */
794
gl_waitqueue_notify_first (&lock->waiting_writers);
921
/* Wake up one of the waiting writers. */
923
gl_waitqueue_notify_first (&lock->waiting_writers);
798
/* Wake up all waiting readers. */
799
lock->runcount += lock->waiting_readers.count;
800
gl_waitqueue_notify_all (&lock->waiting_readers);
927
/* Wake up all waiting readers. */
928
lock->runcount += lock->waiting_readers.count;
929
gl_waitqueue_notify_all (&lock->waiting_readers);
803
932
LeaveCriticalSection (&lock->lock);
807
glthread_rwlock_destroy (gl_rwlock_t *lock)
937
glthread_rwlock_destroy_func (gl_rwlock_t *lock)
809
939
if (!lock->guard.done)
811
941
if (lock->runcount != 0)
813
943
DeleteCriticalSection (&lock->lock);
814
944
if (lock->waiting_readers.array != NULL)
815
945
free (lock->waiting_readers.array);
816
946
if (lock->waiting_writers.array != NULL)
817
947
free (lock->waiting_writers.array);
818
948
lock->guard.done = 0;
821
952
/* --------------------- gl_recursive_lock_t datatype --------------------- */
824
glthread_recursive_lock_init (gl_recursive_lock_t *lock)
955
glthread_recursive_lock_init_func (gl_recursive_lock_t *lock)
829
960
lock->guard.done = 1;
833
glthread_recursive_lock_lock (gl_recursive_lock_t *lock)
964
glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock)
835
966
if (!lock->guard.done)
837
968
if (InterlockedIncrement (&lock->guard.started) == 0)
838
/* This thread is the first one to need this lock. Initialize it. */
839
glthread_recursive_lock_init (lock);
969
/* This thread is the first one to need this lock. Initialize it. */
970
glthread_recursive_lock_init (lock);
841
/* Yield the CPU while waiting for another thread to finish
842
initializing this lock. */
843
while (!lock->guard.done)
972
/* Yield the CPU while waiting for another thread to finish
973
initializing this lock. */
974
while (!lock->guard.done)
847
978
DWORD self = GetCurrentThreadId ();
848
979
if (lock->owner != self)
850
EnterCriticalSection (&lock->lock);
981
EnterCriticalSection (&lock->lock);
853
984
if (++(lock->depth) == 0) /* wraparound? */
859
glthread_recursive_lock_unlock (gl_recursive_lock_t *lock)
994
glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock)
861
996
if (lock->owner != GetCurrentThreadId ())
863
998
if (lock->depth == 0)
865
1000
if (--(lock->depth) == 0)
867
1002
lock->owner = 0;
868
1003
LeaveCriticalSection (&lock->lock);
873
glthread_recursive_lock_destroy (gl_recursive_lock_t *lock)
1009
glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock)
875
1011
if (lock->owner != 0)
877
1013
DeleteCriticalSection (&lock->lock);
878
1014
lock->guard.done = 0;
881
1018
/* -------------------------- gl_once_t datatype -------------------------- */
884
glthread_once (gl_once_t *once_control, void (*initfunction) (void))
1021
glthread_once_func (gl_once_t *once_control, void (*initfunction) (void))
886
1023
if (once_control->inited <= 0)
888
1025
if (InterlockedIncrement (&once_control->started) == 0)
890
/* This thread is the first one to come to this once_control. */
891
InitializeCriticalSection (&once_control->lock);
892
EnterCriticalSection (&once_control->lock);
893
once_control->inited = 0;
895
once_control->inited = 1;
896
LeaveCriticalSection (&once_control->lock);
1027
/* This thread is the first one to come to this once_control. */
1028
InitializeCriticalSection (&once_control->lock);
1029
EnterCriticalSection (&once_control->lock);
1030
once_control->inited = 0;
1032
once_control->inited = 1;
1033
LeaveCriticalSection (&once_control->lock);
900
/* Undo last operation. */
901
InterlockedDecrement (&once_control->started);
902
/* Some other thread has already started the initialization.
903
Yield the CPU while waiting for the other thread to finish
904
initializing and taking the lock. */
905
while (once_control->inited < 0)
907
if (once_control->inited <= 0)
909
/* Take the lock. This blocks until the other thread has
910
finished calling the initfunction. */
911
EnterCriticalSection (&once_control->lock);
912
LeaveCriticalSection (&once_control->lock);
913
if (!(once_control->inited > 0))
1037
/* Undo last operation. */
1038
InterlockedDecrement (&once_control->started);
1039
/* Some other thread has already started the initialization.
1040
Yield the CPU while waiting for the other thread to finish
1041
initializing and taking the lock. */
1042
while (once_control->inited < 0)
1044
if (once_control->inited <= 0)
1046
/* Take the lock. This blocks until the other thread has
1047
finished calling the initfunction. */
1048
EnterCriticalSection (&once_control->lock);
1049
LeaveCriticalSection (&once_control->lock);
1050
if (!(once_control->inited > 0))