summaryrefslogtreecommitdiff
path: root/libs/glibmm2/glibmm/thread.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/glibmm2/glibmm/thread.cc')
-rw-r--r--libs/glibmm2/glibmm/thread.cc399
1 files changed, 399 insertions, 0 deletions
diff --git a/libs/glibmm2/glibmm/thread.cc b/libs/glibmm2/glibmm/thread.cc
new file mode 100644
index 0000000000..1910c6fa38
--- /dev/null
+++ b/libs/glibmm2/glibmm/thread.cc
@@ -0,0 +1,399 @@
+// Generated by gtkmmproc -- DO NOT MODIFY!
+
+#include <glibmm/thread.h>
+#include <glibmm/private/thread_p.h>
+
+// -*- c++ -*-
+/* $Id$ */
+
+/* Copyright (C) 2002 The gtkmm Development Team
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <glibmm/exceptionhandler.h>
+#include <glib/gmessages.h>
+
+
+namespace
+{
+
+extern "C"
+{
+
+static void* call_thread_entry_slot(void* data)
+{
+ sigc::slot_base *const slot = reinterpret_cast<sigc::slot_base*>(data);
+
+ try
+ {
+ // Recreate the specific slot, and drop the reference obtained by create().
+ (*static_cast<sigc::slot<void>*>(slot))();
+ }
+ catch(Glib::Thread::Exit&)
+ {
+ // Just exit from the thread. The Thread::Exit exception
+ // is our sane C++ replacement of g_thread_exit().
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+
+ delete slot;
+ return 0;
+}
+
+} //extern "C"
+
+} // anonymous namespace
+
+
+namespace Glib
+{
+
+// internal
+void thread_init_impl()
+{
+ // Make sure the exception map is initialized before creating any thread.
+ Glib::Error::register_init();
+}
+
+
+/**** Glib::Thread *********************************************************/
+
+// static
+Thread* Thread::create(const sigc::slot<void>& slot, bool joinable)
+{
+ // Make a copy of slot on the heap
+ sigc::slot_base *const slot_copy = new sigc::slot<void>(slot);
+
+ GError* error = 0;
+
+ GThread *const thread = g_thread_create(
+ &call_thread_entry_slot, slot_copy, joinable, &error);
+
+ if(error)
+ {
+ delete slot_copy;
+ Glib::Error::throw_exception(error);
+ }
+
+ return reinterpret_cast<Thread*>(thread);
+}
+
+// static
+Thread* Thread::create(const sigc::slot<void>& slot, unsigned long stack_size,
+ bool joinable, bool bound, ThreadPriority priority)
+{
+ // Make a copy of slot on the heap
+ sigc::slot_base *const slot_copy = new sigc::slot<void>(slot);
+
+ GError* error = 0;
+
+ GThread *const thread = g_thread_create_full(
+ &call_thread_entry_slot, slot_copy, stack_size, joinable,
+ bound, (GThreadPriority) priority, &error);
+
+ if(error)
+ {
+ delete slot_copy;
+ Glib::Error::throw_exception(error);
+ }
+
+ return reinterpret_cast<Thread*>(thread);
+}
+
+// static
+Thread* Thread::self()
+{
+ return reinterpret_cast<Thread*>(g_thread_self());
+}
+
+bool Thread::joinable() const
+{
+ return gobject_.joinable;
+}
+
+void Thread::join()
+{
+ g_thread_join(&gobject_);
+}
+
+void Thread::set_priority(ThreadPriority priority)
+{
+ g_thread_set_priority(&gobject_, (GThreadPriority) priority);
+}
+
+ThreadPriority Thread::get_priority() const
+{
+ return (ThreadPriority) gobject_.priority;
+}
+
+// static
+void Thread::yield()
+{
+ g_thread_yield();
+}
+
+Thread* wrap(GThread* gobject)
+{
+ return reinterpret_cast<Thread*>(gobject);
+}
+
+
+/**** Glib::StaticMutex ****************************************************/
+
+void StaticMutex::lock()
+{
+ g_static_mutex_lock(&gobject_);
+}
+
+bool StaticMutex::trylock()
+{
+ return g_static_mutex_trylock(&gobject_);
+}
+
+void StaticMutex::unlock()
+{
+ g_static_mutex_unlock(&gobject_);
+}
+
+StaticMutex::operator Mutex&()
+{
+ // If GStaticMutex is implemented as struct (e.g. on Linux), its first struct
+ // member (runtime_mutex) is a GMutex pointer. If the gthread implementation
+ // is native (i.e. the vtable pointer passed to g_thread_init() was 0), then
+ // the runtime_mutex pointer is unused, and the rest of the GStaticMutex
+ // struct resembles the mutex data.
+ //
+ // On Win32, GStaticMutex is just a typedef to struct _GMutex*. Either way,
+ // the first sizeof(GMutex*) bytes of GStaticMutex always resemble a GMutex
+ // pointer. The gthread implementation relies on that, and we'll also do so.
+
+ GMutex*& runtime_mutex = reinterpret_cast<GMutex*&>(gobject_);
+
+ // Fortunately, it cannot hurt if we set this to the GMutex pointer returned
+ // by g_static_mutex_get_mutex(). Either we just overwrite it with the same
+ // value, or it was unused anyway. Doing that allows casting the pointer
+ // location to a Glib::Mutex reference (its only data member is a GMutex*).
+
+ runtime_mutex = g_static_mutex_get_mutex(&gobject_);
+
+ return reinterpret_cast<Mutex&>(runtime_mutex);
+}
+
+
+/**** Glib::Mutex **********************************************************/
+
+Mutex::Mutex()
+:
+ gobject_ (g_mutex_new())
+{}
+
+Mutex::~Mutex()
+{
+ g_mutex_free(gobject_);
+}
+
+void Mutex::lock()
+{
+ g_mutex_lock(gobject_);
+}
+
+bool Mutex::trylock()
+{
+ return g_mutex_trylock(gobject_);
+}
+
+void Mutex::unlock()
+{
+ g_mutex_unlock(gobject_);
+}
+
+
+/**** Glib::StaticRecMutex *************************************************/
+
+void StaticRecMutex::lock()
+{
+ g_static_rec_mutex_lock(&gobject_);
+}
+
+bool StaticRecMutex::trylock()
+{
+ return g_static_rec_mutex_trylock(&gobject_);
+}
+
+void StaticRecMutex::unlock()
+{
+ g_static_rec_mutex_unlock(&gobject_);
+}
+
+void StaticRecMutex::lock_full(unsigned int depth)
+{
+ g_static_rec_mutex_lock_full(&gobject_, depth);
+}
+
+unsigned int StaticRecMutex::unlock_full()
+{
+ return g_static_rec_mutex_unlock_full(&gobject_);
+}
+
+StaticRecMutex::operator RecMutex&()
+{
+ return static_cast<RecMutex&>(*this);
+}
+
+
+/**** Glib::RecMutex *******************************************************/
+
+RecMutex::RecMutex()
+{
+ g_static_rec_mutex_init(&gobject_);
+
+ // GLib doesn't have GRecMutex, only GStaticRecMutex. Force initialization
+ // of the mutex now, to mimic the behaviour of a (hypothetical) GRecMutex.
+ g_static_mutex_get_mutex(&gobject_.mutex);
+}
+
+RecMutex::~RecMutex()
+{
+ g_static_rec_mutex_free(&gobject_);
+}
+
+
+/**** Glib::StaticRWLock ***************************************************/
+
+void StaticRWLock::reader_lock()
+{
+ g_static_rw_lock_reader_lock(&gobject_);
+}
+
+bool StaticRWLock::reader_trylock()
+{
+ return g_static_rw_lock_reader_trylock(&gobject_);
+}
+
+void StaticRWLock::reader_unlock()
+{
+ g_static_rw_lock_reader_unlock(&gobject_);
+}
+
+void StaticRWLock::writer_lock()
+{
+ g_static_rw_lock_writer_lock(&gobject_);
+}
+
+bool StaticRWLock::writer_trylock()
+{
+ return g_static_rw_lock_writer_trylock(&gobject_);
+}
+
+void StaticRWLock::writer_unlock()
+{
+ g_static_rw_lock_writer_unlock(&gobject_);
+}
+
+StaticRWLock::operator RWLock&()
+{
+ return static_cast<RWLock&>(*this);
+}
+
+
+/**** Glib::RWLock *********************************************************/
+
+RWLock::RWLock()
+{
+ g_static_rw_lock_init(&gobject_);
+
+ // GLib doesn't have GRWLock, only GStaticRWLock. Force initialization
+ // of the mutex and the condition variables now, to mimic the behaviour
+ // of a (hypothetical) GRWLock.
+
+ if(g_static_mutex_get_mutex(&gobject_.mutex))
+ {
+ gobject_.read_cond = g_cond_new();
+ gobject_.write_cond = g_cond_new();
+ }
+}
+
+RWLock::~RWLock()
+{
+ g_static_rw_lock_free(&gobject_);
+}
+
+
+/**** Glib::Cond ***********************************************************/
+
+Cond::Cond()
+:
+ gobject_ (g_cond_new())
+{}
+
+Cond::~Cond()
+{
+ g_cond_free(gobject_);
+}
+
+void Cond::signal()
+{
+ g_cond_signal(gobject_);
+}
+
+void Cond::broadcast()
+{
+ g_cond_broadcast(gobject_);
+}
+
+void Cond::wait(Mutex& mutex)
+{
+ g_cond_wait(gobject_, mutex.gobj());
+}
+
+bool Cond::timed_wait(Mutex& mutex, const Glib::TimeVal& abs_time)
+{
+ return g_cond_timed_wait(gobject_, mutex.gobj(), const_cast<Glib::TimeVal*>(&abs_time));
+}
+
+
+} // namespace Glib
+
+
+namespace
+{
+} // anonymous namespace
+
+
+Glib::ThreadError::ThreadError(Glib::ThreadError::Code error_code, const Glib::ustring& error_message)
+:
+ Glib::Error (G_THREAD_ERROR, error_code, error_message)
+{}
+
+Glib::ThreadError::ThreadError(GError* gobject)
+:
+ Glib::Error (gobject)
+{}
+
+Glib::ThreadError::Code Glib::ThreadError::code() const
+{
+ return static_cast<Code>(Glib::Error::code());
+}
+
+void Glib::ThreadError::throw_func(GError* gobject)
+{
+ throw Glib::ThreadError(gobject);
+}
+
+