2
// Generated by gtkmmproc -- DO NOT MODIFY!
3
#ifndef _GLIBMM_THREAD_H
4
#define _GLIBMM_THREAD_H
9
/* Copyright (C) 2002 The gtkmm Development Team
11
* This library is free software; you can redistribute it and/or
12
* modify it under the terms of the GNU Library General Public
13
* License as published by the Free Software Foundation; either
14
* version 2 of the License, or (at your option) any later version.
16
* This library is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
* Library General Public License for more details.
21
* You should have received a copy of the GNU Library General Public
22
* License along with this library; if not, write to the Free
23
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
#include <glib/gthread.h>
30
#include <sigc++/sigc++.h>
31
#include <glibmm/error.h>
32
#include <glibmm/timeval.h>
34
/* Shadow THREAD_PRIORITY_NORMAL macro (from winbase.h).
36
#if defined(THREAD_PRIORITY_NORMAL) && !defined(GLIBMM_MACRO_SHADOW_THREAD_PRIORITY_NORMAL)
37
enum { GLIBMM_MACRO_DEFINITION_THREAD_PRIORITY_NORMAL = THREAD_PRIORITY_NORMAL };
38
#undef THREAD_PRIORITY_NORMAL
39
enum { THREAD_PRIORITY_NORMAL = GLIBMM_MACRO_DEFINITION_THREAD_PRIORITY_NORMAL };
40
#define THREAD_PRIORITY_NORMAL THREAD_PRIORITY_NORMAL
41
#define GLIBMM_MACRO_SHADOW_THREAD_PRIORITY_NORMAL 1
45
/** Initializer macro for Glib::StaticMutex.
46
* @relates Glib::StaticMutex
49
#define GLIBMM_STATIC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
51
/** Initializer macro for Glib::StaticRecMutex.
52
* @relates Glib::StaticRecMutex
55
#define GLIBMM_STATIC_REC_MUTEX_INIT { G_STATIC_REC_MUTEX_INIT }
57
/** Initializer macro for Glib::StaticRWLock.
58
* @relates Glib::StaticRWLock
61
#define GLIBMM_STATIC_RW_LOCK_INIT { G_STATIC_RW_LOCK_INIT }
63
/** Initializer macro for Glib::StaticPrivate.
64
* @relates Glib::StaticPrivate
67
#define GLIBMM_STATIC_PRIVATE_INIT { G_STATIC_PRIVATE_INIT }
73
/** @addtogroup glibmmEnums Enums and Flags */
75
/** Specifies the priority of a thread.
76
* @note It is not guaranteed, that threads with different priorities really
77
* behave accordingly. On some systems (e.g. Linux) only <tt>root</tt> can
78
* increase priorities. On other systems (e.g. Solaris) there doesn't seem to
79
* be different scheduling for different priorities. All in all try to avoid
80
* being dependent on priorities.
81
* @ingroup glibmmEnums
86
THREAD_PRIORITY_NORMAL,
88
THREAD_PRIORITY_URGENT
92
/*! @var ThreadPriority THREAD_PRIORITY_LOW
93
* A priority lower than normal.
95
/*! @var ThreadPriority THREAD_PRIORITY_NORMAL
96
* The default priority.
98
/*! @var ThreadPriority THREAD_PRIORITY_HIGH
99
* A priority higher than normal.
101
/*! @var ThreadPriority THREAD_PRIORITY_URGENT
102
* The highest priority.
106
/** @defgroup Threads Threads
107
* Thread abstraction; including threads, different mutexes,
108
* conditions and thread private data.
112
enum NotLock { NOT_LOCK };
113
enum TryLock { TRY_LOCK };
115
/** Initializes the GLib thread system.
116
* Before you use a thread related function in glibmm, you should initialize
117
* the thread system. This is done by calling Glib::thread_init().
119
* @note You should only call thread_init() with a non-<tt>0</tt> parameter
120
* if you really know what you are doing.
122
* @note thread_init() must not be called directly or indirectly as
123
* a callback from glibmm. Also no mutexes may be currently locked while
124
* calling thread_init().
126
* thread_init() might only be called once. On the second call it will
127
* abort with an error. If you want to make sure that the thread system
128
* is initialized, you can do that too:
130
* if(!Glib::thread_supported()) Glib::thread_init();
132
* After that line either the thread system is initialized, or the program
133
* will abort if no thread system is available in GLib, i.e. either
134
* @c G_THREADS_ENABLED is not defined or @c G_THREADS_IMPL_NONE is defined.
136
* If no thread system is available and @a vtable is <tt>0</tt> or if not all
137
* elements of @a vtable are non-<tt>0</tt>, then thread_init() will abort.
139
* @note To use thread_init() in your program, you have to link with the
140
* libraries that the command <tt>pkg-config --libs gthread-2.0</tt>
141
* outputs. This is not the case for all the other thread related functions
142
* of glibmm. Those can be used without having to link with the thread
143
* libraries. (You @em have to link with <tt>gthread-2.0</tt> if you actually
144
* want to use threads in your application, though.)
146
* @param vtable A function table of type @c GThreadFunctions, that provides
147
* the entry points to the thread system to be used.
149
inline void thread_init(GThreadFunctions* vtable = 0);
151
/** Returns whether the thread system is initialized.
152
* @return @c true, if the thread system is initialized.
154
inline bool thread_supported();
161
struct StaticRecMutex;
165
/** Exception class for thread-related errors.
167
class ThreadError : public Glib::Error
175
ThreadError(Code error_code, const Glib::ustring& error_message);
176
explicit ThreadError(GError* gobject);
179
#ifndef DOXYGEN_SHOULD_SKIP_THIS
181
static void throw_func(GError* gobject);
182
friend void wrap_init(); // uses throw_func()
187
/** Represents a running thread.
188
* An instance of this class can only be obtained with create(), self(),
189
* or wrap(GThread*). It's not possible to delete a Thread object. If the
190
* thread is @em not joinable, its resources will be freed automatically
191
* when it exits. Otherwise, if the thread @em is joinable, you must call
192
* join() to avoid a memory leak.
194
* @note g_thread_exit() is not wrapped, because that function exits a thread
195
* without any cleanup. That's especially dangerous in C++ code, since the
196
* destructors of automatic objects won't be invoked. Instead, you can throw
197
* a Thread::Exit exception, which will be caught by the internal thread
200
* @note You might have noticed that the thread entry slot doesn't have the
201
* usual void* return value. If you want to return any data from your thread
202
* you can pass an additional output argument to the thread's entry slot.
209
/** Creates a new thread with the priority <tt>THREAD_PRIORITY_NORMAL</tt>.
210
* If @a joinable is @c true, you can wait for this thread's termination by
211
* calling join(). Otherwise the thread will just disappear, when ready.
213
* The new thread executes the function or method @a slot points to. You can
214
* pass additional arguments using sigc::bind(). If the thread was created
215
* successfully, it is returned, otherwise a ThreadError exception is thrown.
217
* @param slot A slot to execute in the new thread.
218
* @param joinable Should this thread be joinable?
219
* @return The new Thread* on success.
220
* @throw Glib::ThreadError
222
static Thread* create(const sigc::slot<void>& slot, bool joinable);
224
/** Creates a new thread with the priority @a priority. The stack gets the
225
* size @a stack_size or the default value for the current platform, if
226
* @a stack_size is <tt>0</tt>.
228
* If @a joinable is @c true, you can wait for this thread's termination by
229
* calling join(). Otherwise the thread will just disappear, when ready.
230
* If @a bound is @c true, this thread will be scheduled in the system scope,
231
* otherwise the implementation is free to do scheduling in the process
232
* scope. The first variant is more expensive resource-wise, but generally
233
* faster. On some systems (e.g. Linux) all threads are bound.
235
* The new thread executes the function or method @a slot points to. You can
236
* pass additional arguments using sigc::bind(). If the thread was created
237
* successfully, it is returned.
239
* @note It is not guaranteed, that threads with different priorities really
240
* behave accordingly. On some systems (e.g. Linux) only root can increase
241
* priorities. On other systems (e.g. Solaris) there doesn't seem to be
242
* different scheduling for different priorities. All in all try to avoid
243
* being dependent on priorities. Use <tt>Glib::THREAD_PRIORITY_NORMAL</tt>
246
* @note Only use the extended
247
* create(const sigc::slot<void>&, unsigned long, bool, bool, ThreadPriority)
248
* function, when you really can't use the simple
249
* create(const sigc::slot<void>&, bool)
250
* instead. The latter overload does not take @a stack_size, @a bound and
251
* @a priority as arguments, as they should only be used for cases, where
254
* @param slot A slot to execute in the new thread.
255
* @param stack_size A stack size for the new thread, or <tt>0</tt>.
256
* @param joinable Should this thread be joinable?
257
* @param bound Should this thread be bound to a system thread?
258
* @param priority A priority for the thread.
259
* @return The new Thread* on success.
260
* @throw Glib::ThreadError
262
static Thread* create(const sigc::slot<void>& slot, unsigned long stack_size,
263
bool joinable, bool bound, ThreadPriority priority);
265
/** Returns the Thread* corresponding to the calling thread.
266
* @return The current thread.
268
static Thread* self();
270
/** Returns whether the thread is joinable.
271
* @return Whether the thread is joinable.
273
bool joinable() const;
275
/** Waits until the thread finishes.
276
* Waits until the thread finishes, i.e. the slot, as given to create(),
277
* returns or g_thread_exit() is called by the thread. (Calling
278
* g_thread_exit() in a C++ program should be avoided.) All resources of
279
* the thread including the Glib::Thread object are released. The thread
280
* must have been created with <tt>joinable = true</tt>.
284
/** Changes the priority of the thread to @a priority.
285
* @note It is not guaranteed, that threads with different priorities really
286
* behave accordingly. On some systems (e.g. Linux) only @c root can
287
* increase priorities. On other systems (e.g. Solaris) there doesn't seem
288
* to be different scheduling for different priorities. All in all try to
289
* avoid being dependent on priorities.
290
* @param priority A new priority for the thread.
292
void set_priority(ThreadPriority priority);
294
/** Returns the priority of the thread.
295
* @return The thread's priority.
297
ThreadPriority get_priority() const;
299
/** Gives way to other threads waiting to be scheduled.
300
* This function is often used as a method to make busy wait less evil. But
301
* in most cases, you will encounter, there are better methods to do that.
302
* So in general you shouldn't use this function.
306
GThread* gobj() { return &gobject_; }
307
const GThread* gobj() const { return &gobject_; }
312
// Glib::Thread can neither be constructed nor deleted.
314
void operator delete(void*, size_t);
317
Thread(const Thread&);
318
Thread& operator=(const Thread&);
321
/** %Exception class used to exit from a thread.
323
* throw Glib::Thread::Exit();
325
* Write this if you want to exit from a thread created by Thread::create().
326
* Of course you must make sure not to catch Thread::Exit by accident, i.e.
327
* when using <tt>catch(...)</tt> somewhere in your code.
332
/** @relates Glib::Thread */
333
Thread* wrap(GThread* gobject);
336
/** Like Glib::Mutex, but can be defined at compile time.
337
* Use @c GLIBMM_STATIC_MUTEX_INIT to initialize a StaticMutex:
339
* Glib::StaticMutex mutex = GLIBMM_STATIC_MUTEX_INIT;
341
* A StaticMutex can be used without calling Glib::thread_init(), it will
342
* silently do nothing then. That will also work when using the implicit
343
* conversion to Mutex&, thus you can safely use Mutex::Lock with a
354
GStaticMutex* gobj() { return &gobject_; }
356
#ifndef DOXYGEN_SHOULD_SKIP_THIS
357
// Must be public to allow initialization at compile time.
358
GStaticMutex gobject_;
362
/** Represents a mutex (mutual exclusion).
363
* It can be used to protect data against shared access. Try to use
364
* Mutex::Lock instead of calling lock() and unlock() directly --
365
* it will make your life much easier.
367
* @note Before creating a Glib::Mutex, Glib::thread_init() has to be called.
369
* @note Glib::Mutex is not recursive, i.e. a thread will deadlock, if it
370
* already has locked the mutex while calling lock(). Use Glib::RecMutex
371
* instead, if you need recursive mutexes.
382
* If mutex is already locked by another thread, the current thread will
383
* block until mutex is unlocked by the other thread.
388
/** Tries to lock the mutex.
389
* If the mutex is already locked by another thread, it immediately returns
390
* @c false. Otherwise it locks the mutex and returns @c true.
391
* @return Whether the mutex could be locked.
396
/** Unlocks the mutex.
397
* If another thread is blocked in a lock() call for this mutex, it will be
398
* woken and can lock the mutex itself.
403
GMutex* gobj() { return gobject_; }
410
Mutex& operator=(const Mutex&);
413
/** Utility class for exception-safe mutex locking.
414
* @par Usage example:
417
* Glib::Mutex::Lock lock (mutex); // calls mutex.lock()
419
* } // the destructor calls mutex.unlock()
421
* As you can see, the compiler takes care of the unlocking. This is not
422
* only exception safe but also much less error-prone. You could even
423
* <tt>return</tt> while still holding the lock and it will be released
429
explicit inline Lock(Mutex& mutex);
430
inline Lock(Mutex& mutex, NotLock);
431
inline Lock(Mutex& mutex, TryLock);
434
inline void acquire();
435
inline bool try_acquire();
436
inline void release();
437
inline bool locked() const;
444
Lock(const Mutex::Lock&);
445
Mutex::Lock& operator=(const Mutex::Lock&);
449
/** Like Glib::RecMutex, but can be defined at compile time.
450
* Use @c GLIBMM_STATIC_REC_MUTEX_INIT to initialize a StaticRecMutex:
452
* Glib::StaticRecMutex mutex = GLIBMM_STATIC_REC_MUTEX_INIT;
454
* A StaticRecMutex can be used without calling Glib::thread_init(), it will
455
* silently do nothing then. That will also work when using the implicit
456
* conversion to RecMutex&, thus you can safely use RecMutex::Lock with a
459
struct StaticRecMutex
465
void lock_full(unsigned int depth);
466
unsigned int unlock_full();
468
operator RecMutex&();
470
GStaticRecMutex* gobj() { return &gobject_; }
472
#ifndef DOXYGEN_SHOULD_SKIP_THIS
473
// Must be public to allow initialization at compile time.
474
GStaticRecMutex gobject_;
478
class RecMutex : public StaticRecMutex
488
RecMutex(const RecMutex&);
489
RecMutex& operator=(const RecMutex&);
492
/** Utility class for exception-safe locking of recursive mutexes.
497
explicit inline Lock(RecMutex& mutex);
498
inline Lock(RecMutex& mutex, NotLock);
499
inline Lock(RecMutex& mutex, TryLock);
502
inline void acquire();
503
inline bool try_acquire();
504
inline void release();
505
inline bool locked() const;
512
Lock(const RecMutex::Lock&);
513
RecMutex::Lock& operator=(const RecMutex::Lock&);
517
/** Like Glib::RWLock, but can be defined at compile time.
518
* Use @c GLIBMM_STATIC_RW_LOCK_INIT to initialize a StaticRWLock:
520
* Glib::StaticRWLock rw_lock = GLIBMM_STATIC_RW_LOCK_INIT;
522
* A StaticRWLock can be used without calling Glib::thread_init(), it will
523
* silently do nothing then. That will also work when using the implicit
524
* conversion to RWLock&, thus you can safely use RWLock::ReaderLock and
525
* RWLock::WriterLock with a StaticRWLock.
530
bool reader_trylock();
531
void reader_unlock();
534
bool writer_trylock();
535
void writer_unlock();
539
GStaticRWLock* gobj() { return &gobject_; }
541
#ifndef DOXYGEN_SHOULD_SKIP_THIS
542
// Must be public to allow initialization at compile time.
543
GStaticRWLock gobject_;
547
class RWLock : public StaticRWLock
558
RWLock(const RWLock&);
559
RWLock& operator=(const RWLock&);
562
/** Utility class for exception-safe locking of read/write locks.
564
class RWLock::ReaderLock
567
explicit inline ReaderLock(RWLock& rwlock);
568
inline ReaderLock(RWLock& rwlock, NotLock);
569
inline ReaderLock(RWLock& rwlock, TryLock);
570
inline ~ReaderLock();
572
inline void acquire();
573
inline bool try_acquire();
574
inline void release();
575
inline bool locked() const;
582
ReaderLock(const RWLock::ReaderLock&);
583
RWLock::ReaderLock& operator=(const RWLock::ReaderLock&);
586
/** Utility class for exception-safe locking of read/write locks.
588
class RWLock::WriterLock
591
explicit inline WriterLock(RWLock& rwlock);
592
inline WriterLock(RWLock& rwlock, NotLock);
593
inline WriterLock(RWLock& rwlock, TryLock);
594
inline ~WriterLock();
596
inline void acquire();
597
inline bool try_acquire();
598
inline void release();
599
inline bool locked() const;
606
WriterLock(const RWLock::WriterLock&);
607
RWLock::WriterLock& operator=(const RWLock::WriterLock&);
610
/** An opaque data structure to represent a condition.
611
* A @a Cond is an object that threads can block on, if they find a certain
612
* condition to be false. If other threads change the state of this condition
613
* they can signal the @a Cond, such that the waiting thread is woken up.
614
* @par Usage example:
616
* Glib::Cond data_cond;
617
* Glib::Mutex data_mutex;
618
* void* current_data = NULL;
620
* void push_data (void* data)
623
* current_data = data;
624
* data_cond.signal();
625
* data_mutex.unlock();
633
* while (!current_data)
634
* data_cond.wait(data_mutex);
635
* data = current_data;
636
* current_data = NULL;
637
* data_mutex.unlock();
648
/** If threads are waiting for this @a Cond, exactly one of them is woken up.
649
* It is good practice to hold the same lock as the waiting thread, while calling
650
* this method, though not required.
652
* @note This method can also be used if @a Glib::thread_init() has not yet been
653
* called and will do nothing then.
657
/** If threads are waiting for this @a Cond, all of them are woken up.
658
* It is good practice to hold the same lock as the waiting thread, while calling
659
* this method, though not required.
661
* @note This method can also be used if @a Glib::thread_init() has not yet been
662
* called and will do nothing then.
666
/** Waits until this thread is woken up on this @a Cond.
667
* The mutex is unlocked before falling asleep and locked again before resuming.
669
* This method can also be used if @a Glib::thread_init() has not yet been
670
* called and will immediately return then.
672
* @param mutex a @a Mutex that is currently locked.
674
* @note It is important to use the @a wait() and @a timed_wait() methods
675
* only inside a loop, which checks for the condition to be true as it is not
676
* guaranteed that the waiting thread will find it fulfilled, even if the signaling
677
* thread left the condition in that state. This is because another thread can have
678
* altered the condition, before the waiting thread got the chance to be woken up,
679
* even if the condition itself is protected by a @a Mutex.
681
void wait(Mutex& mutex);
683
/** Waits until this thread is woken up on this @a Cond, but not longer than until the time, that is specified by @a abs_time.
684
* The mutex is unlocked before falling asleep and locked again before resuming.
686
* This function can also be used, if @a Glib::thread_init() has not yet been
687
* called and will immediately return @c true then.
689
* @param mutex a @a Mutex that is currently locked.
690
* @param abs_time a max time to wait.
692
* @note It is important to use the @a wait() and @a timed_wait() methods
693
* only inside a loop, which checks for the condition to be true as it is not
694
* guaranteed that the waiting thread will find it fulfilled, even if the signaling
695
* thread left the condition in that state. This is because another thread can have
696
* altered the condition, before the waiting thread got the chance to be woken up,
697
* even if the condition itself is protected by a @a Mutex.
699
bool timed_wait(Mutex& mutex, const Glib::TimeVal& abs_time);
701
GCond* gobj() { return gobject_; }
708
Cond& operator=(const Cond&);
715
typedef void (*DestroyNotifyFunc) (void*);
717
static void delete_ptr(void* data);
720
inline void set(T* data, DestroyNotifyFunc notify_func = &StaticPrivate<T>::delete_ptr);
722
GStaticPrivate* gobj() { return &gobject_; }
724
#ifndef DOXYGEN_SHOULD_SKIP_THIS
725
// Must be public to allow initialization at compile time.
726
GStaticPrivate gobject_;
734
typedef void (*DestructorFunc) (void*);
736
static void delete_ptr(void* data);
738
explicit inline Private(DestructorFunc destructor_func = &Private<T>::delete_ptr);
740
inline void set(T* data);
742
GPrivate* gobj() { return gobject_; }
748
Private(const Private<T>&);
749
Private<T>& operator=(const Private<T>&);
752
/** @} group Threads */
754
/*! A glibmm thread example.
755
* @example thread/thread.cc
759
#ifndef DOXYGEN_SHOULD_SKIP_THIS
761
/***************************************************************************/
762
/* inline implementation */
763
/***************************************************************************/
766
void thread_init_impl();
768
/* This function must be inline, to avoid an unnecessary dependency on
769
* libgthread even if the thread system is not used. libgthread might
770
* not even be available if GLib was compiled without thread support.
773
void thread_init(GThreadFunctions* vtable)
775
g_thread_init(vtable);
776
Glib::thread_init_impl();
780
bool thread_supported()
782
//MSVC++ needs the != 0 to avoid an int -> bool cast warning.
783
return (g_thread_supported() != 0);
787
/**** Glib::Mutex::Lock ****************************************************/
790
Mutex::Lock::Lock(Mutex& mutex)
799
Mutex::Lock::Lock(Mutex& mutex, NotLock)
806
Mutex::Lock::Lock(Mutex& mutex, TryLock)
809
locked_ (mutex.trylock())
820
void Mutex::Lock::acquire()
827
bool Mutex::Lock::try_acquire()
829
locked_ = mutex_.trylock();
834
void Mutex::Lock::release()
841
bool Mutex::Lock::locked() const
847
/**** Glib::RecMutex::Lock *************************************************/
850
RecMutex::Lock::Lock(RecMutex& mutex)
859
RecMutex::Lock::Lock(RecMutex& mutex, NotLock)
866
RecMutex::Lock::Lock(RecMutex& mutex, TryLock)
869
locked_ (mutex.trylock())
873
RecMutex::Lock::~Lock()
880
void RecMutex::Lock::acquire()
887
bool RecMutex::Lock::try_acquire()
889
locked_ = mutex_.trylock();
894
void RecMutex::Lock::release()
901
bool RecMutex::Lock::locked() const
907
/**** Glib::RWLock::ReaderLock *********************************************/
910
RWLock::ReaderLock::ReaderLock(RWLock& rwlock)
915
rwlock_.reader_lock();
919
RWLock::ReaderLock::ReaderLock(RWLock& rwlock, NotLock)
926
RWLock::ReaderLock::ReaderLock(RWLock& rwlock, TryLock)
929
locked_ (rwlock.reader_trylock())
933
RWLock::ReaderLock::~ReaderLock()
936
rwlock_.reader_unlock();
940
void RWLock::ReaderLock::acquire()
942
rwlock_.reader_lock();
947
bool RWLock::ReaderLock::try_acquire()
949
locked_ = rwlock_.reader_trylock();
954
void RWLock::ReaderLock::release()
956
rwlock_.reader_unlock();
961
bool RWLock::ReaderLock::locked() const
967
/**** Glib::RWLock::WriterLock *********************************************/
970
RWLock::WriterLock::WriterLock(RWLock& rwlock)
975
rwlock_.writer_lock();
979
RWLock::WriterLock::WriterLock(RWLock& rwlock, NotLock)
986
RWLock::WriterLock::WriterLock(RWLock& rwlock, TryLock)
989
locked_ (rwlock.writer_trylock())
993
RWLock::WriterLock::~WriterLock()
996
rwlock_.writer_unlock();
1000
void RWLock::WriterLock::acquire()
1002
rwlock_.writer_lock();
1007
bool RWLock::WriterLock::try_acquire()
1009
locked_ = rwlock_.writer_trylock();
1014
void RWLock::WriterLock::release()
1016
rwlock_.writer_unlock();
1021
bool RWLock::WriterLock::locked() const
1027
/**** Glib::StaticPrivate **************************************************/
1031
void StaticPrivate<T>::delete_ptr(void* data)
1033
delete static_cast<T*>(data);
1036
template <class T> inline
1037
T* StaticPrivate<T>::get()
1039
return static_cast<T*>(g_static_private_get(&gobject_));
1042
template <class T> inline
1043
void StaticPrivate<T>::set(T* data, typename StaticPrivate<T>::DestroyNotifyFunc notify_func)
1045
g_static_private_set(&gobject_, data, notify_func);
1049
/**** Glib::Private ********************************************************/
1053
void Private<T>::delete_ptr(void* data)
1055
delete static_cast<T*>(data);
1058
template <class T> inline
1059
Private<T>::Private(typename Private<T>::DestructorFunc destructor_func)
1061
gobject_ (g_private_new(destructor_func))
1064
template <class T> inline
1065
T* Private<T>::get()
1067
return static_cast<T*>(g_private_get(gobject_));
1070
template <class T> inline
1071
void Private<T>::set(T* data)
1073
g_private_set(gobject_, data);
1076
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
1081
#endif /* _GLIBMM_THREAD_H */