2 // Generated by gtkmmproc -- DO NOT MODIFY!
3 #ifndef _GLIBMM_THREAD_H
4 #define _GLIBMM_THREAD_H
7 /* $Id: thread.hg,v 1.13 2005/01/21 12:48:05 murrayc Exp $ */
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 /** Specifies the priority of a thread.
74 * @note It is not guaranteed, that threads with different priorities really
75 * behave accordingly. On some systems (e.g. Linux) only <tt>root</tt> can
76 * increase priorities. On other systems (e.g. Solaris) there doesn't seem to
77 * be different scheduling for different priorities. All in all try to avoid
78 * being dependent on priorities.
80 /** @addtogroup glibmmEnums Enums and Flags */
83 * @ingroup glibmmEnums
88 THREAD_PRIORITY_NORMAL,
90 THREAD_PRIORITY_URGENT
94 /*! @var ThreadPriority THREAD_PRIORITY_LOW
95 * A priority lower than normal.
97 /*! @var ThreadPriority THREAD_PRIORITY_NORMAL
98 * The default priority.
100 /*! @var ThreadPriority THREAD_PRIORITY_HIGH
101 * A priority higher than normal.
103 /*! @var ThreadPriority THREAD_PRIORITY_URGENT
104 * The highest priority.
108 /** @defgroup Threads Threads
109 * Thread abstraction; including threads, different mutexes,
110 * conditions and thread private data.
114 enum NotLock { NOT_LOCK };
115 enum TryLock { TRY_LOCK };
117 /** Initializes the GLib thread system.
118 * Before you use a thread related function in glibmm, you should initialize
119 * the thread system. This is done by calling Glib::thread_init().
121 * @note You should only call thread_init() with a non-<tt>0</tt> parameter
122 * if you really know what you are doing.
124 * @note thread_init() must not be called directly or indirectly as
125 * a callback from glibmm. Also no mutexes may be currently locked while
126 * calling thread_init().
128 * thread_init() might only be called once. On the second call it will
129 * abort with an error. If you want to make sure that the thread system
130 * is initialized, you can do that too:
132 * if(!Glib::thread_supported()) Glib::thread_init();
134 * After that line either the thread system is initialized, or the program
135 * will abort if no thread system is available in GLib, i.e. either
136 * @c G_THREADS_ENABLED is not defined or @c G_THREADS_IMPL_NONE is defined.
138 * If no thread system is available and @a vtable is <tt>0</tt> or if not all
139 * elements of @a vtable are non-<tt>0</tt>, then thread_init() will abort.
141 * @note To use thread_init() in your program, you have to link with the
142 * libraries that the command <tt>pkg-config --libs gthread-2.0</tt>
143 * outputs. This is not the case for all the other thread related functions
144 * of glibmm. Those can be used without having to link with the thread
145 * libraries. (You @em have to link with <tt>gthread-2.0</tt> if you actually
146 * want to use threads in your application, though.)
148 * @param vtable A function table of type @c GThreadFunctions, that provides
149 * the entry points to the thread system to be used.
151 inline void thread_init(GThreadFunctions* vtable = 0);
153 /** Returns whether the thread system is initialized.
154 * @return @c true, if the thread system is initialized.
156 inline bool thread_supported();
163 struct StaticRecMutex;
167 /** Exception class for thread-related errors.
169 class ThreadError : public Glib::Error
177 ThreadError(Code error_code, const Glib::ustring& error_message);
178 explicit ThreadError(GError* gobject);
181 #ifndef DOXYGEN_SHOULD_SKIP_THIS
184 #ifdef GLIBMM_EXCEPTIONS_ENABLED
185 static void throw_func(GError* gobject);
187 //When not using exceptions, we just pass the Exception object around without throwing it:
188 static std::auto_ptr<Glib::Error> throw_func(GError* gobject);
189 #endif //GLIBMM_EXCEPTIONS_ENABLED
191 friend void wrap_init(); // uses throw_func()
196 /** Represents a running thread.
197 * An instance of this class can only be obtained with create(), self(),
198 * or wrap(GThread*). It's not possible to delete a Thread object. If the
199 * thread is @em not joinable, its resources will be freed automatically
200 * when it exits. Otherwise, if the thread @em is joinable, you must call
201 * join() to avoid a memory leak.
203 * @note g_thread_exit() is not wrapped, because that function exits a thread
204 * without any cleanup. That's especially dangerous in C++ code, since the
205 * destructors of automatic objects won't be invoked. Instead, you can throw
206 * a Thread::Exit exception, which will be caught by the internal thread
209 * @note You might have noticed that the thread entry slot doesn't have the
210 * usual void* return value. If you want to return any data from your thread
211 * you can pass an additional output argument to the thread's entry slot.
218 /** Creates a new thread with the priority <tt>THREAD_PRIORITY_NORMAL</tt>.
219 * If @a joinable is @c true, you can wait for this thread's termination by
220 * calling join(). Otherwise the thread will just disappear, when ready.
222 * The new thread executes the function or method @a slot points to. You can
223 * pass additional arguments using sigc::bind(). If the thread was created
224 * successfully, it is returned, otherwise a ThreadError exception is thrown.
226 * @param slot A slot to execute in the new thread.
227 * @param joinable Should this thread be joinable?
228 * @return The new Thread* on success.
229 * @throw Glib::ThreadError
231 static Thread* create(const sigc::slot<void>& slot, bool joinable);
233 /** Creates a new thread with the priority @a priority. The stack gets the
234 * size @a stack_size or the default value for the current platform, if
235 * @a stack_size is <tt>0</tt>.
237 * If @a joinable is @c true, you can wait for this thread's termination by
238 * calling join(). Otherwise the thread will just disappear, when ready.
239 * If @a bound is @c true, this thread will be scheduled in the system scope,
240 * otherwise the implementation is free to do scheduling in the process
241 * scope. The first variant is more expensive resource-wise, but generally
242 * faster. On some systems (e.g. Linux) all threads are bound.
244 * The new thread executes the function or method @a slot points to. You can
245 * pass additional arguments using sigc::bind(). If the thread was created
246 * successfully, it is returned.
248 * @note It is not guaranteed, that threads with different priorities really
249 * behave accordingly. On some systems (e.g. Linux) only root can increase
250 * priorities. On other systems (e.g. Solaris) there doesn't seem to be
251 * different scheduling for different priorities. All in all try to avoid
252 * being dependent on priorities. Use <tt>Glib::THREAD_PRIORITY_NORMAL</tt>
255 * @note Only use the extended
256 * create(const sigc::slot<void>&, unsigned long, bool, bool, ThreadPriority)
257 * function, when you really can't use the simple
258 * create(const sigc::slot<void>&, bool)
259 * instead. The latter overload does not take @a stack_size, @a bound and
260 * @a priority as arguments, as they should only be used for cases, where
263 * @param slot A slot to execute in the new thread.
264 * @param stack_size A stack size for the new thread, or <tt>0</tt>.
265 * @param joinable Should this thread be joinable?
266 * @param bound Should this thread be bound to a system thread?
267 * @param priority A priority for the thread.
268 * @return The new Thread* on success.
269 * @throw Glib::ThreadError
271 static Thread* create(const sigc::slot<void>& slot, unsigned long stack_size,
272 bool joinable, bool bound, ThreadPriority priority);
274 /** Returns the Thread* corresponding to the calling thread.
275 * @return The current thread.
277 static Thread* self();
279 /** Returns whether the thread is joinable.
280 * @return Whether the thread is joinable.
282 bool joinable() const;
284 /** Waits until the thread finishes.
285 * Waits until the thread finishes, i.e. the slot, as given to create(),
286 * returns or g_thread_exit() is called by the thread. (Calling
287 * g_thread_exit() in a C++ program should be avoided.) All resources of
288 * the thread including the Glib::Thread object are released. The thread
289 * must have been created with <tt>joinable = true</tt>.
293 /** Changes the priority of the thread to @a priority.
294 * @note It is not guaranteed, that threads with different priorities really
295 * behave accordingly. On some systems (e.g. Linux) only @c root can
296 * increase priorities. On other systems (e.g. Solaris) there doesn't seem
297 * to be different scheduling for different priorities. All in all try to
298 * avoid being dependent on priorities.
299 * @param priority A new priority for the thread.
301 void set_priority(ThreadPriority priority);
303 /** Returns the priority of the thread.
304 * @return The thread's priority.
306 ThreadPriority get_priority() const;
308 /** Gives way to other threads waiting to be scheduled.
309 * This function is often used as a method to make busy wait less evil. But
310 * in most cases, you will encounter, there are better methods to do that.
311 * So in general you shouldn't use this function.
315 GThread* gobj() { return &gobject_; }
316 const GThread* gobj() const { return &gobject_; }
321 // Glib::Thread can neither be constructed nor deleted.
323 void operator delete(void*, size_t);
326 Thread(const Thread&);
327 Thread& operator=(const Thread&);
330 /** %Exception class used to exit from a thread.
332 * throw Glib::Thread::Exit();
334 * Write this if you want to exit from a thread created by Thread::create().
335 * Of course you must make sure not to catch Thread::Exit by accident, i.e.
336 * when using <tt>catch(...)</tt> somewhere in your code.
341 /** @relates Glib::Thread */
342 Thread* wrap(GThread* gobject);
345 /** Like Glib::Mutex, but can be defined at compile time.
346 * Use @c GLIBMM_STATIC_MUTEX_INIT to initialize a StaticMutex:
348 * Glib::StaticMutex mutex = GLIBMM_STATIC_MUTEX_INIT;
350 * A StaticMutex can be used without calling Glib::thread_init(), it will
351 * silently do nothing then. That will also work when using the implicit
352 * conversion to Mutex&, thus you can safely use Mutex::Lock with a
363 GStaticMutex* gobj() { return &gobject_; }
365 #ifndef DOXYGEN_SHOULD_SKIP_THIS
366 // Must be public to allow initialization at compile time.
367 GStaticMutex gobject_;
371 /** Represents a mutex (mutual exclusion).
372 * It can be used to protect data against shared access. Try to use
373 * Mutex::Lock instead of calling lock() and unlock() directly --
374 * it will make your life much easier.
376 * @note Before creating a Glib::Mutex, Glib::thread_init() has to be called.
378 * @note Glib::Mutex is not recursive, i.e. a thread will deadlock, if it
379 * already has locked the mutex while calling lock(). Use Glib::RecMutex
380 * instead, if you need recursive mutexes.
391 * If mutex is already locked by another thread, the current thread will
392 * block until mutex is unlocked by the other thread.
397 /** Tries to lock the mutex.
398 * If the mutex is already locked by another thread, it immediately returns
399 * @c false. Otherwise it locks the mutex and returns @c true.
400 * @return Whether the mutex could be locked.
405 /** Unlocks the mutex.
406 * If another thread is blocked in a lock() call for this mutex, it will be
407 * woken and can lock the mutex itself.
412 GMutex* gobj() { return gobject_; }
419 Mutex& operator=(const Mutex&);
422 /** Utility class for exception-safe mutex locking.
423 * @par Usage example:
426 * Glib::Mutex::Lock lock (mutex); // calls mutex.lock()
428 * } // the destructor calls mutex.unlock()
430 * As you can see, the compiler takes care of the unlocking. This is not
431 * only exception safe but also much less error-prone. You could even
432 * <tt>return</tt> while still holding the lock and it will be released
438 explicit inline Lock(Mutex& mutex);
439 inline Lock(Mutex& mutex, NotLock);
440 inline Lock(Mutex& mutex, TryLock);
443 inline void acquire();
444 inline bool try_acquire();
445 inline void release();
446 inline bool locked() const;
453 Lock(const Mutex::Lock&);
454 Mutex::Lock& operator=(const Mutex::Lock&);
458 /** Like Glib::RecMutex, but can be defined at compile time.
459 * Use @c GLIBMM_STATIC_REC_MUTEX_INIT to initialize a StaticRecMutex:
461 * Glib::StaticRecMutex mutex = GLIBMM_STATIC_REC_MUTEX_INIT;
463 * A StaticRecMutex can be used without calling Glib::thread_init(), it will
464 * silently do nothing then. That will also work when using the implicit
465 * conversion to RecMutex&, thus you can safely use RecMutex::Lock with a
468 struct StaticRecMutex
474 void lock_full(unsigned int depth);
475 unsigned int unlock_full();
477 operator RecMutex&();
479 GStaticRecMutex* gobj() { return &gobject_; }
481 #ifndef DOXYGEN_SHOULD_SKIP_THIS
482 // Must be public to allow initialization at compile time.
483 GStaticRecMutex gobject_;
487 class RecMutex : public StaticRecMutex
497 RecMutex(const RecMutex&);
498 RecMutex& operator=(const RecMutex&);
501 /** Utility class for exception-safe locking of recursive mutexes.
506 explicit inline Lock(RecMutex& mutex);
507 inline Lock(RecMutex& mutex, NotLock);
508 inline Lock(RecMutex& mutex, TryLock);
511 inline void acquire();
512 inline bool try_acquire();
513 inline void release();
514 inline bool locked() const;
521 Lock(const RecMutex::Lock&);
522 RecMutex::Lock& operator=(const RecMutex::Lock&);
526 /** Like Glib::RWLock, but can be defined at compile time.
527 * Use @c GLIBMM_STATIC_RW_LOCK_INIT to initialize a StaticRWLock:
529 * Glib::StaticRWLock rw_lock = GLIBMM_STATIC_RW_LOCK_INIT;
531 * A StaticRWLock can be used without calling Glib::thread_init(), it will
532 * silently do nothing then. That will also work when using the implicit
533 * conversion to RWLock&, thus you can safely use RWLock::ReaderLock and
534 * RWLock::WriterLock with a StaticRWLock.
539 bool reader_trylock();
540 void reader_unlock();
543 bool writer_trylock();
544 void writer_unlock();
548 GStaticRWLock* gobj() { return &gobject_; }
550 #ifndef DOXYGEN_SHOULD_SKIP_THIS
551 // Must be public to allow initialization at compile time.
552 GStaticRWLock gobject_;
556 class RWLock : public StaticRWLock
567 RWLock(const RWLock&);
568 RWLock& operator=(const RWLock&);
571 /** Utility class for exception-safe locking of read/write locks.
573 class RWLock::ReaderLock
576 explicit inline ReaderLock(RWLock& rwlock);
577 inline ReaderLock(RWLock& rwlock, NotLock);
578 inline ReaderLock(RWLock& rwlock, TryLock);
579 inline ~ReaderLock();
581 inline void acquire();
582 inline bool try_acquire();
583 inline void release();
584 inline bool locked() const;
591 ReaderLock(const RWLock::ReaderLock&);
592 RWLock::ReaderLock& operator=(const RWLock::ReaderLock&);
595 /** Utility class for exception-safe locking of read/write locks.
597 class RWLock::WriterLock
600 explicit inline WriterLock(RWLock& rwlock);
601 inline WriterLock(RWLock& rwlock, NotLock);
602 inline WriterLock(RWLock& rwlock, TryLock);
603 inline ~WriterLock();
605 inline void acquire();
606 inline bool try_acquire();
607 inline void release();
608 inline bool locked() const;
615 WriterLock(const RWLock::WriterLock&);
616 RWLock::WriterLock& operator=(const RWLock::WriterLock&);
619 /** An opaque data structure to represent a condition.
620 * A @a Cond is an object that threads can block on, if they find a certain
621 * condition to be false. If other threads change the state of this condition
622 * they can signal the @a Cond, such that the waiting thread is woken up.
623 * @par Usage example:
625 * Glib::Cond data_cond;
626 * Glib::Mutex data_mutex;
627 * void* current_data = NULL;
629 * void push_data (void* data)
632 * current_data = data;
633 * data_cond.signal();
634 * data_mutex.unlock();
642 * while (!current_data)
643 * data_cond.wait(data_mutex);
644 * data = current_data;
645 * current_data = NULL;
646 * data_mutex.unlock();
657 /** If threads are waiting for this @a Cond, exactly one of them is 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 /** If threads are waiting for this @a Cond, all of them are woken up.
667 * It is good practice to hold the same lock as the waiting thread, while calling
668 * this method, though not required.
670 * @note This method can also be used if @a Glib::thread_init() has not yet been
671 * called and will do nothing then.
675 /** Waits until this thread is woken up on this @a Cond.
676 * The mutex is unlocked before falling asleep and locked again before resuming.
678 * This method can also be used if @a Glib::thread_init() has not yet been
679 * called and will immediately return then.
681 * @param mutex a @a Mutex that is currently locked.
683 * @note It is important to use the @a wait() and @a timed_wait() methods
684 * only inside a loop, which checks for the condition to be true as it is not
685 * guaranteed that the waiting thread will find it fulfilled, even if the signaling
686 * thread left the condition in that state. This is because another thread can have
687 * altered the condition, before the waiting thread got the chance to be woken up,
688 * even if the condition itself is protected by a @a Mutex.
690 void wait(Mutex& mutex);
692 /** 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.
693 * The mutex is unlocked before falling asleep and locked again before resuming.
695 * This function can also be used, if @a Glib::thread_init() has not yet been
696 * called and will immediately return @c true then.
698 * @param mutex a @a Mutex that is currently locked.
699 * @param abs_time a max time to wait.
701 * @note It is important to use the @a wait() and @a timed_wait() methods
702 * only inside a loop, which checks for the condition to be true as it is not
703 * guaranteed that the waiting thread will find it fulfilled, even if the signaling
704 * thread left the condition in that state. This is because another thread can have
705 * altered the condition, before the waiting thread got the chance to be woken up,
706 * even if the condition itself is protected by a @a Mutex.
708 bool timed_wait(Mutex& mutex, const Glib::TimeVal& abs_time);
710 GCond* gobj() { return gobject_; }
717 Cond& operator=(const Cond&);
724 typedef void (*DestroyNotifyFunc) (void*);
726 static void delete_ptr(void* data);
729 inline void set(T* data, DestroyNotifyFunc notify_func = &StaticPrivate<T>::delete_ptr);
731 GStaticPrivate* gobj() { return &gobject_; }
733 #ifndef DOXYGEN_SHOULD_SKIP_THIS
734 // Must be public to allow initialization at compile time.
735 GStaticPrivate gobject_;
743 typedef void (*DestructorFunc) (void*);
745 static void delete_ptr(void* data);
747 explicit inline Private(DestructorFunc destructor_func = &Private<T>::delete_ptr);
749 inline void set(T* data);
751 GPrivate* gobj() { return gobject_; }
757 Private(const Private<T>&);
758 Private<T>& operator=(const Private<T>&);
761 /** @} group Threads */
763 /*! A glibmm thread example.
764 * @example thread/thread.cc
768 #ifndef DOXYGEN_SHOULD_SKIP_THIS
770 /***************************************************************************/
771 /* inline implementation */
772 /***************************************************************************/
775 void thread_init_impl();
777 /* This function must be inline, to avoid an unnecessary dependency on
778 * libgthread even if the thread system is not used. libgthread might
779 * not even be available if GLib was compiled without thread support.
782 void thread_init(GThreadFunctions* vtable)
784 g_thread_init(vtable);
785 Glib::thread_init_impl();
789 bool thread_supported()
791 //MSVC++ needs the != 0 to avoid an int -> bool cast warning.
792 return (g_thread_supported() != 0);
796 /**** Glib::Mutex::Lock ****************************************************/
799 Mutex::Lock::Lock(Mutex& mutex)
808 Mutex::Lock::Lock(Mutex& mutex, NotLock)
815 Mutex::Lock::Lock(Mutex& mutex, TryLock)
818 locked_ (mutex.trylock())
829 void Mutex::Lock::acquire()
836 bool Mutex::Lock::try_acquire()
838 locked_ = mutex_.trylock();
843 void Mutex::Lock::release()
850 bool Mutex::Lock::locked() const
856 /**** Glib::RecMutex::Lock *************************************************/
859 RecMutex::Lock::Lock(RecMutex& mutex)
868 RecMutex::Lock::Lock(RecMutex& mutex, NotLock)
875 RecMutex::Lock::Lock(RecMutex& mutex, TryLock)
878 locked_ (mutex.trylock())
882 RecMutex::Lock::~Lock()
889 void RecMutex::Lock::acquire()
896 bool RecMutex::Lock::try_acquire()
898 locked_ = mutex_.trylock();
903 void RecMutex::Lock::release()
910 bool RecMutex::Lock::locked() const
916 /**** Glib::RWLock::ReaderLock *********************************************/
919 RWLock::ReaderLock::ReaderLock(RWLock& rwlock)
924 rwlock_.reader_lock();
928 RWLock::ReaderLock::ReaderLock(RWLock& rwlock, NotLock)
935 RWLock::ReaderLock::ReaderLock(RWLock& rwlock, TryLock)
938 locked_ (rwlock.reader_trylock())
942 RWLock::ReaderLock::~ReaderLock()
945 rwlock_.reader_unlock();
949 void RWLock::ReaderLock::acquire()
951 rwlock_.reader_lock();
956 bool RWLock::ReaderLock::try_acquire()
958 locked_ = rwlock_.reader_trylock();
963 void RWLock::ReaderLock::release()
965 rwlock_.reader_unlock();
970 bool RWLock::ReaderLock::locked() const
976 /**** Glib::RWLock::WriterLock *********************************************/
979 RWLock::WriterLock::WriterLock(RWLock& rwlock)
984 rwlock_.writer_lock();
988 RWLock::WriterLock::WriterLock(RWLock& rwlock, NotLock)
995 RWLock::WriterLock::WriterLock(RWLock& rwlock, TryLock)
998 locked_ (rwlock.writer_trylock())
1002 RWLock::WriterLock::~WriterLock()
1005 rwlock_.writer_unlock();
1009 void RWLock::WriterLock::acquire()
1011 rwlock_.writer_lock();
1016 bool RWLock::WriterLock::try_acquire()
1018 locked_ = rwlock_.writer_trylock();
1023 void RWLock::WriterLock::release()
1025 rwlock_.writer_unlock();
1030 bool RWLock::WriterLock::locked() const
1036 /**** Glib::StaticPrivate **************************************************/
1040 void StaticPrivate<T>::delete_ptr(void* data)
1042 delete static_cast<T*>(data);
1045 template <class T> inline
1046 T* StaticPrivate<T>::get()
1048 return static_cast<T*>(g_static_private_get(&gobject_));
1051 template <class T> inline
1052 void StaticPrivate<T>::set(T* data, typename StaticPrivate<T>::DestroyNotifyFunc notify_func)
1054 g_static_private_set(&gobject_, data, notify_func);
1058 /**** Glib::Private ********************************************************/
1062 void Private<T>::delete_ptr(void* data)
1064 delete static_cast<T*>(data);
1067 template <class T> inline
1068 Private<T>::Private(typename Private<T>::DestructorFunc destructor_func)
1070 gobject_ (g_private_new(destructor_func))
1073 template <class T> inline
1074 T* Private<T>::get()
1076 return static_cast<T*>(g_private_get(gobject_));
1079 template <class T> inline
1080 void Private<T>::set(T* data)
1082 g_private_set(gobject_, data);
1085 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
1090 #endif /* _GLIBMM_THREAD_H */