v0.2.2 9100209

gthread.go RawHistoryFolder

1// Package glib was automatically generated by github.com/bnema/puregotk DO NOT EDIT
2package glib
3
4import (
5	"structs"
6	"unsafe"
7
8	"github.com/ebitengine/purego"
9
10	"github.com/bnema/puregotk/pkg/core"
11	"github.com/bnema/puregotk/v4/gobject/types"
12)
13
14// Specifies the type of the @func functions passed to g_thread_new()
15// or g_thread_try_new().
16type ThreadFunc func(uintptr) uintptr
17
18// The #GCond struct is an opaque data structure that represents a
19// condition. Threads can block on a #GCond if they find a certain
20// condition to be false. If other threads change the state of this
21// condition they signal the #GCond, and that causes the waiting
22// threads to be woken up.
23//
24// Consider the following example of a shared variable.  One or more
25// threads can wait for data to be published to the variable and when
26// another thread publishes the data, it can signal one of the waiting
27// threads to wake up to collect the data.
28//
29// Here is an example for using GCond to block a thread until a condition
30// is satisfied:
31// |[<!-- language="C" -->
32//
33//	gpointer current_data = NULL;
34//	GMutex data_mutex;
35//	GCond data_cond;
36//
37//	void
38//	push_data (gpointer data)
39//	{
40//	  g_mutex_lock (&data_mutex);
41//	  current_data = data;
42//	  g_cond_signal (&data_cond);
43//	  g_mutex_unlock (&data_mutex);
44//	}
45//
46//	gpointer
47//	pop_data (void)
48//	{
49//	  gpointer data;
50//
51//	  g_mutex_lock (&data_mutex);
52//	  while (!current_data)
53//	    g_cond_wait (&data_cond, &data_mutex);
54//	  data = current_data;
55//	  current_data = NULL;
56//	  g_mutex_unlock (&data_mutex);
57//
58//	  return data;
59//	}
60//
61// ]|
62// Whenever a thread calls pop_data() now, it will wait until
63// current_data is non-%NULL, i.e. until some other thread
64// has called push_data().
65//
66// The example shows that use of a condition variable must always be
67// paired with a mutex.  Without the use of a mutex, there would be a
68// race between the check of @current_data by the while loop in
69// pop_data() and waiting. Specifically, another thread could set
70// @current_data after the check, and signal the cond (with nobody
71// waiting on it) before the first thread goes to sleep. #GCond is
72// specifically useful for its ability to release the mutex and go
73// to sleep atomically.
74//
75// It is also important to use the g_cond_wait() and g_cond_wait_until()
76// functions only inside a loop which checks for the condition to be
77// true.  See g_cond_wait() for an explanation of why the condition may
78// not be true even after it returns.
79//
80// If a #GCond is allocated in static storage then it can be used
81// without initialisation.  Otherwise, you should call g_cond_init()
82// on it and g_cond_clear() when done.
83//
84// A #GCond should only be accessed via the g_cond_ functions.
85type Cond struct {
86	_ structs.HostLayout
87
88	P uintptr
89
90	I [2]uint
91}
92
93func (x *Cond) GoPointer() uintptr {
94	return uintptr(unsafe.Pointer(x))
95}
96
97var xCondBroadcast func(uintptr)
98
99// If threads are waiting for @cond, all of them are unblocked.
100// If no threads are waiting for @cond, this function has no effect.
101// It is good practice to lock the same mutex as the waiting threads
102// while calling this function, though not required.
103func (x *Cond) Broadcast() {
104
105	xCondBroadcast(x.GoPointer())
106
107}
108
109var xCondClear func(uintptr)
110
111// Frees the resources allocated to a #GCond with g_cond_init().
112//
113// This function should not be used with a #GCond that has been
114// statically allocated.
115//
116// Calling g_cond_clear() for a #GCond on which threads are
117// blocking leads to undefined behaviour.
118func (x *Cond) Clear() {
119
120	xCondClear(x.GoPointer())
121
122}
123
124var xCondFree func(uintptr)
125
126// Destroys a #GCond that has been created with g_cond_new().
127//
128// Calling g_cond_free() for a #GCond on which threads are
129// blocking leads to undefined behaviour.
130func (x *Cond) Free() {
131
132	xCondFree(x.GoPointer())
133
134}
135
136var xCondInit func(uintptr)
137
138// Initialises a #GCond so that it can be used.
139//
140// This function is useful to initialise a #GCond that has been
141// allocated as part of a larger structure.  It is not necessary to
142// initialise a #GCond that has been statically allocated.
143//
144// To undo the effect of g_cond_init() when a #GCond is no longer
145// needed, use g_cond_clear().
146//
147// Calling g_cond_init() on an already-initialised #GCond leads
148// to undefined behaviour.
149func (x *Cond) Init() {
150
151	xCondInit(x.GoPointer())
152
153}
154
155var xCondSignal func(uintptr)
156
157// If threads are waiting for @cond, at least one of them is unblocked.
158// If no threads are waiting for @cond, this function has no effect.
159// It is good practice to hold the same lock as the waiting thread
160// while calling this function, though not required.
161func (x *Cond) Signal() {
162
163	xCondSignal(x.GoPointer())
164
165}
166
167var xCondTimedWait func(uintptr, *Mutex, *TimeVal) bool
168
169// Waits until this thread is woken up on @cond, but not longer than
170// until the time specified by @abs_time. The @mutex is unlocked before
171// falling asleep and locked again before resuming.
172//
173// If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait().
174//
175// This function can be used even if g_thread_init() has not yet been
176// called, and, in that case, will immediately return %TRUE.
177//
178// To easily calculate @abs_time a combination of g_get_real_time()
179// and g_time_val_add() can be used.
180func (x *Cond) TimedWait(MutexVar *Mutex, AbsTimeVar *TimeVal) bool {
181
182	cret := xCondTimedWait(x.GoPointer(), MutexVar, AbsTimeVar)
183	return cret
184}
185
186var xCondWait func(uintptr, *Mutex)
187
188// Atomically releases @mutex and waits until @cond is signalled.
189// When this function returns, @mutex is locked again and owned by the
190// calling thread.
191//
192// When using condition variables, it is possible that a spurious wakeup
193// may occur (ie: g_cond_wait() returns even though g_cond_signal() was
194// not called).  It's also possible that a stolen wakeup may occur.
195// This is when g_cond_signal() is called, but another thread acquires
196// @mutex before this thread and modifies the state of the program in
197// such a way that when g_cond_wait() is able to return, the expected
198// condition is no longer met.
199//
200// For this reason, g_cond_wait() must always be used in a loop.  See
201// the documentation for #GCond for a complete example.
202func (x *Cond) Wait(MutexVar *Mutex) {
203
204	xCondWait(x.GoPointer(), MutexVar)
205
206}
207
208var xCondWaitUntil func(uintptr, *Mutex, int64) bool
209
210// Waits until either @cond is signalled or @end_time has passed.
211//
212// As with g_cond_wait() it is possible that a spurious or stolen wakeup
213// could occur.  For that reason, waiting on a condition variable should
214// always be in a loop, based on an explicitly-checked predicate.
215//
216// %TRUE is returned if the condition variable was signalled (or in the
217// case of a spurious wakeup).  %FALSE is returned if @end_time has
218// passed.
219//
220// The following code shows how to correctly perform a timed wait on a
221// condition variable (extending the example presented in the
222// documentation for #GCond):
223//
224// |[<!-- language="C" -->
225// gpointer
226// pop_data_timed (void)
227//
228//	{
229//	  gint64 end_time;
230//	  gpointer data;
231//
232//	  g_mutex_lock (&data_mutex);
233//
234//	  end_time = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND;
235//	  while (!current_data)
236//	    if (!g_cond_wait_until (&data_cond, &data_mutex, end_time))
237//	      {
238//	        // timeout has passed.
239//	        g_mutex_unlock (&data_mutex);
240//	        return NULL;
241//	      }
242//
243//	  // there is data for us
244//	  data = current_data;
245//	  current_data = NULL;
246//
247//	  g_mutex_unlock (&data_mutex);
248//
249//	  return data;
250//	}
251//
252// ]|
253//
254// Notice that the end time is calculated once, before entering the
255// loop and reused.  This is the motivation behind the use of absolute
256// time on this API -- if a relative time of 5 seconds were passed
257// directly to the call and a spurious wakeup occurred, the program would
258// have to start over waiting again (which would lead to a total wait
259// time of more than 5 seconds).
260func (x *Cond) WaitUntil(MutexVar *Mutex, EndTimeVar int64) bool {
261
262	cret := xCondWaitUntil(x.GoPointer(), MutexVar, EndTimeVar)
263	return cret
264}
265
266// A #GOnce struct controls a one-time initialization function. Any
267// one-time initialization function must have its own unique #GOnce
268// struct.
269type Once struct {
270	_ structs.HostLayout
271
272	Status OnceStatus
273
274	Retval uintptr
275}
276
277func (x *Once) GoPointer() uintptr {
278	return uintptr(unsafe.Pointer(x))
279}
280
281var xOnceImpl func(uintptr, uintptr, uintptr) uintptr
282
283func (x *Once) Impl(FuncVar *ThreadFunc, ArgVar uintptr) uintptr {
284
285	var FuncVarRef uintptr
286	if FuncVar != nil {
287		FuncVarPtr := uintptr(unsafe.Pointer(FuncVar))
288		if cbRefPtr, ok := GetCallback(FuncVarPtr); ok {
289			FuncVarRef = cbRefPtr
290		} else {
291			fcb := func(arg0 uintptr) uintptr {
292				cbFn := *FuncVar
293				return cbFn(arg0)
294			}
295			FuncVarRef = purego.NewCallback(fcb)
296			SaveCallbackWithClosure(FuncVarPtr, FuncVarRef, FuncVar)
297		}
298	}
299
300	cret := xOnceImpl(x.GoPointer(), FuncVarRef, ArgVar)
301	return cret
302}
303
304// The #GPrivate struct is an opaque data structure to represent a
305// thread-local data key. It is approximately equivalent to the
306// pthread_setspecific()/pthread_getspecific() APIs on POSIX and to
307// TlsSetValue()/TlsGetValue() on Windows.
308//
309// If you don't already know why you might want this functionality,
310// then you probably don't need it.
311//
312// #GPrivate is a very limited resource (as far as 128 per program,
313// shared between all libraries). It is also not possible to destroy a
314// #GPrivate after it has been used. As such, it is only ever acceptable
315// to use #GPrivate in static scope, and even then sparingly so.
316//
317// See G_PRIVATE_INIT() for a couple of examples.
318//
319// The #GPrivate structure should be considered opaque.  It should only
320// be accessed via the g_private_ functions.
321type Private struct {
322	_ structs.HostLayout
323
324	P uintptr
325
326	Notify DestroyNotify
327
328	Future [2]uintptr
329}
330
331func (x *Private) GoPointer() uintptr {
332	return uintptr(unsafe.Pointer(x))
333}
334
335var xPrivateGet func(uintptr) uintptr
336
337// Returns the current value of the thread local variable @key.
338//
339// If the value has not yet been set in this thread, %NULL is returned.
340// Values are never copied between threads (when a new thread is
341// created, for example).
342func (x *Private) Get() uintptr {
343
344	cret := xPrivateGet(x.GoPointer())
345	return cret
346}
347
348var xPrivateReplace func(uintptr, uintptr)
349
350// Sets the thread local variable @key to have the value @value in the
351// current thread.
352//
353// This function differs from g_private_set() in the following way: if
354// the previous value was non-%NULL then the #GDestroyNotify handler for
355// @key is run on it.
356func (x *Private) Replace(ValueVar uintptr) {
357
358	xPrivateReplace(x.GoPointer(), ValueVar)
359
360}
361
362var xPrivateSet func(uintptr, uintptr)
363
364// Sets the thread local variable @key to have the value @value in the
365// current thread.
366//
367// This function differs from g_private_replace() in the following way:
368// the #GDestroyNotify for @key is not called on the old value.
369func (x *Private) Set(ValueVar uintptr) {
370
371	xPrivateSet(x.GoPointer(), ValueVar)
372
373}
374
375// The GRWLock struct is an opaque data structure to represent a
376// reader-writer lock. It is similar to a #GMutex in that it allows
377// multiple threads to coordinate access to a shared resource.
378//
379// The difference to a mutex is that a reader-writer lock discriminates
380// between read-only ('reader') and full ('writer') access. While only
381// one thread at a time is allowed write access (by holding the 'writer'
382// lock via g_rw_lock_writer_lock()), multiple threads can gain
383// simultaneous read-only access (by holding the 'reader' lock via
384// g_rw_lock_reader_lock()).
385//
386// It is unspecified whether readers or writers have priority in acquiring the
387// lock when a reader already holds the lock and a writer is queued to acquire
388// it.
389//
390// Here is an example for an array with access functions:
391// |[<!-- language="C" -->
392//
393//	 GRWLock lock;
394//	 GPtrArray *array;
395//
396//	 gpointer
397//	 my_array_get (guint index)
398//	 {
399//	   gpointer retval = NULL;
400//
401//	   if (!array)
402//	     return NULL;
403//
404//	   g_rw_lock_reader_lock (&lock);
405//	   if (index < array->len)
406//	     retval = g_ptr_array_index (array, index);
407//	   g_rw_lock_reader_unlock (&lock);
408//
409//	   return retval;
410//	 }
411//
412//	 void
413//	 my_array_set (guint index, gpointer data)
414//	 {
415//	   g_rw_lock_writer_lock (&lock);
416//
417//	   if (!array)
418//	     array = g_ptr_array_new ();
419//
420//	   if (index >= array->len)
421//	     g_ptr_array_set_size (array, index+1);
422//	   g_ptr_array_index (array, index) = data;
423//
424//	   g_rw_lock_writer_unlock (&lock);
425//	 }
426//	]|
427//
428// This example shows an array which can be accessed by many readers
429// (the my_array_get() function) simultaneously, whereas the writers
430// (the my_array_set() function) will only be allowed one at a time
431// and only if no readers currently access the array. This is because
432// of the potentially dangerous resizing of the array. Using these
433// functions is fully multi-thread safe now.
434//
435// If a #GRWLock is allocated in static storage then it can be used
436// without initialisation.  Otherwise, you should call
437// g_rw_lock_init() on it and g_rw_lock_clear() when done.
438//
439// A GRWLock should only be accessed with the g_rw_lock_ functions.
440type RWLock struct {
441	_ structs.HostLayout
442
443	P uintptr
444
445	I [2]uint
446}
447
448func (x *RWLock) GoPointer() uintptr {
449	return uintptr(unsafe.Pointer(x))
450}
451
452var xRWLockClear func(uintptr)
453
454// Frees the resources allocated to a lock with g_rw_lock_init().
455//
456// This function should not be used with a #GRWLock that has been
457// statically allocated.
458//
459// Calling g_rw_lock_clear() when any thread holds the lock
460// leads to undefined behaviour.
461func (x *RWLock) Clear() {
462
463	xRWLockClear(x.GoPointer())
464
465}
466
467var xRWLockInit func(uintptr)
468
469// Initializes a #GRWLock so that it can be used.
470//
471// This function is useful to initialize a lock that has been
472// allocated on the stack, or as part of a larger structure.  It is not
473// necessary to initialise a reader-writer lock that has been statically
474// allocated.
475//
476// |[<!-- language="C" -->
477//
478//	typedef struct {
479//	  GRWLock l;
480//	  ...
481//	} Blob;
482//
483// Blob *b;
484//
485// b = g_new (Blob, 1);
486// g_rw_lock_init (&b->l);
487// ]|
488//
489// To undo the effect of g_rw_lock_init() when a lock is no longer
490// needed, use g_rw_lock_clear().
491//
492// Calling g_rw_lock_init() on an already initialized #GRWLock leads
493// to undefined behaviour.
494func (x *RWLock) Init() {
495
496	xRWLockInit(x.GoPointer())
497
498}
499
500var xRWLockReaderLock func(uintptr)
501
502// Obtain a read lock on @rw_lock. If another thread currently holds
503// the write lock on @rw_lock, the current thread will block until the
504// write lock was (held and) released. If another thread does not hold
505// the write lock, but is waiting for it, it is implementation defined
506// whether the reader or writer will block. Read locks can be taken
507// recursively.
508//
509// Calling g_rw_lock_reader_lock() while the current thread already
510// owns a write lock leads to undefined behaviour. Read locks however
511// can be taken recursively, in which case you need to make sure to
512// call g_rw_lock_reader_unlock() the same amount of times.
513//
514// It is implementation-defined how many read locks are allowed to be
515// held on the same lock simultaneously. If the limit is hit,
516// or if a deadlock is detected, a critical warning will be emitted.
517func (x *RWLock) ReaderLock() {
518
519	xRWLockReaderLock(x.GoPointer())
520
521}
522
523var xRWLockReaderTrylock func(uintptr) bool
524
525// Tries to obtain a read lock on @rw_lock and returns %TRUE if
526// the read lock was successfully obtained. Otherwise it
527// returns %FALSE.
528func (x *RWLock) ReaderTrylock() bool {
529
530	cret := xRWLockReaderTrylock(x.GoPointer())
531	return cret
532}
533
534var xRWLockReaderUnlock func(uintptr)
535
536// Release a read lock on @rw_lock.
537//
538// Calling g_rw_lock_reader_unlock() on a lock that is not held
539// by the current thread leads to undefined behaviour.
540func (x *RWLock) ReaderUnlock() {
541
542	xRWLockReaderUnlock(x.GoPointer())
543
544}
545
546var xRWLockWriterLock func(uintptr)
547
548// Obtain a write lock on @rw_lock. If another thread currently holds
549// a read or write lock on @rw_lock, the current thread will block
550// until all other threads have dropped their locks on @rw_lock.
551//
552// Calling g_rw_lock_writer_lock() while the current thread already
553// owns a read or write lock on @rw_lock leads to undefined behaviour.
554func (x *RWLock) WriterLock() {
555
556	xRWLockWriterLock(x.GoPointer())
557
558}
559
560var xRWLockWriterTrylock func(uintptr) bool
561
562// Tries to obtain a write lock on @rw_lock. If another thread
563// currently holds a read or write lock on @rw_lock, it immediately
564// returns %FALSE.
565// Otherwise it locks @rw_lock and returns %TRUE.
566func (x *RWLock) WriterTrylock() bool {
567
568	cret := xRWLockWriterTrylock(x.GoPointer())
569	return cret
570}
571
572var xRWLockWriterUnlock func(uintptr)
573
574// Release a write lock on @rw_lock.
575//
576// Calling g_rw_lock_writer_unlock() on a lock that is not held
577// by the current thread leads to undefined behaviour.
578func (x *RWLock) WriterUnlock() {
579
580	xRWLockWriterUnlock(x.GoPointer())
581
582}
583
584// The GRecMutex struct is an opaque data structure to represent a
585// recursive mutex. It is similar to a #GMutex with the difference
586// that it is possible to lock a GRecMutex multiple times in the same
587// thread without deadlock. When doing so, care has to be taken to
588// unlock the recursive mutex as often as it has been locked.
589//
590// If a #GRecMutex is allocated in static storage then it can be used
591// without initialisation.  Otherwise, you should call
592// g_rec_mutex_init() on it and g_rec_mutex_clear() when done.
593//
594// A GRecMutex should only be accessed with the
595// g_rec_mutex_ functions.
596type RecMutex struct {
597	_ structs.HostLayout
598
599	P uintptr
600
601	I [2]uint
602}
603
604func (x *RecMutex) GoPointer() uintptr {
605	return uintptr(unsafe.Pointer(x))
606}
607
608var xRecMutexClear func(uintptr)
609
610// Frees the resources allocated to a recursive mutex with
611// g_rec_mutex_init().
612//
613// This function should not be used with a #GRecMutex that has been
614// statically allocated.
615//
616// Calling g_rec_mutex_clear() on a locked recursive mutex leads
617// to undefined behaviour.
618func (x *RecMutex) Clear() {
619
620	xRecMutexClear(x.GoPointer())
621
622}
623
624var xRecMutexInit func(uintptr)
625
626// Initializes a #GRecMutex so that it can be used.
627//
628// This function is useful to initialize a recursive mutex
629// that has been allocated on the stack, or as part of a larger
630// structure.
631//
632// It is not necessary to initialise a recursive mutex that has been
633// statically allocated.
634//
635// |[<!-- language="C" -->
636//
637//	typedef struct {
638//	  GRecMutex m;
639//	  ...
640//	} Blob;
641//
642// Blob *b;
643//
644// b = g_new (Blob, 1);
645// g_rec_mutex_init (&b->m);
646// ]|
647//
648// Calling g_rec_mutex_init() on an already initialized #GRecMutex
649// leads to undefined behaviour.
650//
651// To undo the effect of g_rec_mutex_init() when a recursive mutex
652// is no longer needed, use g_rec_mutex_clear().
653func (x *RecMutex) Init() {
654
655	xRecMutexInit(x.GoPointer())
656
657}
658
659var xRecMutexLock func(uintptr)
660
661// Locks @rec_mutex. If @rec_mutex is already locked by another
662// thread, the current thread will block until @rec_mutex is
663// unlocked by the other thread. If @rec_mutex is already locked
664// by the current thread, the 'lock count' of @rec_mutex is increased.
665// The mutex will only become available again when it is unlocked
666// as many times as it has been locked.
667func (x *RecMutex) Lock() {
668
669	xRecMutexLock(x.GoPointer())
670
671}
672
673var xRecMutexTrylock func(uintptr) bool
674
675// Tries to lock @rec_mutex. If @rec_mutex is already locked
676// by another thread, it immediately returns %FALSE. Otherwise
677// it locks @rec_mutex and returns %TRUE.
678func (x *RecMutex) Trylock() bool {
679
680	cret := xRecMutexTrylock(x.GoPointer())
681	return cret
682}
683
684var xRecMutexUnlock func(uintptr)
685
686// Unlocks @rec_mutex. If another thread is blocked in a
687// g_rec_mutex_lock() call for @rec_mutex, it will become unblocked
688// and can lock @rec_mutex itself.
689//
690// Calling g_rec_mutex_unlock() on a recursive mutex that is not
691// locked by the current thread leads to undefined behaviour.
692func (x *RecMutex) Unlock() {
693
694	xRecMutexUnlock(x.GoPointer())
695
696}
697
698// A #GStaticMutex works like a #GMutex.
699//
700// Prior to GLib 2.32, GStaticMutex had the significant advantage
701// that it doesn't need to be created at run-time, but can be defined
702// at compile-time. Since 2.32, #GMutex can be statically allocated
703// as well, and GStaticMutex has been deprecated.
704//
705// Here is a version of our give_me_next_number() example using
706// a GStaticMutex:
707// |[
708//
709//	int
710//	give_me_next_number (void)
711//	{
712//	  static int current_number = 0;
713//	  int ret_val;
714//	  static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
715//
716//	  g_static_mutex_lock (&mutex);
717//	  ret_val = current_number = calc_next_number (current_number);
718//	  g_static_mutex_unlock (&mutex);
719//
720//	  return ret_val;
721//	}
722//
723// ]|
724//
725// Sometimes you would like to dynamically create a mutex. If you don't
726// want to require prior calling to g_thread_init(), because your code
727// should also be usable in non-threaded programs, you are not able to
728// use g_mutex_new() and thus #GMutex, as that requires a prior call to
729// g_thread_init(). In these cases you can also use a #GStaticMutex.
730// It must be initialized with g_static_mutex_init() before using it
731// and freed with with g_static_mutex_free() when not needed anymore to
732// free up any allocated resources.
733//
734// Even though #GStaticMutex is not opaque, it should only be used with
735// the following functions, as it is defined differently on different
736// platforms.
737//
738// All of the g_static_mutex_* functions apart from
739// g_static_mutex_get_mutex() can also be used even if g_thread_init()
740// has not yet been called. Then they do nothing, apart from
741// g_static_mutex_trylock() which does nothing but returning %TRUE.
742//
743// All of the g_static_mutex_* functions are actually macros. Apart from
744// taking their addresses, you can however use them as if they were
745// functions.
746type StaticMutex struct {
747	_ structs.HostLayout
748
749	Mutex *Mutex
750}
751
752func (x *StaticMutex) GoPointer() uintptr {
753	return uintptr(unsafe.Pointer(x))
754}
755
756var xStaticMutexFree func(uintptr)
757
758// Releases all resources allocated to @mutex.
759//
760// You don't have to call this functions for a #GStaticMutex with an
761// unbounded lifetime, i.e. objects declared 'static', but if you have
762// a #GStaticMutex as a member of a structure and the structure is
763// freed, you should also free the #GStaticMutex.
764//
765// Calling g_static_mutex_free() on a locked mutex may result in
766// undefined behaviour.
767func (x *StaticMutex) Free() {
768
769	xStaticMutexFree(x.GoPointer())
770
771}
772
773var xStaticMutexGetMutexImpl func(uintptr) *Mutex
774
775func (x *StaticMutex) GetMutexImpl() *Mutex {
776
777	cret := xStaticMutexGetMutexImpl(x.GoPointer())
778	return cret
779}
780
781var xStaticMutexInit func(uintptr)
782
783// Initializes @mutex.
784// Alternatively you can initialize it with %G_STATIC_MUTEX_INIT.
785func (x *StaticMutex) Init() {
786
787	xStaticMutexInit(x.GoPointer())
788
789}
790
791// A #GStaticPrivate works almost like a #GPrivate, but it has one
792// significant advantage. It doesn't need to be created at run-time
793// like a #GPrivate, but can be defined at compile-time. This is
794// similar to the difference between #GMutex and #GStaticMutex.
795//
796// Now look at our give_me_next_number() example with #GStaticPrivate:
797// |[
798//
799//	int
800//	give_me_next_number ()
801//	{
802//	  static GStaticPrivate current_number_key = G_STATIC_PRIVATE_INIT;
803//	  int *current_number = g_static_private_get (&current_number_key);
804//
805//	  if (!current_number)
806//	    {
807//	      current_number = g_new (int, 1);
808//	      *current_number = 0;
809//	      g_static_private_set (&current_number_key, current_number, g_free);
810//	    }
811//
812//	  *current_number = calc_next_number (*current_number);
813//
814//	  return *current_number;
815//	}
816//
817// ]|
818type StaticPrivate struct {
819	_ structs.HostLayout
820
821	Index uint
822}
823
824func (x *StaticPrivate) GoPointer() uintptr {
825	return uintptr(unsafe.Pointer(x))
826}
827
828var xStaticPrivateFree func(uintptr)
829
830// Releases all resources allocated to @private_key.
831//
832// You don't have to call this functions for a #GStaticPrivate with an
833// unbounded lifetime, i.e. objects declared 'static', but if you have
834// a #GStaticPrivate as a member of a structure and the structure is
835// freed, you should also free the #GStaticPrivate.
836func (x *StaticPrivate) Free() {
837
838	xStaticPrivateFree(x.GoPointer())
839
840}
841
842var xStaticPrivateGet func(uintptr) uintptr
843
844// Works like g_private_get() only for a #GStaticPrivate.
845//
846// This function works even if g_thread_init() has not yet been called.
847func (x *StaticPrivate) Get() uintptr {
848
849	cret := xStaticPrivateGet(x.GoPointer())
850	return cret
851}
852
853var xStaticPrivateInit func(uintptr)
854
855// Initializes @private_key. Alternatively you can initialize it with
856// %G_STATIC_PRIVATE_INIT.
857func (x *StaticPrivate) Init() {
858
859	xStaticPrivateInit(x.GoPointer())
860
861}
862
863var xStaticPrivateSet func(uintptr, uintptr, uintptr)
864
865// Sets the pointer keyed to @private_key for the current thread and
866// the function @notify to be called with that pointer (%NULL or
867// non-%NULL), whenever the pointer is set again or whenever the
868// current thread ends.
869//
870// This function works even if g_thread_init() has not yet been called.
871// If g_thread_init() is called later, the @data keyed to @private_key
872// will be inherited only by the main thread, i.e. the one that called
873// g_thread_init().
874//
875// @notify is used quite differently from @destructor in g_private_new().
876func (x *StaticPrivate) Set(DataVar uintptr, NotifyVar *DestroyNotify) {
877
878	var NotifyVarRef uintptr
879	if NotifyVar != nil {
880		NotifyVarPtr := uintptr(unsafe.Pointer(NotifyVar))
881		if cbRefPtr, ok := GetCallback(NotifyVarPtr); ok {
882			NotifyVarRef = cbRefPtr
883		} else {
884			fcb := func(arg0 uintptr) {
885				cbFn := *NotifyVar
886				cbFn(arg0)
887			}
888			NotifyVarRef = purego.NewCallback(fcb)
889			SaveCallbackWithClosure(NotifyVarPtr, NotifyVarRef, NotifyVar)
890		}
891	}
892
893	xStaticPrivateSet(x.GoPointer(), DataVar, NotifyVarRef)
894
895}
896
897// The #GStaticRWLock struct represents a read-write lock. A read-write
898// lock can be used for protecting data that some portions of code only
899// read from, while others also write. In such situations it is
900// desirable that several readers can read at once, whereas of course
901// only one writer may write at a time.
902//
903// Take a look at the following example:
904// |[
905//
906//	GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT;
907//	GPtrArray *array;
908//
909//	gpointer
910//	my_array_get (guint index)
911//	{
912//	  gpointer retval = NULL;
913//
914//	  if (!array)
915//	    return NULL;
916//
917//	  g_static_rw_lock_reader_lock (&rwlock);
918//	  if (index < array->len)
919//	    retval = g_ptr_array_index (array, index);
920//	  g_static_rw_lock_reader_unlock (&rwlock);
921//
922//	  return retval;
923//	}
924//
925//	void
926//	my_array_set (guint index, gpointer data)
927//	{
928//	  g_static_rw_lock_writer_lock (&rwlock);
929//
930//	  if (!array)
931//	    array = g_ptr_array_new ();
932//
933//	  if (index >= array->len)
934//	    g_ptr_array_set_size (array, index + 1);
935//	  g_ptr_array_index (array, index) = data;
936//
937//	  g_static_rw_lock_writer_unlock (&rwlock);
938//	}
939//
940// ]|
941//
942// This example shows an array which can be accessed by many readers
943// (the my_array_get() function) simultaneously, whereas the writers
944// (the my_array_set() function) will only be allowed once at a time
945// and only if no readers currently access the array. This is because
946// of the potentially dangerous resizing of the array. Using these
947// functions is fully multi-thread safe now.
948//
949// Most of the time, writers should have precedence over readers. That
950// means, for this implementation, that as soon as a writer wants to
951// lock the data, no other reader is allowed to lock the data, whereas,
952// of course, the readers that already have locked the data are allowed
953// to finish their operation. As soon as the last reader unlocks the
954// data, the writer will lock it.
955//
956// Even though #GStaticRWLock is not opaque, it should only be used
957// with the following functions.
958//
959// All of the g_static_rw_lock_* functions can be used even if
960// g_thread_init() has not been called. Then they do nothing, apart
961// from g_static_rw_lock_*_trylock, which does nothing but returning %TRUE.
962//
963// A read-write lock has a higher overhead than a mutex. For example, both
964// g_static_rw_lock_reader_lock() and g_static_rw_lock_reader_unlock() have
965// to lock and unlock a #GStaticMutex, so it takes at least twice the time
966// to lock and unlock a #GStaticRWLock that it does to lock and unlock a
967// #GStaticMutex. So only data structures that are accessed by multiple
968// readers, and which keep the lock for a considerable time justify a
969// #GStaticRWLock. The above example most probably would fare better with a
970// #GStaticMutex.
971type StaticRWLock struct {
972	_ structs.HostLayout
973
974	Mutex uintptr
975
976	ReadCond *Cond
977
978	WriteCond *Cond
979
980	ReadCounter uint
981
982	HaveWriter bool
983
984	WantToRead uint
985
986	WantToWrite uint
987}
988
989func (x *StaticRWLock) GoPointer() uintptr {
990	return uintptr(unsafe.Pointer(x))
991}
992
993var xStaticRWLockFree func(uintptr)
994
995// Releases all resources allocated to @lock.
996//
997// You don't have to call this functions for a #GStaticRWLock with an
998// unbounded lifetime, i.e. objects declared 'static', but if you have
999// a #GStaticRWLock as a member of a structure, and the structure is
1000// freed, you should also free the #GStaticRWLock.
1001func (x *StaticRWLock) Free() {
1002
1003	xStaticRWLockFree(x.GoPointer())
1004
1005}
1006
1007var xStaticRWLockInit func(uintptr)
1008
1009// A #GStaticRWLock must be initialized with this function before it
1010// can be used. Alternatively you can initialize it with
1011// %G_STATIC_RW_LOCK_INIT.
1012func (x *StaticRWLock) Init() {
1013
1014	xStaticRWLockInit(x.GoPointer())
1015
1016}
1017
1018var xStaticRWLockReaderLock func(uintptr)
1019
1020// Locks @lock for reading. There may be unlimited concurrent locks for
1021// reading of a #GStaticRWLock at the same time.  If @lock is already
1022// locked for writing by another thread or if another thread is already
1023// waiting to lock @lock for writing, this function will block until
1024// @lock is unlocked by the other writing thread and no other writing
1025// threads want to lock @lock. This lock has to be unlocked by
1026// g_static_rw_lock_reader_unlock().
1027//
1028// #GStaticRWLock is not recursive. It might seem to be possible to
1029// recursively lock for reading, but that can result in a deadlock, due
1030// to writer preference.
1031func (x *StaticRWLock) ReaderLock() {
1032
1033	xStaticRWLockReaderLock(x.GoPointer())
1034
1035}
1036
1037var xStaticRWLockReaderTrylock func(uintptr) bool
1038
1039// Tries to lock @lock for reading. If @lock is already locked for
1040// writing by another thread or if another thread is already waiting to
1041// lock @lock for writing, immediately returns %FALSE. Otherwise locks
1042// @lock for reading and returns %TRUE. This lock has to be unlocked by
1043// g_static_rw_lock_reader_unlock().
1044func (x *StaticRWLock) ReaderTrylock() bool {
1045
1046	cret := xStaticRWLockReaderTrylock(x.GoPointer())
1047	return cret
1048}
1049
1050var xStaticRWLockReaderUnlock func(uintptr)
1051
1052// Unlocks @lock. If a thread waits to lock @lock for writing and all
1053// locks for reading have been unlocked, the waiting thread is woken up
1054// and can lock @lock for writing.
1055func (x *StaticRWLock) ReaderUnlock() {
1056
1057	xStaticRWLockReaderUnlock(x.GoPointer())
1058
1059}
1060
1061var xStaticRWLockWriterLock func(uintptr)
1062
1063// Locks @lock for writing. If @lock is already locked for writing or
1064// reading by other threads, this function will block until @lock is
1065// completely unlocked and then lock @lock for writing. While this
1066// functions waits to lock @lock, no other thread can lock @lock for
1067// reading. When @lock is locked for writing, no other thread can lock
1068// @lock (neither for reading nor writing). This lock has to be
1069// unlocked by g_static_rw_lock_writer_unlock().
1070func (x *StaticRWLock) WriterLock() {
1071
1072	xStaticRWLockWriterLock(x.GoPointer())
1073
1074}
1075
1076var xStaticRWLockWriterTrylock func(uintptr) bool
1077
1078// Tries to lock @lock for writing. If @lock is already locked (for
1079// either reading or writing) by another thread, it immediately returns
1080// %FALSE. Otherwise it locks @lock for writing and returns %TRUE. This
1081// lock has to be unlocked by g_static_rw_lock_writer_unlock().
1082func (x *StaticRWLock) WriterTrylock() bool {
1083
1084	cret := xStaticRWLockWriterTrylock(x.GoPointer())
1085	return cret
1086}
1087
1088var xStaticRWLockWriterUnlock func(uintptr)
1089
1090// Unlocks @lock. If a thread is waiting to lock @lock for writing and
1091// all locks for reading have been unlocked, the waiting thread is
1092// woken up and can lock @lock for writing. If no thread is waiting to
1093// lock @lock for writing, and some thread or threads are waiting to
1094// lock @lock for reading, the waiting threads are woken up and can
1095// lock @lock for reading.
1096func (x *StaticRWLock) WriterUnlock() {
1097
1098	xStaticRWLockWriterUnlock(x.GoPointer())
1099
1100}
1101
1102// A #GStaticRecMutex works like a #GStaticMutex, but it can be locked
1103// multiple times by one thread. If you enter it n times, you have to
1104// unlock it n times again to let other threads lock it. An exception
1105// is the function g_static_rec_mutex_unlock_full(): that allows you to
1106// unlock a #GStaticRecMutex completely returning the depth, (i.e. the
1107// number of times this mutex was locked). The depth can later be used
1108// to restore the state of the #GStaticRecMutex by calling
1109// g_static_rec_mutex_lock_full(). In GLib 2.32, #GStaticRecMutex has
1110// been deprecated in favor of #GRecMutex.
1111//
1112// Even though #GStaticRecMutex is not opaque, it should only be used
1113// with the following functions.
1114//
1115// All of the g_static_rec_mutex_* functions can be used even if
1116// g_thread_init() has not been called. Then they do nothing, apart
1117// from g_static_rec_mutex_trylock(), which does nothing but returning
1118// %TRUE.
1119type StaticRecMutex struct {
1120	_ structs.HostLayout
1121
1122	Mutex uintptr
1123
1124	Depth uint
1125}
1126
1127func (x *StaticRecMutex) GoPointer() uintptr {
1128	return uintptr(unsafe.Pointer(x))
1129}
1130
1131var xStaticRecMutexFree func(uintptr)
1132
1133// Releases all resources allocated to a #GStaticRecMutex.
1134//
1135// You don't have to call this functions for a #GStaticRecMutex with an
1136// unbounded lifetime, i.e. objects declared 'static', but if you have
1137// a #GStaticRecMutex as a member of a structure and the structure is
1138// freed, you should also free the #GStaticRecMutex.
1139func (x *StaticRecMutex) Free() {
1140
1141	xStaticRecMutexFree(x.GoPointer())
1142
1143}
1144
1145var xStaticRecMutexInit func(uintptr)
1146
1147// A #GStaticRecMutex must be initialized with this function before it
1148// can be used. Alternatively you can initialize it with
1149// %G_STATIC_REC_MUTEX_INIT.
1150func (x *StaticRecMutex) Init() {
1151
1152	xStaticRecMutexInit(x.GoPointer())
1153
1154}
1155
1156var xStaticRecMutexLock func(uintptr)
1157
1158// Locks @mutex. If @mutex is already locked by another thread, the
1159// current thread will block until @mutex is unlocked by the other
1160// thread. If @mutex is already locked by the calling thread, this
1161// functions increases the depth of @mutex and returns immediately.
1162func (x *StaticRecMutex) Lock() {
1163
1164	xStaticRecMutexLock(x.GoPointer())
1165
1166}
1167
1168var xStaticRecMutexLockFull func(uintptr, uint)
1169
1170// Works like calling g_static_rec_mutex_lock() for @mutex @depth times.
1171func (x *StaticRecMutex) LockFull(DepthVar uint) {
1172
1173	xStaticRecMutexLockFull(x.GoPointer(), DepthVar)
1174
1175}
1176
1177var xStaticRecMutexTrylock func(uintptr) bool
1178
1179// Tries to lock @mutex. If @mutex is already locked by another thread,
1180// it immediately returns %FALSE. Otherwise it locks @mutex and returns
1181// %TRUE. If @mutex is already locked by the calling thread, this
1182// functions increases the depth of @mutex and immediately returns
1183// %TRUE.
1184func (x *StaticRecMutex) Trylock() bool {
1185
1186	cret := xStaticRecMutexTrylock(x.GoPointer())
1187	return cret
1188}
1189
1190var xStaticRecMutexUnlock func(uintptr)
1191
1192// Unlocks @mutex. Another thread will be allowed to lock @mutex only
1193// when it has been unlocked as many times as it had been locked
1194// before. If @mutex is completely unlocked and another thread is
1195// blocked in a g_static_rec_mutex_lock() call for @mutex, it will be
1196// woken and can lock @mutex itself.
1197func (x *StaticRecMutex) Unlock() {
1198
1199	xStaticRecMutexUnlock(x.GoPointer())
1200
1201}
1202
1203var xStaticRecMutexUnlockFull func(uintptr) uint
1204
1205// Completely unlocks @mutex. If another thread is blocked in a
1206// g_static_rec_mutex_lock() call for @mutex, it will be woken and can
1207// lock @mutex itself. This function returns the number of times that
1208// @mutex has been locked by the current thread. To restore the state
1209// before the call to g_static_rec_mutex_unlock_full() you can call
1210// g_static_rec_mutex_lock_full() with the depth returned by this
1211// function.
1212func (x *StaticRecMutex) UnlockFull() uint {
1213
1214	cret := xStaticRecMutexUnlockFull(x.GoPointer())
1215	return cret
1216}
1217
1218// The #GThread struct represents a running thread. This struct
1219// is returned by g_thread_new() or g_thread_try_new(). You can
1220// obtain the #GThread struct representing the current thread by
1221// calling g_thread_self().
1222//
1223// GThread is refcounted, see g_thread_ref() and g_thread_unref().
1224// The thread represented by it holds a reference while it is running,
1225// and g_thread_join() consumes the reference that it is given, so
1226// it is normally not necessary to manage GThread references
1227// explicitly.
1228//
1229// The structure is opaque -- none of its fields may be directly
1230// accessed.
1231type Thread struct {
1232	_ structs.HostLayout
1233
1234	Func ThreadFunc
1235
1236	Data uintptr
1237
1238	Joinable bool
1239
1240	Priority ThreadPriority
1241}
1242
1243var xThreadGLibType func() types.GType
1244
1245func ThreadGLibType() types.GType {
1246	return xThreadGLibType()
1247}
1248
1249func (x *Thread) GoPointer() uintptr {
1250	return uintptr(unsafe.Pointer(x))
1251}
1252
1253var xNewThread func(uintptr, uintptr, uintptr) *Thread
1254
1255// This function creates a new thread. The new thread starts by invoking
1256// @func with the argument data. The thread will run until @func returns
1257// or until g_thread_exit() is called from the new thread. The return value
1258// of @func becomes the return value of the thread, which can be obtained
1259// with g_thread_join().
1260//
1261// The @name can be useful for discriminating threads in a debugger.
1262// It is not used for other purposes and does not have to be unique.
1263// Some systems restrict the length of @name to 16 bytes.
1264//
1265// If the thread can not be created the program aborts. See
1266// g_thread_try_new() if you want to attempt to deal with failures.
1267//
1268// If you are using threads to offload (potentially many) short-lived tasks,
1269// #GThreadPool may be more appropriate than manually spawning and tracking
1270// multiple #GThreads.
1271//
1272// To free the struct returned by this function, use g_thread_unref().
1273// Note that g_thread_join() implicitly unrefs the #GThread as well.
1274//
1275// New threads by default inherit their scheduler policy (POSIX) or thread
1276// priority (Windows) of the thread creating the new thread.
1277//
1278// This behaviour changed in GLib 2.64: before threads on Windows were not
1279// inheriting the thread priority but were spawned with the default priority.
1280// Starting with GLib 2.64 the behaviour is now consistent between Windows and
1281// POSIX and all threads inherit their parent thread's priority.
1282func NewThread(NameVar *string, FuncVar *ThreadFunc, DataVar uintptr) *Thread {
1283
1284	var FuncVarRef uintptr
1285	if FuncVar != nil {
1286		FuncVarPtr := uintptr(unsafe.Pointer(FuncVar))
1287		if cbRefPtr, ok := GetCallback(FuncVarPtr); ok {
1288			FuncVarRef = cbRefPtr
1289		} else {
1290			fcb := func(arg0 uintptr) uintptr {
1291				cbFn := *FuncVar
1292				return cbFn(arg0)
1293			}
1294			FuncVarRef = purego.NewCallback(fcb)
1295			SaveCallbackWithClosure(FuncVarPtr, FuncVarRef, FuncVar)
1296		}
1297	}
1298
1299	NameVarPtr := core.GStrdupNullable(NameVar)
1300	defer core.GFreeNullable(NameVarPtr)
1301
1302	cret := xNewThread(NameVarPtr, FuncVarRef, DataVar)
1303	return cret
1304}
1305
1306var xThreadTryNew func(uintptr, uintptr, uintptr, **Error) *Thread
1307
1308// This function is the same as g_thread_new() except that
1309// it allows for the possibility of failure.
1310//
1311// If a thread can not be created (due to resource limits),
1312// @error is set and %NULL is returned.
1313func ThreadTryNew(NameVar *string, FuncVar *ThreadFunc, DataVar uintptr) (*Thread, error) {
1314	var cerr *Error
1315
1316	var FuncVarRef uintptr
1317	if FuncVar != nil {
1318		FuncVarPtr := uintptr(unsafe.Pointer(FuncVar))
1319		if cbRefPtr, ok := GetCallback(FuncVarPtr); ok {
1320			FuncVarRef = cbRefPtr
1321		} else {
1322			fcb := func(arg0 uintptr) uintptr {
1323				cbFn := *FuncVar
1324				return cbFn(arg0)
1325			}
1326			FuncVarRef = purego.NewCallback(fcb)
1327			SaveCallbackWithClosure(FuncVarPtr, FuncVarRef, FuncVar)
1328		}
1329	}
1330
1331	NameVarPtr := core.GStrdupNullable(NameVar)
1332	defer core.GFreeNullable(NameVarPtr)
1333
1334	cret := xThreadTryNew(NameVarPtr, FuncVarRef, DataVar, &cerr)
1335	if cerr == nil {
1336		return cret, nil
1337	}
1338	return cret, cerr
1339
1340}
1341
1342var xThreadGetName func(uintptr) string
1343
1344// Gets the name of the thread.
1345//
1346// This function is intended for debugging purposes.
1347func (x *Thread) GetName() string {
1348
1349	cret := xThreadGetName(x.GoPointer())
1350	return cret
1351}
1352
1353var xThreadJoin func(uintptr) uintptr
1354
1355// Waits until @thread finishes, i.e. the function @func, as
1356// given to g_thread_new(), returns or g_thread_exit() is called.
1357// If @thread has already terminated, then g_thread_join()
1358// returns immediately.
1359//
1360// Any thread can wait for any other thread by calling g_thread_join(),
1361// not just its 'creator'. Calling g_thread_join() from multiple threads
1362// for the same @thread leads to undefined behaviour.
1363//
1364// The value returned by @func or given to g_thread_exit() is
1365// returned by this function.
1366//
1367// g_thread_join() consumes the reference to the passed-in @thread.
1368// This will usually cause the #GThread struct and associated resources
1369// to be freed. Use g_thread_ref() to obtain an extra reference if you
1370// want to keep the GThread alive beyond the g_thread_join() call.
1371func (x *Thread) Join() uintptr {
1372
1373	cret := xThreadJoin(x.GoPointer())
1374	return cret
1375}
1376
1377var xThreadRef func(uintptr) *Thread
1378
1379// Increase the reference count on @thread.
1380func (x *Thread) Ref() *Thread {
1381
1382	cret := xThreadRef(x.GoPointer())
1383	return cret
1384}
1385
1386var xThreadSetPriority func(uintptr, ThreadPriority)
1387
1388// This function does nothing.
1389func (x *Thread) SetPriority(PriorityVar ThreadPriority) {
1390
1391	xThreadSetPriority(x.GoPointer(), PriorityVar)
1392
1393}
1394
1395var xThreadUnref func(uintptr)
1396
1397// Decrease the reference count on @thread, possibly freeing all
1398// resources associated with it.
1399//
1400// Note that each thread holds a reference to its #GThread while
1401// it is running, so it is safe to drop your own reference to it
1402// if you don't need it anymore.
1403func (x *Thread) Unref() {
1404
1405	xThreadUnref(x.GoPointer())
1406
1407}
1408
1409// This function table is no longer used by g_thread_init()
1410// to initialize the thread system.
1411type ThreadFunctions struct {
1412	_ structs.HostLayout
1413
1414	xMutexNew uintptr
1415
1416	xMutexLock uintptr
1417
1418	xMutexTrylock uintptr
1419
1420	xMutexUnlock uintptr
1421
1422	xMutexFree uintptr
1423
1424	xCondNew uintptr
1425
1426	xCondSignal uintptr
1427
1428	xCondBroadcast uintptr
1429
1430	xCondWait uintptr
1431
1432	xCondTimedWait uintptr
1433
1434	xCondFree uintptr
1435
1436	xPrivateNew uintptr
1437
1438	xPrivateGet uintptr
1439
1440	xPrivateSet uintptr
1441
1442	xThreadCreate uintptr
1443
1444	xThreadYield uintptr
1445
1446	xThreadJoin uintptr
1447
1448	xThreadExit uintptr
1449
1450	xThreadSetPriority uintptr
1451
1452	xThreadSelf uintptr
1453
1454	xThreadEqual uintptr
1455}
1456
1457func (x *ThreadFunctions) GoPointer() uintptr {
1458	return uintptr(unsafe.Pointer(x))
1459}
1460
1461// OverrideMutexNew sets the "mutex_new" callback function.
1462// virtual function pointer for g_mutex_new()
1463func (x *ThreadFunctions) OverrideMutexNew(cb func() *Mutex) {
1464	if cb == nil {
1465		x.xMutexNew = 0
1466	} else {
1467		x.xMutexNew = purego.NewCallback(func() *Mutex {
1468			return cb()
1469		})
1470	}
1471}
1472
1473// GetMutexNew gets the "mutex_new" callback function.
1474// virtual function pointer for g_mutex_new()
1475func (x *ThreadFunctions) GetMutexNew() func() *Mutex {
1476	if x.xMutexNew == 0 {
1477		return nil
1478	}
1479	var rawCallback func() *Mutex
1480	purego.RegisterFunc(&rawCallback, x.xMutexNew)
1481	return func() *Mutex {
1482		return rawCallback()
1483	}
1484}
1485
1486// OverrideMutexLock sets the "mutex_lock" callback function.
1487// virtual function pointer for g_mutex_lock()
1488func (x *ThreadFunctions) OverrideMutexLock(cb func(*Mutex)) {
1489	if cb == nil {
1490		x.xMutexLock = 0
1491	} else {
1492		x.xMutexLock = purego.NewCallback(func(MutexVarp *Mutex) {
1493			cb(MutexVarp)
1494		})
1495	}
1496}
1497
1498// GetMutexLock gets the "mutex_lock" callback function.
1499// virtual function pointer for g_mutex_lock()
1500func (x *ThreadFunctions) GetMutexLock() func(*Mutex) {
1501	if x.xMutexLock == 0 {
1502		return nil
1503	}
1504	var rawCallback func(MutexVarp *Mutex)
1505	purego.RegisterFunc(&rawCallback, x.xMutexLock)
1506	return func(MutexVar *Mutex) {
1507		rawCallback(MutexVar)
1508	}
1509}
1510
1511// OverrideMutexTrylock sets the "mutex_trylock" callback function.
1512// virtual function pointer for g_mutex_trylock()
1513func (x *ThreadFunctions) OverrideMutexTrylock(cb func(*Mutex) bool) {
1514	if cb == nil {
1515		x.xMutexTrylock = 0
1516	} else {
1517		x.xMutexTrylock = purego.NewCallback(func(MutexVarp *Mutex) bool {
1518			return cb(MutexVarp)
1519		})
1520	}
1521}
1522
1523// GetMutexTrylock gets the "mutex_trylock" callback function.
1524// virtual function pointer for g_mutex_trylock()
1525func (x *ThreadFunctions) GetMutexTrylock() func(*Mutex) bool {
1526	if x.xMutexTrylock == 0 {
1527		return nil
1528	}
1529	var rawCallback func(MutexVarp *Mutex) bool
1530	purego.RegisterFunc(&rawCallback, x.xMutexTrylock)
1531	return func(MutexVar *Mutex) bool {
1532		return rawCallback(MutexVar)
1533	}
1534}
1535
1536// OverrideMutexUnlock sets the "mutex_unlock" callback function.
1537// virtual function pointer for g_mutex_unlock()
1538func (x *ThreadFunctions) OverrideMutexUnlock(cb func(*Mutex)) {
1539	if cb == nil {
1540		x.xMutexUnlock = 0
1541	} else {
1542		x.xMutexUnlock = purego.NewCallback(func(MutexVarp *Mutex) {
1543			cb(MutexVarp)
1544		})
1545	}
1546}
1547
1548// GetMutexUnlock gets the "mutex_unlock" callback function.
1549// virtual function pointer for g_mutex_unlock()
1550func (x *ThreadFunctions) GetMutexUnlock() func(*Mutex) {
1551	if x.xMutexUnlock == 0 {
1552		return nil
1553	}
1554	var rawCallback func(MutexVarp *Mutex)
1555	purego.RegisterFunc(&rawCallback, x.xMutexUnlock)
1556	return func(MutexVar *Mutex) {
1557		rawCallback(MutexVar)
1558	}
1559}
1560
1561// OverrideMutexFree sets the "mutex_free" callback function.
1562// virtual function pointer for g_mutex_free()
1563func (x *ThreadFunctions) OverrideMutexFree(cb func(*Mutex)) {
1564	if cb == nil {
1565		x.xMutexFree = 0
1566	} else {
1567		x.xMutexFree = purego.NewCallback(func(MutexVarp *Mutex) {
1568			cb(MutexVarp)
1569		})
1570	}
1571}
1572
1573// GetMutexFree gets the "mutex_free" callback function.
1574// virtual function pointer for g_mutex_free()
1575func (x *ThreadFunctions) GetMutexFree() func(*Mutex) {
1576	if x.xMutexFree == 0 {
1577		return nil
1578	}
1579	var rawCallback func(MutexVarp *Mutex)
1580	purego.RegisterFunc(&rawCallback, x.xMutexFree)
1581	return func(MutexVar *Mutex) {
1582		rawCallback(MutexVar)
1583	}
1584}
1585
1586// OverrideCondNew sets the "cond_new" callback function.
1587// virtual function pointer for g_cond_new()
1588func (x *ThreadFunctions) OverrideCondNew(cb func() *Cond) {
1589	if cb == nil {
1590		x.xCondNew = 0
1591	} else {
1592		x.xCondNew = purego.NewCallback(func() *Cond {
1593			return cb()
1594		})
1595	}
1596}
1597
1598// GetCondNew gets the "cond_new" callback function.
1599// virtual function pointer for g_cond_new()
1600func (x *ThreadFunctions) GetCondNew() func() *Cond {
1601	if x.xCondNew == 0 {
1602		return nil
1603	}
1604	var rawCallback func() *Cond
1605	purego.RegisterFunc(&rawCallback, x.xCondNew)
1606	return func() *Cond {
1607		return rawCallback()
1608	}
1609}
1610
1611// OverrideCondSignal sets the "cond_signal" callback function.
1612// virtual function pointer for g_cond_signal()
1613func (x *ThreadFunctions) OverrideCondSignal(cb func(*Cond)) {
1614	if cb == nil {
1615		x.xCondSignal = 0
1616	} else {
1617		x.xCondSignal = purego.NewCallback(func(CondVarp *Cond) {
1618			cb(CondVarp)
1619		})
1620	}
1621}
1622
1623// GetCondSignal gets the "cond_signal" callback function.
1624// virtual function pointer for g_cond_signal()
1625func (x *ThreadFunctions) GetCondSignal() func(*Cond) {
1626	if x.xCondSignal == 0 {
1627		return nil
1628	}
1629	var rawCallback func(CondVarp *Cond)
1630	purego.RegisterFunc(&rawCallback, x.xCondSignal)
1631	return func(CondVar *Cond) {
1632		rawCallback(CondVar)
1633	}
1634}
1635
1636// OverrideCondBroadcast sets the "cond_broadcast" callback function.
1637// virtual function pointer for g_cond_broadcast()
1638func (x *ThreadFunctions) OverrideCondBroadcast(cb func(*Cond)) {
1639	if cb == nil {
1640		x.xCondBroadcast = 0
1641	} else {
1642		x.xCondBroadcast = purego.NewCallback(func(CondVarp *Cond) {
1643			cb(CondVarp)
1644		})
1645	}
1646}
1647
1648// GetCondBroadcast gets the "cond_broadcast" callback function.
1649// virtual function pointer for g_cond_broadcast()
1650func (x *ThreadFunctions) GetCondBroadcast() func(*Cond) {
1651	if x.xCondBroadcast == 0 {
1652		return nil
1653	}
1654	var rawCallback func(CondVarp *Cond)
1655	purego.RegisterFunc(&rawCallback, x.xCondBroadcast)
1656	return func(CondVar *Cond) {
1657		rawCallback(CondVar)
1658	}
1659}
1660
1661// OverrideCondWait sets the "cond_wait" callback function.
1662// virtual function pointer for g_cond_wait()
1663func (x *ThreadFunctions) OverrideCondWait(cb func(*Cond, *Mutex)) {
1664	if cb == nil {
1665		x.xCondWait = 0
1666	} else {
1667		x.xCondWait = purego.NewCallback(func(CondVarp *Cond, MutexVarp *Mutex) {
1668			cb(CondVarp, MutexVarp)
1669		})
1670	}
1671}
1672
1673// GetCondWait gets the "cond_wait" callback function.
1674// virtual function pointer for g_cond_wait()
1675func (x *ThreadFunctions) GetCondWait() func(*Cond, *Mutex) {
1676	if x.xCondWait == 0 {
1677		return nil
1678	}
1679	var rawCallback func(CondVarp *Cond, MutexVarp *Mutex)
1680	purego.RegisterFunc(&rawCallback, x.xCondWait)
1681	return func(CondVar *Cond, MutexVar *Mutex) {
1682		rawCallback(CondVar, MutexVar)
1683	}
1684}
1685
1686// OverrideCondTimedWait sets the "cond_timed_wait" callback function.
1687// virtual function pointer for g_cond_timed_wait()
1688func (x *ThreadFunctions) OverrideCondTimedWait(cb func(*Cond, *Mutex, *TimeVal) bool) {
1689	if cb == nil {
1690		x.xCondTimedWait = 0
1691	} else {
1692		x.xCondTimedWait = purego.NewCallback(func(CondVarp *Cond, MutexVarp *Mutex, EndTimeVarp *TimeVal) bool {
1693			return cb(CondVarp, MutexVarp, EndTimeVarp)
1694		})
1695	}
1696}
1697
1698// GetCondTimedWait gets the "cond_timed_wait" callback function.
1699// virtual function pointer for g_cond_timed_wait()
1700func (x *ThreadFunctions) GetCondTimedWait() func(*Cond, *Mutex, *TimeVal) bool {
1701	if x.xCondTimedWait == 0 {
1702		return nil
1703	}
1704	var rawCallback func(CondVarp *Cond, MutexVarp *Mutex, EndTimeVarp *TimeVal) bool
1705	purego.RegisterFunc(&rawCallback, x.xCondTimedWait)
1706	return func(CondVar *Cond, MutexVar *Mutex, EndTimeVar *TimeVal) bool {
1707		return rawCallback(CondVar, MutexVar, EndTimeVar)
1708	}
1709}
1710
1711// OverrideCondFree sets the "cond_free" callback function.
1712// virtual function pointer for g_cond_free()
1713func (x *ThreadFunctions) OverrideCondFree(cb func(*Cond)) {
1714	if cb == nil {
1715		x.xCondFree = 0
1716	} else {
1717		x.xCondFree = purego.NewCallback(func(CondVarp *Cond) {
1718			cb(CondVarp)
1719		})
1720	}
1721}
1722
1723// GetCondFree gets the "cond_free" callback function.
1724// virtual function pointer for g_cond_free()
1725func (x *ThreadFunctions) GetCondFree() func(*Cond) {
1726	if x.xCondFree == 0 {
1727		return nil
1728	}
1729	var rawCallback func(CondVarp *Cond)
1730	purego.RegisterFunc(&rawCallback, x.xCondFree)
1731	return func(CondVar *Cond) {
1732		rawCallback(CondVar)
1733	}
1734}
1735
1736// OverridePrivateNew sets the "private_new" callback function.
1737// virtual function pointer for g_private_new()
1738func (x *ThreadFunctions) OverridePrivateNew(cb func(*DestroyNotify) *Private) {
1739	if cb == nil {
1740		x.xPrivateNew = 0
1741	} else {
1742		x.xPrivateNew = purego.NewCallback(func(DestructorVarp uintptr) *Private {
1743			return cb((*DestroyNotify)(unsafe.Pointer(DestructorVarp)))
1744		})
1745	}
1746}
1747
1748// GetPrivateNew gets the "private_new" callback function.
1749// virtual function pointer for g_private_new()
1750func (x *ThreadFunctions) GetPrivateNew() func(*DestroyNotify) *Private {
1751	if x.xPrivateNew == 0 {
1752		return nil
1753	}
1754	var rawCallback func(DestructorVarp uintptr) *Private
1755	purego.RegisterFunc(&rawCallback, x.xPrivateNew)
1756	return func(DestructorVar *DestroyNotify) *Private {
1757		return rawCallback(NewCallback(DestructorVar))
1758	}
1759}
1760
1761// OverridePrivateGet sets the "private_get" callback function.
1762// virtual function pointer for g_private_get()
1763func (x *ThreadFunctions) OverridePrivateGet(cb func(*Private) uintptr) {
1764	if cb == nil {
1765		x.xPrivateGet = 0
1766	} else {
1767		x.xPrivateGet = purego.NewCallback(func(PrivateKeyVarp *Private) uintptr {
1768			return cb(PrivateKeyVarp)
1769		})
1770	}
1771}
1772
1773// GetPrivateGet gets the "private_get" callback function.
1774// virtual function pointer for g_private_get()
1775func (x *ThreadFunctions) GetPrivateGet() func(*Private) uintptr {
1776	if x.xPrivateGet == 0 {
1777		return nil
1778	}
1779	var rawCallback func(PrivateKeyVarp *Private) uintptr
1780	purego.RegisterFunc(&rawCallback, x.xPrivateGet)
1781	return func(PrivateKeyVar *Private) uintptr {
1782		return rawCallback(PrivateKeyVar)
1783	}
1784}
1785
1786// OverridePrivateSet sets the "private_set" callback function.
1787// virtual function pointer for g_private_set()
1788func (x *ThreadFunctions) OverridePrivateSet(cb func(*Private, uintptr)) {
1789	if cb == nil {
1790		x.xPrivateSet = 0
1791	} else {
1792		x.xPrivateSet = purego.NewCallback(func(PrivateKeyVarp *Private, DataVarp uintptr) {
1793			cb(PrivateKeyVarp, DataVarp)
1794		})
1795	}
1796}
1797
1798// GetPrivateSet gets the "private_set" callback function.
1799// virtual function pointer for g_private_set()
1800func (x *ThreadFunctions) GetPrivateSet() func(*Private, uintptr) {
1801	if x.xPrivateSet == 0 {
1802		return nil
1803	}
1804	var rawCallback func(PrivateKeyVarp *Private, DataVarp uintptr)
1805	purego.RegisterFunc(&rawCallback, x.xPrivateSet)
1806	return func(PrivateKeyVar *Private, DataVar uintptr) {
1807		rawCallback(PrivateKeyVar, DataVar)
1808	}
1809}
1810
1811// OverrideThreadCreate sets the "thread_create" callback function.
1812// virtual function pointer for g_thread_create()
1813func (x *ThreadFunctions) OverrideThreadCreate(cb func(*ThreadFunc, uintptr, uint, bool, bool, ThreadPriority, uintptr)) {
1814	if cb == nil {
1815		x.xThreadCreate = 0
1816	} else {
1817		x.xThreadCreate = purego.NewCallback(func(FuncVarp uintptr, DataVarp uintptr, StackSizeVarp uint, JoinableVarp bool, BoundVarp bool, PriorityVarp ThreadPriority, ThreadVarp uintptr) {
1818			cb((*ThreadFunc)(unsafe.Pointer(FuncVarp)), DataVarp, StackSizeVarp, JoinableVarp, BoundVarp, PriorityVarp, ThreadVarp)
1819		})
1820	}
1821}
1822
1823// GetThreadCreate gets the "thread_create" callback function.
1824// virtual function pointer for g_thread_create()
1825func (x *ThreadFunctions) GetThreadCreate() func(*ThreadFunc, uintptr, uint, bool, bool, ThreadPriority, uintptr) {
1826	if x.xThreadCreate == 0 {
1827		return nil
1828	}
1829	var rawCallback func(FuncVarp uintptr, DataVarp uintptr, StackSizeVarp uint, JoinableVarp bool, BoundVarp bool, PriorityVarp ThreadPriority, ThreadVarp uintptr)
1830	purego.RegisterFunc(&rawCallback, x.xThreadCreate)
1831	return func(FuncVar *ThreadFunc, DataVar uintptr, StackSizeVar uint, JoinableVar bool, BoundVar bool, PriorityVar ThreadPriority, ThreadVar uintptr) {
1832		rawCallback(NewCallback(FuncVar), DataVar, StackSizeVar, JoinableVar, BoundVar, PriorityVar, ThreadVar)
1833	}
1834}
1835
1836// OverrideThreadYield sets the "thread_yield" callback function.
1837// virtual function pointer for g_thread_yield()
1838func (x *ThreadFunctions) OverrideThreadYield(cb func()) {
1839	if cb == nil {
1840		x.xThreadYield = 0
1841	} else {
1842		x.xThreadYield = purego.NewCallback(func() {
1843			cb()
1844		})
1845	}
1846}
1847
1848// GetThreadYield gets the "thread_yield" callback function.
1849// virtual function pointer for g_thread_yield()
1850func (x *ThreadFunctions) GetThreadYield() func() {
1851	if x.xThreadYield == 0 {
1852		return nil
1853	}
1854	var rawCallback func()
1855	purego.RegisterFunc(&rawCallback, x.xThreadYield)
1856	return func() {
1857		rawCallback()
1858	}
1859}
1860
1861// OverrideThreadJoin sets the "thread_join" callback function.
1862// virtual function pointer for g_thread_join()
1863func (x *ThreadFunctions) OverrideThreadJoin(cb func(uintptr)) {
1864	if cb == nil {
1865		x.xThreadJoin = 0
1866	} else {
1867		x.xThreadJoin = purego.NewCallback(func(ThreadVarp uintptr) {
1868			cb(ThreadVarp)
1869		})
1870	}
1871}
1872
1873// GetThreadJoin gets the "thread_join" callback function.
1874// virtual function pointer for g_thread_join()
1875func (x *ThreadFunctions) GetThreadJoin() func(uintptr) {
1876	if x.xThreadJoin == 0 {
1877		return nil
1878	}
1879	var rawCallback func(ThreadVarp uintptr)
1880	purego.RegisterFunc(&rawCallback, x.xThreadJoin)
1881	return func(ThreadVar uintptr) {
1882		rawCallback(ThreadVar)
1883	}
1884}
1885
1886// OverrideThreadExit sets the "thread_exit" callback function.
1887// virtual function pointer for g_thread_exit()
1888func (x *ThreadFunctions) OverrideThreadExit(cb func()) {
1889	if cb == nil {
1890		x.xThreadExit = 0
1891	} else {
1892		x.xThreadExit = purego.NewCallback(func() {
1893			cb()
1894		})
1895	}
1896}
1897
1898// GetThreadExit gets the "thread_exit" callback function.
1899// virtual function pointer for g_thread_exit()
1900func (x *ThreadFunctions) GetThreadExit() func() {
1901	if x.xThreadExit == 0 {
1902		return nil
1903	}
1904	var rawCallback func()
1905	purego.RegisterFunc(&rawCallback, x.xThreadExit)
1906	return func() {
1907		rawCallback()
1908	}
1909}
1910
1911// OverrideThreadSetPriority sets the "thread_set_priority" callback function.
1912// virtual function pointer for
1913//
1914//	g_thread_set_priority()
1915func (x *ThreadFunctions) OverrideThreadSetPriority(cb func(uintptr, ThreadPriority)) {
1916	if cb == nil {
1917		x.xThreadSetPriority = 0
1918	} else {
1919		x.xThreadSetPriority = purego.NewCallback(func(ThreadVarp uintptr, PriorityVarp ThreadPriority) {
1920			cb(ThreadVarp, PriorityVarp)
1921		})
1922	}
1923}
1924
1925// GetThreadSetPriority gets the "thread_set_priority" callback function.
1926// virtual function pointer for
1927//
1928//	g_thread_set_priority()
1929func (x *ThreadFunctions) GetThreadSetPriority() func(uintptr, ThreadPriority) {
1930	if x.xThreadSetPriority == 0 {
1931		return nil
1932	}
1933	var rawCallback func(ThreadVarp uintptr, PriorityVarp ThreadPriority)
1934	purego.RegisterFunc(&rawCallback, x.xThreadSetPriority)
1935	return func(ThreadVar uintptr, PriorityVar ThreadPriority) {
1936		rawCallback(ThreadVar, PriorityVar)
1937	}
1938}
1939
1940// OverrideThreadSelf sets the "thread_self" callback function.
1941// virtual function pointer for g_thread_self()
1942func (x *ThreadFunctions) OverrideThreadSelf(cb func(uintptr)) {
1943	if cb == nil {
1944		x.xThreadSelf = 0
1945	} else {
1946		x.xThreadSelf = purego.NewCallback(func(ThreadVarp uintptr) {
1947			cb(ThreadVarp)
1948		})
1949	}
1950}
1951
1952// GetThreadSelf gets the "thread_self" callback function.
1953// virtual function pointer for g_thread_self()
1954func (x *ThreadFunctions) GetThreadSelf() func(uintptr) {
1955	if x.xThreadSelf == 0 {
1956		return nil
1957	}
1958	var rawCallback func(ThreadVarp uintptr)
1959	purego.RegisterFunc(&rawCallback, x.xThreadSelf)
1960	return func(ThreadVar uintptr) {
1961		rawCallback(ThreadVar)
1962	}
1963}
1964
1965// OverrideThreadEqual sets the "thread_equal" callback function.
1966// used internally by recursive mutex locks and by some
1967//
1968//	assertion checks
1969func (x *ThreadFunctions) OverrideThreadEqual(cb func(uintptr, uintptr) bool) {
1970	if cb == nil {
1971		x.xThreadEqual = 0
1972	} else {
1973		x.xThreadEqual = purego.NewCallback(func(Thread1Varp uintptr, Thread2Varp uintptr) bool {
1974			return cb(Thread1Varp, Thread2Varp)
1975		})
1976	}
1977}
1978
1979// GetThreadEqual gets the "thread_equal" callback function.
1980// used internally by recursive mutex locks and by some
1981//
1982//	assertion checks
1983func (x *ThreadFunctions) GetThreadEqual() func(uintptr, uintptr) bool {
1984	if x.xThreadEqual == 0 {
1985		return nil
1986	}
1987	var rawCallback func(Thread1Varp uintptr, Thread2Varp uintptr) bool
1988	purego.RegisterFunc(&rawCallback, x.xThreadEqual)
1989	return func(Thread1Var uintptr, Thread2Var uintptr) bool {
1990		return rawCallback(Thread1Var, Thread2Var)
1991	}
1992}
1993
1994// The #GMutex struct is an opaque data structure to represent a mutex
1995// (mutual exclusion). It can be used to protect data against shared
1996// access.
1997//
1998// Take for example the following function:
1999// |[<!-- language="C" -->
2000//
2001//	int
2002//	give_me_next_number (void)
2003//	{
2004//	  static int current_number = 0;
2005//
2006//	  // now do a very complicated calculation to calculate the new
2007//	  // number, this might for example be a random number generator
2008//	  current_number = calc_next_number (current_number);
2009//
2010//	  return current_number;
2011//	}
2012//
2013// ]|
2014// It is easy to see that this won't work in a multi-threaded
2015// application. There current_number must be protected against shared
2016// access. A #GMutex can be used as a solution to this problem:
2017// |[<!-- language="C" -->
2018//
2019//	int
2020//	give_me_next_number (void)
2021//	{
2022//	  static GMutex mutex;
2023//	  static int current_number = 0;
2024//	  int ret_val;
2025//
2026//	  g_mutex_lock (&mutex);
2027//	  ret_val = current_number = calc_next_number (current_number);
2028//	  g_mutex_unlock (&mutex);
2029//
2030//	  return ret_val;
2031//	}
2032//
2033// ]|
2034// Notice that the #GMutex is not initialised to any particular value.
2035// Its placement in static storage ensures that it will be initialised
2036// to all-zeros, which is appropriate.
2037//
2038// If a #GMutex is placed in other contexts (eg: embedded in a struct)
2039// then it must be explicitly initialised using g_mutex_init().
2040//
2041// A #GMutex should only be accessed via g_mutex_ functions.
2042type Mutex = uintptr
2043
2044// Opaque type. See g_mutex_locker_new() for details.
2045type MutexLocker = uintptr
2046
2047// Opaque type. See g_rw_lock_reader_locker_new() for details.
2048type RWLockReaderLocker = uintptr
2049
2050// Opaque type. See g_rw_lock_writer_locker_new() for details.
2051type RWLockWriterLocker = uintptr
2052
2053// Opaque type. See g_rec_mutex_locker_new() for details.
2054type RecMutexLocker = uintptr
2055
2056// The possible statuses of a one-time initialization function
2057// controlled by a #GOnce struct.
2058type OnceStatus int
2059
2060const (
2061
2062	// the function has not been called yet.
2063	GOnceStatusNotcalledValue OnceStatus = 0
2064	// the function call is currently in progress.
2065	GOnceStatusProgressValue OnceStatus = 1
2066	// the function has been called.
2067	GOnceStatusReadyValue OnceStatus = 2
2068)
2069
2070// Possible errors of thread related functions.
2071type ThreadError int
2072
2073const (
2074
2075	// a thread couldn't be created due to resource
2076	//                        shortage. Try again later.
2077	GThreadErrorAgainValue ThreadError = 0
2078)
2079
2080// Thread priorities.
2081type ThreadPriority int
2082
2083const (
2084
2085	// a priority lower than normal
2086	GThreadPriorityLowValue ThreadPriority = 0
2087	// the default priority
2088	GThreadPriorityNormalValue ThreadPriority = 1
2089	// a priority higher than normal
2090	GThreadPriorityHighValue ThreadPriority = 2
2091	// the highest priority
2092	GThreadPriorityUrgentValue ThreadPriority = 3
2093)
2094
2095var xCondNew func() *Cond
2096
2097// Allocates and initializes a new #GCond.
2098func CondNew() *Cond {
2099
2100	cret := xCondNew()
2101
2102	return cret
2103}
2104
2105var xGetNumProcessors func() uint
2106
2107// Determine the approximate number of threads that the system will
2108// schedule simultaneously for this process.  This is intended to be
2109// used as a parameter to g_thread_pool_new() for CPU bound tasks and
2110// similar cases.
2111func GetNumProcessors() uint {
2112
2113	cret := xGetNumProcessors()
2114
2115	return cret
2116}
2117
2118var xMutexNew func() *Mutex
2119
2120// Allocates and initializes a new #GMutex.
2121func MutexNew() *Mutex {
2122
2123	cret := xMutexNew()
2124
2125	return cret
2126}
2127
2128var xOnceInitEnter func(*uintptr) bool
2129
2130// Function to be called when starting a critical initialization
2131// section. The argument @location must point to a static
2132// 0-initialized variable that will be set to a value other than 0 at
2133// the end of the initialization section. In combination with
2134// g_once_init_leave() and the unique address @value_location, it can
2135// be ensured that an initialization section will be executed only once
2136// during a program's life time, and that concurrent threads are
2137// blocked until initialization completed. To be used in constructs
2138// like this:
2139//
2140// |[<!-- language="C" -->
2141//
2142//	static gsize initialization_value = 0;
2143//
2144//	if (g_once_init_enter (&initialization_value))
2145//	  {
2146//	    gsize setup_value = 42; // initialization code here
2147//
2148//	    g_once_init_leave (&initialization_value, setup_value);
2149//	  }
2150//
2151//	// use initialization_value here
2152//
2153// ]|
2154//
2155// While @location has a `volatile` qualifier, this is a historical artifact and
2156// the pointer passed to it should not be `volatile`.
2157func OnceInitEnter(LocationVar *uintptr) bool {
2158
2159	cret := xOnceInitEnter(LocationVar)
2160
2161	return cret
2162}
2163
2164var xOnceInitEnterImpl func(uint) bool
2165
2166func OnceInitEnterImpl(LocationVar uint) bool {
2167
2168	cret := xOnceInitEnterImpl(LocationVar)
2169
2170	return cret
2171}
2172
2173var xOnceInitEnterPointer func(uintptr) bool
2174
2175// This functions behaves in the same way as g_once_init_enter(), but can
2176// can be used to initialize pointers (or #guintptr) instead of #gsize.
2177//
2178// |[<!-- language="C" -->
2179//
2180//	static MyStruct *interesting_struct = NULL;
2181//
2182//	if (g_once_init_enter_pointer (&interesting_struct))
2183//	  {
2184//	    MyStruct *setup_value = allocate_my_struct (); // initialization code here
2185//
2186//	    g_once_init_leave_pointer (&interesting_struct, g_steal_pointer (&setup_value));
2187//	  }
2188//
2189//	// use interesting_struct here
2190//
2191// ]|
2192func OnceInitEnterPointer(LocationVar uintptr) bool {
2193
2194	cret := xOnceInitEnterPointer(LocationVar)
2195
2196	return cret
2197}
2198
2199var xOnceInitLeave func(*uintptr, uint)
2200
2201// Counterpart to g_once_init_enter(). Expects a location of a static
2202// 0-initialized initialization variable, and an initialization value
2203// other than 0. Sets the variable to the initialization value, and
2204// releases concurrent threads blocking in g_once_init_enter() on this
2205// initialization variable.
2206//
2207// While @location has a `volatile` qualifier, this is a historical artifact and
2208// the pointer passed to it should not be `volatile`.
2209func OnceInitLeave(LocationVar *uintptr, ResultVar uint) {
2210
2211	xOnceInitLeave(LocationVar, ResultVar)
2212
2213}
2214
2215var xOnceInitLeavePointer func(uintptr, uintptr)
2216
2217// Counterpart to g_once_init_enter_pointer(). Expects a location of a static
2218// `NULL`-initialized initialization variable, and an initialization value
2219// other than `NULL`. Sets the variable to the initialization value, and
2220// releases concurrent threads blocking in g_once_init_enter_pointer() on this
2221// initialization variable.
2222//
2223// This functions behaves in the same way as g_once_init_leave(), but
2224// can be used to initialize pointers (or #guintptr) instead of #gsize.
2225func OnceInitLeavePointer(LocationVar uintptr, ResultVar uintptr) {
2226
2227	xOnceInitLeavePointer(LocationVar, ResultVar)
2228
2229}
2230
2231var xPrivateNew func(uintptr) *Private
2232
2233// Creates a new #GPrivate.
2234func PrivateNew(NotifyVar *DestroyNotify) *Private {
2235
2236	var NotifyVarRef uintptr
2237	if NotifyVar != nil {
2238		NotifyVarPtr := uintptr(unsafe.Pointer(NotifyVar))
2239		if cbRefPtr, ok := GetCallback(NotifyVarPtr); ok {
2240			NotifyVarRef = cbRefPtr
2241		} else {
2242			fcb := func(arg0 uintptr) {
2243				cbFn := *NotifyVar
2244				cbFn(arg0)
2245			}
2246			NotifyVarRef = purego.NewCallback(fcb)
2247			SaveCallbackWithClosure(NotifyVarPtr, NotifyVarRef, NotifyVar)
2248		}
2249	}
2250
2251	cret := xPrivateNew(NotifyVarRef)
2252
2253	return cret
2254}
2255
2256var xThreadCreate func(uintptr, uintptr, bool, **Error) *Thread
2257
2258// This function creates a new thread.
2259//
2260// The new thread executes the function @func with the argument @data.
2261// If the thread was created successfully, it is returned.
2262//
2263// @error can be %NULL to ignore errors, or non-%NULL to report errors.
2264// The error is set, if and only if the function returns %NULL.
2265//
2266// This function returns a reference to the created thread only if
2267// @joinable is %TRUE.  In that case, you must free this reference by
2268// calling g_thread_unref() or g_thread_join().  If @joinable is %FALSE
2269// then you should probably not touch the return value.
2270func ThreadCreate(FuncVar *ThreadFunc, DataVar uintptr, JoinableVar bool) (*Thread, error) {
2271	var cerr *Error
2272
2273	var FuncVarRef uintptr
2274	if FuncVar != nil {
2275		FuncVarPtr := uintptr(unsafe.Pointer(FuncVar))
2276		if cbRefPtr, ok := GetCallback(FuncVarPtr); ok {
2277			FuncVarRef = cbRefPtr
2278		} else {
2279			fcb := func(arg0 uintptr) uintptr {
2280				cbFn := *FuncVar
2281				return cbFn(arg0)
2282			}
2283			FuncVarRef = purego.NewCallback(fcb)
2284			SaveCallbackWithClosure(FuncVarPtr, FuncVarRef, FuncVar)
2285		}
2286	}
2287
2288	cret := xThreadCreate(FuncVarRef, DataVar, JoinableVar, &cerr)
2289
2290	if cerr == nil {
2291		return cret, nil
2292	}
2293	return cret, cerr
2294
2295}
2296
2297var xThreadCreateFull func(uintptr, uintptr, uint, bool, bool, ThreadPriority, **Error) *Thread
2298
2299// This function creates a new thread.
2300func ThreadCreateFull(FuncVar *ThreadFunc, DataVar uintptr, StackSizeVar uint, JoinableVar bool, BoundVar bool, PriorityVar ThreadPriority) (*Thread, error) {
2301	var cerr *Error
2302
2303	var FuncVarRef uintptr
2304	if FuncVar != nil {
2305		FuncVarPtr := uintptr(unsafe.Pointer(FuncVar))
2306		if cbRefPtr, ok := GetCallback(FuncVarPtr); ok {
2307			FuncVarRef = cbRefPtr
2308		} else {
2309			fcb := func(arg0 uintptr) uintptr {
2310				cbFn := *FuncVar
2311				return cbFn(arg0)
2312			}
2313			FuncVarRef = purego.NewCallback(fcb)
2314			SaveCallbackWithClosure(FuncVarPtr, FuncVarRef, FuncVar)
2315		}
2316	}
2317
2318	cret := xThreadCreateFull(FuncVarRef, DataVar, StackSizeVar, JoinableVar, BoundVar, PriorityVar, &cerr)
2319
2320	if cerr == nil {
2321		return cret, nil
2322	}
2323	return cret, cerr
2324
2325}
2326
2327var xThreadExit func(uintptr)
2328
2329// Terminates the current thread.
2330//
2331// If another thread is waiting for us using g_thread_join() then the
2332// waiting thread will be woken up and get @retval as the return value
2333// of g_thread_join().
2334//
2335// Calling g_thread_exit() with a parameter @retval is equivalent to
2336// returning @retval from the function @func, as given to g_thread_new().
2337//
2338// You must only call g_thread_exit() from a thread that you created
2339// yourself with g_thread_new() or related APIs. You must not call
2340// this function from a thread created with another threading library
2341// or or from within a #GThreadPool.
2342func ThreadExit(RetvalVar uintptr) {
2343
2344	xThreadExit(RetvalVar)
2345
2346}
2347
2348var xThreadForeach func(uintptr, uintptr)
2349
2350// Call @thread_func on all #GThreads that have been
2351// created with g_thread_create().
2352//
2353// Note that threads may decide to exit while @thread_func is
2354// running, so without intimate knowledge about the lifetime of
2355// foreign threads, @thread_func shouldn't access the GThread*
2356// pointer passed in as first argument. However, @thread_func will
2357// not be called for threads which are known to have exited already.
2358//
2359// Due to thread lifetime checks, this function has an execution complexity
2360// which is quadratic in the number of existing threads.
2361func ThreadForeach(ThreadFuncVar *Func, UserDataVar uintptr) {
2362
2363	var ThreadFuncVarRef uintptr
2364	if ThreadFuncVar != nil {
2365		ThreadFuncVarPtr := uintptr(unsafe.Pointer(ThreadFuncVar))
2366		if cbRefPtr, ok := GetCallback(ThreadFuncVarPtr); ok {
2367			ThreadFuncVarRef = cbRefPtr
2368		} else {
2369			fcb := func(arg0 uintptr, arg1 uintptr) {
2370				cbFn := *ThreadFuncVar
2371				cbFn(arg0, arg1)
2372			}
2373			ThreadFuncVarRef = purego.NewCallback(fcb)
2374			SaveCallbackWithClosure(ThreadFuncVarPtr, ThreadFuncVarRef, ThreadFuncVar)
2375		}
2376	}
2377
2378	xThreadForeach(ThreadFuncVarRef, UserDataVar)
2379
2380}
2381
2382var xThreadGetInitialized func() bool
2383
2384// Indicates if g_thread_init() has been called.
2385func ThreadGetInitialized() bool {
2386
2387	cret := xThreadGetInitialized()
2388
2389	return cret
2390}
2391
2392var xThreadInit func(uintptr)
2393
2394// If you use GLib from more than one thread, you must initialize the
2395// thread system by calling g_thread_init().
2396//
2397// Since version 2.24, calling g_thread_init() multiple times is allowed,
2398// but nothing happens except for the first call.
2399//
2400// Since version 2.32, GLib does not support custom thread implementations
2401// anymore and the @vtable parameter is ignored and you should pass %NULL.
2402//
2403// ::: note
2404//
2405//	g_thread_init() must not be called directly or indirectly in a
2406//	callback from GLib. Also no mutexes may be currently locked
2407//	while calling g_thread_init().
2408//
2409// ::: note
2410//
2411//	To use g_thread_init() in your program, you have to link with
2412//	the libraries that the command `pkg-config --libs gthread-2.0`
2413//	outputs. This is not the case for all the other thread-related
2414//	functions of GLib. Those can be used without having to link
2415//	with the thread libraries.
2416func ThreadInit(VtableVar uintptr) {
2417
2418	xThreadInit(VtableVar)
2419
2420}
2421
2422var xThreadInitWithErrorcheckMutexes func(uintptr)
2423
2424func ThreadInitWithErrorcheckMutexes(VtableVar uintptr) {
2425
2426	xThreadInitWithErrorcheckMutexes(VtableVar)
2427
2428}
2429
2430var xThreadSelf func() *Thread
2431
2432// This function returns the #GThread corresponding to the
2433// current thread. Note that this function does not increase
2434// the reference count of the returned struct.
2435//
2436// This function will return a #GThread even for threads that
2437// were not created by GLib (i.e. those created by other threading
2438// APIs). This may be useful for thread identification purposes
2439// (i.e. comparisons) but you must not use GLib functions (such
2440// as g_thread_join()) on these threads.
2441func ThreadSelf() *Thread {
2442
2443	cret := xThreadSelf()
2444
2445	return cret
2446}
2447
2448var xThreadYield func()
2449
2450// Causes the calling thread to voluntarily relinquish the CPU, so
2451// that other threads can run.
2452//
2453// This function is often used as a method to make busy wait less evil.
2454func ThreadYield() {
2455
2456	xThreadYield()
2457
2458}
2459
2460func init() {
2461	core.SetPackageName("GLIB", "glib-2.0")
2462	core.SetSharedLibraries("GLIB", []string{"libgobject-2.0.so.0", "libglib-2.0.so.0"})
2463	var libs []uintptr
2464	for _, libPath := range core.GetPaths("GLIB") {
2465		lib, err := purego.Dlopen(libPath, purego.RTLD_NOW|purego.RTLD_GLOBAL)
2466		if err != nil {
2467			panic(err)
2468		}
2469		libs = append(libs, lib)
2470	}
2471
2472	core.PuregoSafeRegister(&xCondNew, libs, "g_cond_new")
2473	core.PuregoSafeRegister(&xGetNumProcessors, libs, "g_get_num_processors")
2474	core.PuregoSafeRegister(&xMutexNew, libs, "g_mutex_new")
2475	core.PuregoSafeRegister(&xOnceInitEnter, libs, "g_once_init_enter")
2476	core.PuregoSafeRegister(&xOnceInitEnterImpl, libs, "g_once_init_enter_impl")
2477	core.PuregoSafeRegister(&xOnceInitEnterPointer, libs, "g_once_init_enter_pointer")
2478	core.PuregoSafeRegister(&xOnceInitLeave, libs, "g_once_init_leave")
2479	core.PuregoSafeRegister(&xOnceInitLeavePointer, libs, "g_once_init_leave_pointer")
2480	core.PuregoSafeRegister(&xPrivateNew, libs, "g_private_new")
2481	core.PuregoSafeRegister(&xThreadCreate, libs, "g_thread_create")
2482	core.PuregoSafeRegister(&xThreadCreateFull, libs, "g_thread_create_full")
2483	core.PuregoSafeRegister(&xThreadExit, libs, "g_thread_exit")
2484	core.PuregoSafeRegister(&xThreadForeach, libs, "g_thread_foreach")
2485	core.PuregoSafeRegister(&xThreadGetInitialized, libs, "g_thread_get_initialized")
2486	core.PuregoSafeRegister(&xThreadInit, libs, "g_thread_init")
2487	core.PuregoSafeRegister(&xThreadInitWithErrorcheckMutexes, libs, "g_thread_init_with_errorcheck_mutexes")
2488	core.PuregoSafeRegister(&xThreadSelf, libs, "g_thread_self")
2489	core.PuregoSafeRegister(&xThreadYield, libs, "g_thread_yield")
2490
2491	core.PuregoSafeRegister(&xCondBroadcast, libs, "g_cond_broadcast")
2492	core.PuregoSafeRegister(&xCondClear, libs, "g_cond_clear")
2493	core.PuregoSafeRegister(&xCondFree, libs, "g_cond_free")
2494	core.PuregoSafeRegister(&xCondInit, libs, "g_cond_init")
2495	core.PuregoSafeRegister(&xCondSignal, libs, "g_cond_signal")
2496	core.PuregoSafeRegister(&xCondTimedWait, libs, "g_cond_timed_wait")
2497	core.PuregoSafeRegister(&xCondWait, libs, "g_cond_wait")
2498	core.PuregoSafeRegister(&xCondWaitUntil, libs, "g_cond_wait_until")
2499
2500	core.PuregoSafeRegister(&xOnceImpl, libs, "g_once_impl")
2501
2502	core.PuregoSafeRegister(&xPrivateGet, libs, "g_private_get")
2503	core.PuregoSafeRegister(&xPrivateReplace, libs, "g_private_replace")
2504	core.PuregoSafeRegister(&xPrivateSet, libs, "g_private_set")
2505
2506	core.PuregoSafeRegister(&xRWLockClear, libs, "g_rw_lock_clear")
2507	core.PuregoSafeRegister(&xRWLockInit, libs, "g_rw_lock_init")
2508	core.PuregoSafeRegister(&xRWLockReaderLock, libs, "g_rw_lock_reader_lock")
2509	core.PuregoSafeRegister(&xRWLockReaderTrylock, libs, "g_rw_lock_reader_trylock")
2510	core.PuregoSafeRegister(&xRWLockReaderUnlock, libs, "g_rw_lock_reader_unlock")
2511	core.PuregoSafeRegister(&xRWLockWriterLock, libs, "g_rw_lock_writer_lock")
2512	core.PuregoSafeRegister(&xRWLockWriterTrylock, libs, "g_rw_lock_writer_trylock")
2513	core.PuregoSafeRegister(&xRWLockWriterUnlock, libs, "g_rw_lock_writer_unlock")
2514
2515	core.PuregoSafeRegister(&xRecMutexClear, libs, "g_rec_mutex_clear")
2516	core.PuregoSafeRegister(&xRecMutexInit, libs, "g_rec_mutex_init")
2517	core.PuregoSafeRegister(&xRecMutexLock, libs, "g_rec_mutex_lock")
2518	core.PuregoSafeRegister(&xRecMutexTrylock, libs, "g_rec_mutex_trylock")
2519	core.PuregoSafeRegister(&xRecMutexUnlock, libs, "g_rec_mutex_unlock")
2520
2521	core.PuregoSafeRegister(&xStaticMutexFree, libs, "g_static_mutex_free")
2522	core.PuregoSafeRegister(&xStaticMutexGetMutexImpl, libs, "g_static_mutex_get_mutex_impl")
2523	core.PuregoSafeRegister(&xStaticMutexInit, libs, "g_static_mutex_init")
2524
2525	core.PuregoSafeRegister(&xStaticPrivateFree, libs, "g_static_private_free")
2526	core.PuregoSafeRegister(&xStaticPrivateGet, libs, "g_static_private_get")
2527	core.PuregoSafeRegister(&xStaticPrivateInit, libs, "g_static_private_init")
2528	core.PuregoSafeRegister(&xStaticPrivateSet, libs, "g_static_private_set")
2529
2530	core.PuregoSafeRegister(&xStaticRWLockFree, libs, "g_static_rw_lock_free")
2531	core.PuregoSafeRegister(&xStaticRWLockInit, libs, "g_static_rw_lock_init")
2532	core.PuregoSafeRegister(&xStaticRWLockReaderLock, libs, "g_static_rw_lock_reader_lock")
2533	core.PuregoSafeRegister(&xStaticRWLockReaderTrylock, libs, "g_static_rw_lock_reader_trylock")
2534	core.PuregoSafeRegister(&xStaticRWLockReaderUnlock, libs, "g_static_rw_lock_reader_unlock")
2535	core.PuregoSafeRegister(&xStaticRWLockWriterLock, libs, "g_static_rw_lock_writer_lock")
2536	core.PuregoSafeRegister(&xStaticRWLockWriterTrylock, libs, "g_static_rw_lock_writer_trylock")
2537	core.PuregoSafeRegister(&xStaticRWLockWriterUnlock, libs, "g_static_rw_lock_writer_unlock")
2538
2539	core.PuregoSafeRegister(&xStaticRecMutexFree, libs, "g_static_rec_mutex_free")
2540	core.PuregoSafeRegister(&xStaticRecMutexInit, libs, "g_static_rec_mutex_init")
2541	core.PuregoSafeRegister(&xStaticRecMutexLock, libs, "g_static_rec_mutex_lock")
2542	core.PuregoSafeRegister(&xStaticRecMutexLockFull, libs, "g_static_rec_mutex_lock_full")
2543	core.PuregoSafeRegister(&xStaticRecMutexTrylock, libs, "g_static_rec_mutex_trylock")
2544	core.PuregoSafeRegister(&xStaticRecMutexUnlock, libs, "g_static_rec_mutex_unlock")
2545	core.PuregoSafeRegister(&xStaticRecMutexUnlockFull, libs, "g_static_rec_mutex_unlock_full")
2546
2547	core.PuregoSafeRegister(&xThreadGLibType, libs, "g_thread_get_type")
2548
2549	core.PuregoSafeRegister(&xNewThread, libs, "g_thread_new")
2550	core.PuregoSafeRegister(&xThreadTryNew, libs, "g_thread_try_new")
2551
2552	core.PuregoSafeRegister(&xThreadGetName, libs, "g_thread_get_name")
2553	core.PuregoSafeRegister(&xThreadJoin, libs, "g_thread_join")
2554	core.PuregoSafeRegister(&xThreadRef, libs, "g_thread_ref")
2555	core.PuregoSafeRegister(&xThreadSetPriority, libs, "g_thread_set_priority")
2556	core.PuregoSafeRegister(&xThreadUnref, libs, "g_thread_unref")
2557
2558}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 102

↑↓ moveenter openesc close