summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMurray Cumming <murrayc@murrayc.com>2016-11-10 13:26:00 +0100
committerMurray Cumming <murrayc@murrayc.com>2016-11-14 10:43:21 +0100
commitdb75f338fb1865fbec12daae64dac4d0a1b9abf8 (patch)
treee502ea0b726f1dccd35c90660aab43d3b283e045
parent53ceee1d8f4967d4fc3a9ece73a8a273583aae5e (diff)
downloadglibmm-db75f338fb1865fbec12daae64dac4d0a1b9abf8.tar.gz
Remove deprecated Thread and Threads API.
-rw-r--r--examples/Makefile.am6
-rw-r--r--examples/thread/thread.cc126
-rw-r--r--examples/thread/threadpool.cc68
-rw-r--r--glib/glibmm.h7
-rw-r--r--glib/glibmm/dispatcher.cc28
-rw-r--r--glib/glibmm/exceptionhandler.cc19
-rw-r--r--glib/glibmm/filelist.am2
-rw-r--r--glib/glibmm/main.cc21
-rw-r--r--glib/glibmm/main.h51
-rw-r--r--glib/glibmm/threadpool.cc255
-rw-r--r--glib/glibmm/threadpool.h200
-rw-r--r--glib/src/filelist.am2
-rw-r--r--glib/src/thread.ccg427
-rw-r--r--glib/src/thread.hg1085
-rw-r--r--glib/src/threads.ccg302
-rw-r--r--glib/src/threads.hg932
16 files changed, 1 insertions, 3530 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 0de871a7..885552d5 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -32,11 +32,7 @@ check_PROGRAMS = \
options/example \
properties/example \
regex/example \
- settings/settings \
- thread/dispatcher \
- thread/dispatcher2 \
- thread/thread \
- thread/threadpool
+ settings/settings
glibmm_includes = -I$(top_builddir)/glib $(if $(srcdir:.=),-I$(top_srcdir)/glib)
giomm_includes = -I$(top_builddir)/gio $(if $(srcdir:.=),-I$(top_srcdir)/gio)
diff --git a/examples/thread/thread.cc b/examples/thread/thread.cc
deleted file mode 100644
index 7af27350..00000000
--- a/examples/thread/thread.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-
-#include <condition_variable>
-#include <iostream>
-#include <memory>
-#include <mutex>
-#include <queue>
-#include <thread>
-#if defined(_MSC_VER) && (_MSC_VER < 1900)
-/* For using noexcept on Visual Studio 2013 */
-#include <glibmmconfig.h>
-#endif
-#include <glibmm/init.h>
-#include <glibmm/random.h>
-#include <glibmm/timer.h>
-
-namespace
-{
-
-class MessageQueue
-{
-public:
- MessageQueue();
- ~MessageQueue();
-
- void producer();
- void consumer();
-
-private:
- std::mutex mutex_;
- std::condition_variable cond_push_;
- std::condition_variable cond_pop_;
- std::queue<int> queue_;
-};
-
-MessageQueue::MessageQueue()
-{
-}
-
-MessageQueue::~MessageQueue()
-{
-}
-
-void
-MessageQueue::producer()
-{
- Glib::Rand rand(1234);
-
- for (auto i = 0; i < 200; ++i)
- {
- {
- std::unique_lock<std::mutex> lock(mutex_);
-
- cond_pop_.wait(lock, [this]() -> bool { return queue_.size() < 64; });
-
- queue_.push(i);
- std::cout << '*';
- std::cout.flush();
-
- // We unlock before notifying, because that is what the documentation suggests:
- // http://en.cppreference.com/w/cpp/thread/condition_variable
- lock.unlock();
- cond_push_.notify_one();
- }
-
- if (rand.get_bool())
- continue;
-
- Glib::usleep(rand.get_int_range(0, 100000));
- }
-}
-
-void
-MessageQueue::consumer()
-{
- Glib::Rand rand(4567);
-
- for (;;)
- {
- {
- std::unique_lock<std::mutex> lock(mutex_);
-
- cond_push_.wait(lock, [this]() -> bool { return !queue_.empty(); });
-
- const int i = queue_.front();
- queue_.pop();
- std::cout << "\x08 \x08";
- std::cout.flush();
-
- // We unlock before notifying, because that is what the documentation suggests:
- // http://en.cppreference.com/w/cpp/thread/condition_variable
- lock.unlock();
- cond_pop_.notify_one();
-
- if (i >= 199)
- break;
- }
-
- if (rand.get_bool())
- continue;
-
- Glib::usleep(rand.get_int_range(10000, 200000));
- }
-}
-}
-
-int
-main(int, char**)
-{
- Glib::init();
-
- MessageQueue queue;
-
- // TODO: Use std::make_unique() when we use C++14:
- const auto producer =
- std::unique_ptr<std::thread>(new std::thread(&MessageQueue::producer, &queue));
-
- const auto consumer =
- std::unique_ptr<std::thread>(new std::thread(&MessageQueue::consumer, &queue));
-
- producer->join();
- consumer->join();
-
- std::cout << std::endl;
-
- return 0;
-}
diff --git a/examples/thread/threadpool.cc b/examples/thread/threadpool.cc
deleted file mode 100644
index 885962bc..00000000
--- a/examples/thread/threadpool.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-
-#include <iostream>
-#include <mutex>
-#include <thread>
-
-// TODO: Remove this example sometime. Glib::ThreadPool is deprecated.
-// TODO: Maybe use std::async() instead?
-#undef GLIBMM_DISABLE_DEPRECATED
-
-#include <glibmmconfig.h>
-
-#ifdef GLIBMM_DISABLE_DEPRECATED
-int
-main(int, char**)
-{
- // If glibmm is configured with --disable-deprecated-api,
- // GLIBMM_DISABLE_DEPRECATED is defined in glibmmconfig.h.
- std::cout << "Glib::ThreadPool not available because deprecated API has been disabled."
- << std::endl;
- return 77; // Tell automake's test harness to skip this test.
-}
-
-#else
-
-#include <glibmm/random.h>
-#include <glibmm/threadpool.h>
-#include <glibmm/timer.h>
-
-namespace
-{
-
-std::mutex mutex;
-
-void
-print_char(char c)
-{
- Glib::Rand rand;
-
- for (auto i = 0; i < 100; ++i)
- {
- {
- std::lock_guard<std::mutex> lock(mutex);
- std::cout << c;
- std::cout.flush();
- }
- Glib::usleep(rand.get_int_range(10000, 100000));
- }
-}
-
-} // anonymous namespace
-
-int
-main(int, char**)
-{
- Glib::ThreadPool pool(10);
-
- for (auto c = 'a'; c <= 'z'; ++c)
- {
- pool.push(sigc::bind(sigc::ptr_fun(&print_char), c));
- }
-
- pool.shutdown();
-
- std::cout << std::endl;
-
- return 0;
-}
-#endif // GLIBMM_DISABLE_DEPRECATED
diff --git a/glib/glibmm.h b/glib/glibmm.h
index b82b1430..79d3e1d3 100644
--- a/glib/glibmm.h
+++ b/glib/glibmm.h
@@ -84,12 +84,6 @@
//#include <glibmm/i18n.h> //This must be included by the application, after system headers such as
//<iostream>.
-// Include this first because we need it to be the first thing to include <glib.h>,
-// so we can do an undef trick to still use deprecated API in the header:
-#include <glibmm/thread.h>
-
-#include <glibmm/threads.h>
-
#include <glibmm/arrayhandle.h>
#include <glibmm/balancedtree.h>
#include <glibmm/base64.h>
@@ -140,7 +134,6 @@
#include <glibmm/slisthandle.h>
#include <glibmm/spawn.h>
#include <glibmm/stringutils.h>
-#include <glibmm/threadpool.h>
#include <glibmm/timer.h>
#include <glibmm/timeval.h>
#include <glibmm/timezone.h>
diff --git a/glib/glibmm/dispatcher.cc b/glib/glibmm/dispatcher.cc
index 83da346d..3c8a65d0 100644
--- a/glib/glibmm/dispatcher.cc
+++ b/glib/glibmm/dispatcher.cc
@@ -15,10 +15,6 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef GLIBMM_CAN_USE_THREAD_LOCAL
-#include <glibmm/threads.h>
-#endif
-
#include <glibmm/dispatcher.h>
#include <glibmm/exceptionhandler.h>
#include <glibmm/fileutils.h>
@@ -147,11 +143,7 @@ protected:
explicit DispatchNotifier(const Glib::RefPtr<MainContext>& context);
private:
-#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
static thread_local DispatchNotifier* thread_specific_instance_;
-#else
- static Glib::Threads::Private<DispatchNotifier> thread_specific_instance_;
-#endif
std::set<const Dispatcher*> deleted_dispatchers_;
@@ -175,11 +167,7 @@ private:
// static
-#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
thread_local DispatchNotifier* DispatchNotifier::thread_specific_instance_ = nullptr;
-#else
-Glib::Threads::Private<DispatchNotifier> DispatchNotifier::thread_specific_instance_;
-#endif
DispatchNotifier::DispatchNotifier(const Glib::RefPtr<MainContext>& context)
: deleted_dispatchers_(),
@@ -282,20 +270,12 @@ DispatchNotifier*
DispatchNotifier::reference_instance(
const Glib::RefPtr<MainContext>& context, const Dispatcher* dispatcher)
{
-#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
DispatchNotifier* instance = thread_specific_instance_;
-#else
- DispatchNotifier* instance = thread_specific_instance_.get();
-#endif
if (!instance)
{
instance = new DispatchNotifier(context);
-#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
thread_specific_instance_ = instance;
-#else
- thread_specific_instance_.replace(instance);
-#endif
}
else
{
@@ -323,11 +303,7 @@ DispatchNotifier::reference_instance(
void
DispatchNotifier::unreference_instance(DispatchNotifier* notifier, const Dispatcher* dispatcher)
{
-#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
DispatchNotifier* const instance = thread_specific_instance_;
-#else
- DispatchNotifier* const instance = thread_specific_instance_.get();
-#endif
// Yes, the notifier argument is only used to check for sanity.
g_return_if_fail(instance == notifier);
@@ -344,12 +320,8 @@ DispatchNotifier::unreference_instance(DispatchNotifier* notifier, const Dispatc
{
g_return_if_fail(instance->ref_count_ == 0); // could be < 0 if messed up
-#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
delete thread_specific_instance_;
thread_specific_instance_ = nullptr;
-#else
- thread_specific_instance_.replace(nullptr);
-#endif
}
}
diff --git a/glib/glibmm/exceptionhandler.cc b/glib/glibmm/exceptionhandler.cc
index 7a16c789..e80e0093 100644
--- a/glib/glibmm/exceptionhandler.cc
+++ b/glib/glibmm/exceptionhandler.cc
@@ -19,9 +19,6 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef GLIBMM_CAN_USE_THREAD_LOCAL
-#include <glibmm/threads.h>
-#endif
#include <glibmmconfig.h>
#include <glibmm/error.h>
#include <glibmm/exceptionhandler.h>
@@ -36,11 +33,7 @@ using HandlerList = std::list<sigc::slot<void()>>;
// Each thread has its own list of exception handlers
// to avoid thread synchronization problems.
-#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
static thread_local HandlerList* thread_specific_handler_list = nullptr;
-#else
-static Glib::Threads::Private<HandlerList> thread_specific_handler_list;
-#endif
static void
glibmm_exception_warning(const GError* error)
@@ -92,20 +85,12 @@ namespace Glib
sigc::connection
add_exception_handler(const sigc::slot<void()>& slot)
{
-#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
HandlerList* handler_list = thread_specific_handler_list;
-#else
- HandlerList* handler_list = thread_specific_handler_list.get();
-#endif
if (!handler_list)
{
handler_list = new HandlerList();
-#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
thread_specific_handler_list = handler_list;
-#else
- thread_specific_handler_list.set(handler_list);
-#endif
}
handler_list->emplace_back(slot);
@@ -130,11 +115,7 @@ exception_handlers_invoke() noexcept
// handled. If there are no more handlers in the list and the exception
// is still unhandled, call glibmm_unexpected_exception().
-#ifdef GLIBMM_CAN_USE_THREAD_LOCAL
if (HandlerList* const handler_list = thread_specific_handler_list)
-#else
- if(HandlerList *const handler_list = thread_specific_handler_list.get())
-#endif
{
HandlerList::iterator pslot = handler_list->begin();
diff --git a/glib/glibmm/filelist.am b/glib/glibmm/filelist.am
index dc6615f5..afeb2b4c 100644
--- a/glib/glibmm/filelist.am
+++ b/glib/glibmm/filelist.am
@@ -30,7 +30,6 @@ glibmm_files_extra_cc = \
signalproxy_connectionnode.cc \
streamiochannel.cc \
stringutils.cc \
- threadpool.cc \
timer.cc \
timeval.cc \
ustring.cc \
@@ -74,7 +73,6 @@ glibmm_files_extra_h = \
slisthandle.h \
streamiochannel.h \
stringutils.h \
- threadpool.h \
timer.h \
timeval.h \
ustring.h \
diff --git a/glib/glibmm/main.cc b/glib/glibmm/main.cc
index 06521a47..f549e021 100644
--- a/glib/glibmm/main.cc
+++ b/glib/glibmm/main.cc
@@ -17,13 +17,6 @@
#include <glibmmconfig.h> // May define GLIBMM_DISABLE_DEPRECATED
-#ifndef GLIBMM_DISABLE_DEPRECATED
-// Include glibmm/thread.h first because we need it to be first to include <glib.h>,
-// so we can do an undef trick to still use deprecated API in the header:
-#include <glibmm/thread.h>
-#include <glibmm/threads.h>
-#endif // GLIBMM_DISABLE_DEPRECATED
-
#include <glibmm/main.h>
#include <glibmm/exceptionhandler.h>
#include <glibmm/wrap.h>
@@ -608,20 +601,6 @@ MainContext::acquire()
return g_main_context_acquire(gobj());
}
-#ifndef GLIBMM_DISABLE_DEPRECATED
-bool
-MainContext::wait(Glib::Cond& cond, Glib::Mutex& mutex)
-{
- return g_main_context_wait(gobj(), cond.gobj(), mutex.gobj());
-}
-
-bool
-MainContext::wait(Glib::Threads::Cond& cond, Glib::Threads::Mutex& mutex)
-{
- return g_main_context_wait(gobj(), cond.gobj(), mutex.gobj());
-}
-#endif // GLIBMM_DISABLE_DEPRECATED
-
void
MainContext::release()
{
diff --git a/glib/glibmm/main.h b/glib/glibmm/main.h
index 4dbbf150..26718764 100644
--- a/glib/glibmm/main.h
+++ b/glib/glibmm/main.h
@@ -30,17 +30,6 @@
namespace Glib
{
-#ifndef GLIBMM_DISABLE_DEPRECATED
-class Cond;
-class Mutex;
-
-namespace Threads
-{
-class Cond;
-class Mutex;
-}
-#endif // GLIBMM_DISABLE_DEPRECATED
-
/** @defgroup MainLoop The Main Event Loop
* Manages all available sources of events.
* @{
@@ -69,16 +58,6 @@ private:
GPollFD gobject_;
};
-// Concerning SignalTimeout::connect_once(), SignalTimeout::connect_seconds_once()
-// and SignalIdle::connect_once():
-// See https://bugzilla.gnome.org/show_bug.cgi?id=396963 and
-// http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
-// It's recommended to replace sigc::slot<void()>& by std::function<void()>& in
-// Threads::Thread::create() and ThreadPool::push() at the next ABI break.
-// Such a replacement would be a mixed blessing in SignalTimeout and SignalIdle.
-// In a single-threaded program auto-disconnection of trackable slots is safe
-// and can be useful.
-
class SignalTimeout
{
public:
@@ -453,36 +432,6 @@ public:
*/
bool acquire();
-#ifndef GLIBMM_DISABLE_DEPRECATED
- /** Tries to become the owner of the specified context, as with acquire(). But if another thread
- * is the owner,
- * atomically drop mutex and wait on cond until that owner releases ownership or until cond is
- * signaled, then try
- * again (once) to become the owner.
- * @param cond A condition variable.
- * @param mutex A mutex, currently held.
- * @return true if the operation succeeded, and this thread is now the owner of context.
- *
- * @deprecated Use wait(Glib::Threads::Cond& cond, Glib::Threads::Mutex& mutex) instead.
- */
- bool wait(Glib::Cond& cond, Glib::Mutex& mutex);
-
- // Deprecated mostly because it uses deprecated Glib::Threads:: for parameters.
- /** Tries to become the owner of the specified context, as with acquire(). But if another thread
- * is the owner,
- * atomically drop mutex and wait on cond until that owner releases ownership or until cond is
- * signaled, then try
- * again (once) to become the owner.
- * @param cond A condition variable.
- * @param mutex A mutex, currently held.
- * @return true if the operation succeeded, and this thread is now the owner of context.
- *
- * @deprecated Please use the underlying g_main_context_wait() function if you really need this
- * functionality.
- */
- bool wait(Glib::Threads::Cond& cond, Glib::Threads::Mutex& mutex);
-#endif // GLIBMM_DISABLE_DEPRECATED
-
/** Releases ownership of a context previously acquired by this thread with acquire(). If the
* context was acquired
* multiple times, the only release ownership when release() is called as many times as it was
diff --git a/glib/glibmm/threadpool.cc b/glib/glibmm/threadpool.cc
deleted file mode 100644
index 7070ccdf..00000000
--- a/glib/glibmm/threadpool.cc
+++ /dev/null
@@ -1,255 +0,0 @@
-/* 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 Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <glibmmconfig.h>
-#ifndef GLIBMM_DISABLE_DEPRECATED
-
-#include <glibmm/threadpool.h>
-#include <glibmm/exceptionhandler.h>
-#include <glibmm/threads.h>
-#include <glib.h>
-#include <list>
-
-namespace Glib
-{
-
-// internal
-class ThreadPool::SlotList
-{
-public:
- SlotList();
- ~SlotList() noexcept;
-
- // noncopyable
- SlotList(const ThreadPool::SlotList&) = delete;
- ThreadPool::SlotList& operator=(const ThreadPool::SlotList&) = delete;
-
- sigc::slot<void()>* push(const sigc::slot<void()>& slot);
- sigc::slot<void()> pop(sigc::slot<void()>* slot_ptr);
-
- void lock_and_unlock();
-
-private:
- Glib::Threads::Mutex mutex_;
- std::list<sigc::slot<void()>> list_;
-};
-
-ThreadPool::SlotList::SlotList()
-{
-}
-
-ThreadPool::SlotList::~SlotList() noexcept
-{
-}
-
-sigc::slot<void()>*
-ThreadPool::SlotList::push(const sigc::slot<void()>& slot)
-{
- Threads::Mutex::Lock lock(mutex_);
-
- list_.emplace_back(slot);
- return &list_.back();
-}
-
-sigc::slot<void()>
-ThreadPool::SlotList::pop(sigc::slot<void()>* slot_ptr)
-{
- sigc::slot<void()> slot;
-
- {
- Threads::Mutex::Lock lock(mutex_);
-
- std::list<sigc::slot<void()>>::iterator pslot = list_.begin();
- while (pslot != list_.end() && slot_ptr != &*pslot)
- ++pslot;
-
- if (pslot != list_.end())
- {
- slot = *pslot;
- list_.erase(pslot);
- }
- }
-
- return slot;
-}
-
-void
-ThreadPool::SlotList::lock_and_unlock()
-{
- mutex_.lock();
- mutex_.unlock();
-}
-
-} // namespace Glib
-
-namespace
-{
-
-static void
-call_thread_entry_slot(void* data, void* user_data)
-{
- try
- {
- Glib::ThreadPool::SlotList* const slot_list =
- static_cast<Glib::ThreadPool::SlotList*>(user_data);
-
- sigc::slot<void()> slot(slot_list->pop(static_cast<sigc::slot<void()>*>(data)));
-
- slot();
- }
- catch (Glib::Threads::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();
- }
-}
-
-} // anonymous namespace
-
-namespace Glib
-{
-
-ThreadPool::ThreadPool(int max_threads, bool exclusive)
-: gobject_(nullptr), slot_list_(new SlotList())
-{
- GError* error = nullptr;
-
- gobject_ = g_thread_pool_new(&call_thread_entry_slot, slot_list_, max_threads, exclusive, &error);
-
- if (error)
- {
- delete slot_list_;
- slot_list_ = nullptr;
- Glib::Error::throw_exception(error);
- }
-}
-
-ThreadPool::~ThreadPool() noexcept
-{
- if (gobject_)
- g_thread_pool_free(gobject_, 1, 1);
-
- if (slot_list_)
- {
- slot_list_->lock_and_unlock();
- delete slot_list_;
- }
-}
-
-void
-ThreadPool::push(const sigc::slot<void()>& slot)
-{
- sigc::slot<void()>* const slot_ptr = slot_list_->push(slot);
-
- GError* error = nullptr;
- g_thread_pool_push(gobject_, slot_ptr, &error);
-
- if (error)
- {
- slot_list_->pop(slot_ptr);
- Glib::Error::throw_exception(error);
- }
-}
-
-void
-ThreadPool::set_max_threads(int max_threads)
-{
- GError* error = nullptr;
- g_thread_pool_set_max_threads(gobject_, max_threads, &error);
-
- if (error)
- Glib::Error::throw_exception(error);
-}
-
-int
-ThreadPool::get_max_threads() const
-{
- return g_thread_pool_get_max_threads(gobject_);
-}
-
-unsigned int
-ThreadPool::get_num_threads() const
-{
- return g_thread_pool_get_num_threads(gobject_);
-}
-
-unsigned int
-ThreadPool::unprocessed() const
-{
- return g_thread_pool_unprocessed(gobject_);
-}
-
-bool
-ThreadPool::get_exclusive() const
-{
- g_return_val_if_fail(gobject_ != nullptr, false);
-
- return gobject_->exclusive;
-}
-
-void
-ThreadPool::shutdown(bool immediately)
-{
- if (gobject_)
- {
- g_thread_pool_free(gobject_, immediately, 1);
- gobject_ = nullptr;
- }
-
- if (slot_list_)
- {
- slot_list_->lock_and_unlock();
- delete slot_list_;
- slot_list_ = nullptr;
- }
-}
-
-// static
-void
-ThreadPool::set_max_unused_threads(int max_threads)
-{
- g_thread_pool_set_max_unused_threads(max_threads);
-}
-
-// static
-int
-ThreadPool::get_max_unused_threads()
-{
- return g_thread_pool_get_max_unused_threads();
-}
-
-// static
-unsigned int
-ThreadPool::get_num_unused_threads()
-{
- return g_thread_pool_get_num_unused_threads();
-}
-
-// static
-void
-ThreadPool::stop_unused_threads()
-{
- g_thread_pool_stop_unused_threads();
-}
-
-} // namespace Glib
-
-#endif // GLIBMM_DISABLE_DEPRECATED
diff --git a/glib/glibmm/threadpool.h b/glib/glibmm/threadpool.h
deleted file mode 100644
index 06285f0d..00000000
--- a/glib/glibmm/threadpool.h
+++ /dev/null
@@ -1,200 +0,0 @@
-#ifndef _GLIBMM_THREADPOOL_H
-#define _GLIBMM_THREADPOOL_H
-
-/* 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 Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <glibmmconfig.h>
-
-#ifndef GLIBMM_DISABLE_DEPRECATED
-
-#include <sigc++/sigc++.h>
-
-extern "C" {
-using GThreadPool = struct _GThreadPool;
-}
-
-namespace Glib
-{
-
-/** @defgroup ThreadPools Thread Pools
- * Pools of threads to execute work concurrently.
- *
- * @deprecated This is deprecated in favor of the standard C++ concurrency API in C++11 and C++14.
- *
- * @{
- */
-
-// TODO: Is std::async() an appropriate replacement to mention for this deprecated API?
-
-/** A pool of threads to execute work concurrently.
- *
- * @deprecated This is deprecated in favor of the standard C++ concurrency API in C++11 and C++14.
- */
-class ThreadPool
-{
-public:
- /** Constructs a new thread pool.
- * Whenever you call ThreadPool::push(), either a new thread is created or an
- * unused one is reused. At most @a max_threads threads are running
- * concurrently for this thread pool. @a max_threads&nbsp;=&nbsp;-1 allows
- * unlimited threads to be created for this thread pool.
- *
- * The parameter @a exclusive determines, whether the thread pool owns all
- * threads exclusive or whether the threads are shared globally. If @a
- * exclusive is <tt>true</tt>, @a max_threads threads are started immediately
- * and they will run exclusively for this thread pool until it is destroyed
- * by ~ThreadPool(). If @a exclusive is <tt>false</tt>, threads are created
- * when needed and shared between all non-exclusive thread pools. This
- * implies that @a max_threads may not be -1 for exclusive thread pools.
- *
- * @param max_threads The maximal number of threads to execute concurrently
- * in the new thread pool, -1 means no limit.
- * @param exclusive Should this thread pool be exclusive?
- * @throw Glib::ThreadError An error can only occur when @a exclusive is
- * set to <tt>true</tt> and not all @a max_threads threads could be created.
- */
- explicit ThreadPool(int max_threads = -1, bool exclusive = false);
- virtual ~ThreadPool() noexcept;
-
- // See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
- // TODO: At the next ABI break, consider changing const sigc::slot<void()>& slot
- // to const std::function<void()>& func, if it can be assumed that all supported
- // compilers understand the C++11 template class std::function<>.
- /** Inserts @a slot into the list of tasks to be executed by the pool.
- * When the number of currently running threads is lower than the maximal
- * allowed number of threads, a new thread is started (or reused). Otherwise
- * @a slot stays in the queue until a thread in this pool finishes its
- * previous task and processes @a slot.
- *
- * Because sigc::trackable is not thread-safe, if the slot represents a
- * non-static class method and is created by sigc::mem_fun(), the class concerned
- * should not derive from sigc::trackable. You can use, say, boost::bind() or,
- * in C++11, std::bind() or a C++11 lambda expression instead of sigc::mem_fun().
- *
- * @param slot A new task for the thread pool.
- * @throw Glib::ThreadError An error can only occur when a new thread
- * couldn't be created. In that case @a slot is simply appended to the
- * queue of work to do.
- */
- void push(const sigc::slot<void()>& slot);
-
- /** Sets the maximal allowed number of threads for the pool.
- * A value of -1 means that the maximal number of threads is unlimited.
- * Setting @a max_threads to 0 means stopping all work for pool. It is
- * effectively frozen until @a max_threads is set to a non-zero value again.
- *
- * A thread is never terminated while it is still running. Instead the
- * maximal number of threads only has effect for the allocation of new
- * threads in ThreadPool::push(). A new thread is allocated whenever the
- * number of currently running threads in the pool is smaller than the
- * maximal number.
- *
- * @param max_threads A new maximal number of threads for the pool.
- * @throw Glib::ThreadError An error can only occur when a new thread
- * couldn't be created.
- */
- void set_max_threads(int max_threads);
-
- /** Returns the maximal number of threads for the pool.
- * @return The maximal number of threads.
- */
- int get_max_threads() const;
-
- /** Returns the number of threads currently running in the pool.
- * @return The number of threads currently running.
- */
- unsigned int get_num_threads() const;
-
- /** Returns the number of tasks still unprocessed in the pool.
- * @return The number of unprocessed tasks.
- */
- unsigned int unprocessed() const;
-
- /** Returns whether all threads are exclusive to this pool.
- * @return Whether all threads are exclusive to this pool.
- */
- bool get_exclusive() const;
-
- /** Frees all resources allocated for the pool.
- * If @a immediately is <tt>true</tt>, no new task is processed. Otherwise the
- * pool is not freed before the last task is processed. Note however, that no
- * thread of this pool is interrupted while processing a task. Instead at least
- * all still running threads can finish their tasks before the pool is freed.
- *
- * This method does not return before all tasks to be processed (dependent on
- * @a immediately, whether all or only the currently running) are ready.
- * After calling shutdown() the pool must not be used anymore.
- *
- * @param immediately Should the pool shut down immediately?
- */
- void shutdown(bool immediately = false);
-
- /** Sets the maximal number of unused threads to @a max_threads.
- * If @a max_threads is -1, no limit is imposed on the number of unused threads.
- * @param max_threads Maximal number of unused threads.
- */
- static void set_max_unused_threads(int max_threads);
-
- /** Returns the maximal allowed number of unused threads.
- * @return The maximal number of unused threads.
- */
- static int get_max_unused_threads();
-
- /** Returns the number of currently unused threads.
- * @return The number of currently unused threads.
- */
- static unsigned int get_num_unused_threads();
-
- /** Stops all currently unused threads.
- * This does not change the maximal number of unused threads. This function can
- * be used to regularly stop all unused threads e.g. from Glib::signal_timeout().
- */
- static void stop_unused_threads();
-
- GThreadPool* gobj() { return gobject_; }
- const GThreadPool* gobj() const { return gobject_; }
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
- class SlotList;
-#endif
-
-private:
- GThreadPool* gobject_;
- SlotList* slot_list_;
-
- ThreadPool(const ThreadPool&);
- ThreadPool& operator=(const ThreadPool&);
-};
-
-/** @} group ThreadPools */
-
-/***************************************************************************/
-/* inline implementation */
-/***************************************************************************/
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-
-/**** Glib::Private ********************************************************/
-
-#endif /* DOXYGEN_SHOULD_SKIP_THIS */
-
-} // namespace Glib
-
-#endif // GLIBMM_DISABLE_DEPRECATED
-
-#endif /* _GLIBMM_THREADPOOL_H */
diff --git a/glib/src/filelist.am b/glib/src/filelist.am
index 6b52c61a..a8c2c406 100644
--- a/glib/src/filelist.am
+++ b/glib/src/filelist.am
@@ -36,8 +36,6 @@ glibmm_files_any_hg = \
regex.hg \
shell.hg \
spawn.hg \
- thread.hg \
- threads.hg \
timezone.hg \
unicode.hg \
uriutils.hg \
diff --git a/glib/src/thread.ccg b/glib/src/thread.ccg
deleted file mode 100644
index 7965ab99..00000000
--- a/glib/src/thread.ccg
+++ /dev/null
@@ -1,427 +0,0 @@
-/* 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 Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser 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.h>
-
-namespace
-{
-
-extern "C" {
-
-static void*
-call_thread_entry_slot(void* data)
-{
- const auto 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 nullptr;
-}
-
-} // extern "C"
-
-} // anonymous namespace
-
-namespace Glib
-{
-
-// This was always meant as an internal method. It is no longer called,
-// and no longer needs to be called. We are keeping it just to avoid
-// breaking ABI, though hopefully nobody is using it anyway.
-// TODO: Remove this when we can break ABI.
-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
- const auto slot_copy = new sigc::slot<void()>(slot);
-
- GError* error = nullptr;
-
- const auto thread = g_thread_try_new(nullptr, &call_thread_entry_slot, slot_copy, &error);
-
- if (error)
- {
- delete slot_copy;
- // Glib::Error::throw_exception() will probably wrap G_THREAD_ERROR in a
- // Glib::Threads::ThreadError instance, but we want a Glib::ThreadError.
- if (error->domain == G_THREAD_ERROR)
- throw Glib::ThreadError(error);
- else
- 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
- const auto slot_copy = new sigc::slot<void()>(slot);
-
- GError* error = nullptr;
-
- const auto 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() will probably wrap G_THREAD_ERROR in a
- // Glib::Threads::ThreadError instance, but we want a Glib::ThreadError.
- if (error->domain == G_THREAD_ERROR)
- throw Glib::ThreadError(error);
- else
- Glib::Error::throw_exception(error);
- }
-
- return reinterpret_cast<Thread*>(thread);
-}
-
-// static
-Thread*
-Thread::self()
-{
- return reinterpret_cast<Thread*>(g_thread_self());
-}
-
-void
-Thread::join()
-{
- g_thread_join(&gobject_);
-}
-
-bool
-Thread::joinable() const
-{
- return true; // An appropriate result now that this is deprecated because all threads are now
- // joinable.
-}
-
-void
-Thread::set_priority(ThreadPriority priority)
-{
- g_thread_set_priority(&gobject_, (GThreadPriority)priority);
-}
-
-ThreadPriority
-Thread::get_priority() const
-{
- return THREAD_PRIORITY_NORMAL; // An appropriate result now that this is deprecated because the
- // priority concept has been removed.
-}
-
-void
-thread_init(GThreadFunctions* /* vtable */)
-{
- // g_thread_init() is deprecated and now does nothing,
- // so we do not even call it. That avoids a need to link to gthread-2.0,
- // which contains the empty g_thread_init() implementation.
- // g_thread_init(vtable);
-
- Glib::thread_init_impl();
-}
-
-bool
-thread_supported()
-{
- // MSVC++ needs the != 0 to avoid an int -> bool cast warning.
- return (g_thread_supported() != 0);
-}
-
-// 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()) // TODO: Use a statically-allocated GMutext instead, with g_mutex_init().
-{
-}
-
-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_);
-}
-
-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));
-}
-
-void*
-StaticPrivate_get_helper(GStaticPrivate* private_key)
-{
- return g_static_private_get(private_key);
-}
-
-void
-StaticPrivate_set_helper(GStaticPrivate* private_key, gpointer data, GDestroyNotify notify)
-{
- return g_static_private_set(private_key, data, notify);
-}
-
-GPrivate*
-GPrivate_new_helper(GDestroyNotify notify)
-{
- return g_private_new(notify);
-}
-
-} // namespace Glib
diff --git a/glib/src/thread.hg b/glib/src/thread.hg
deleted file mode 100644
index 045ce2b6..00000000
--- a/glib/src/thread.hg
+++ /dev/null
@@ -1,1085 +0,0 @@
-/* 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 Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-_DEFS(glibmm,glib)
-_CONFIGINCLUDE(glibmmconfig.h)
-
-_IS_DEPRECATED // This whole file is deprecated.
-
-#m4 _PUSH(SECTION_CC_PRE_INCLUDES)
-//Stop the compiler warnings about using the deprecated API;
-#define GLIB_DISABLE_DEPRECATION_WARNINGS 1
-#m4 _POP()
-
-// We use GThreadFunctions in the (deprecated) API, so we must temporarily undef G_DISABLE_DEPRECATED.
-// Temporarily undef G_DISABLE_DEPRECATED, redefining it later if appropriate.
-#if defined(G_DISABLE_DEPRECATED) && !defined(GLIBMM_G_DISABLE_DEPRECATED_UNDEFED)
-//Stop the deprecation ifdef guards around the API declarations:
-#undef G_DISABLE_DEPRECATED
-#define GLIBMM_G_DISABLE_DEPRECATED_UNDEFED 1
-#endif
-
-#include <glib.h>
-
-// Redefine G_DISABLE_DEPRECATED if it was defined before we temporarily undefed it:
-#if defined(GLIBMM_G_DISABLE_DEPRECATED_UNDEFED)
-#define G_DISABLE_DEPRECATED 1
-#undef GLIBMM_G_DISABLE_DEPRECATED_UNDEFED
-#endif
-
-
-#include <glibmm/error.h>
-#include <glibmm/timeval.h>
-#include <sigc++/sigc++.h>
-
-#include <cstddef>
-
-/* Shadow THREAD_PRIORITY_NORMAL macro (from winbase.h).
- */
-#if defined(THREAD_PRIORITY_NORMAL) && !defined(GLIBMM_MACRO_SHADOW_THREAD_PRIORITY_NORMAL)
-enum { GLIBMM_MACRO_DEFINITION_THREAD_PRIORITY_NORMAL = THREAD_PRIORITY_NORMAL };
-#undef THREAD_PRIORITY_NORMAL
-enum { THREAD_PRIORITY_NORMAL = GLIBMM_MACRO_DEFINITION_THREAD_PRIORITY_NORMAL };
-#define THREAD_PRIORITY_NORMAL THREAD_PRIORITY_NORMAL
-#define GLIBMM_MACRO_SHADOW_THREAD_PRIORITY_NORMAL 1
-#endif
-
-
-/** Initializer macro for Glib::StaticRecMutex.
- * @relates Glib::StaticRecMutex
- * @hideinitializer
- *
- * @deprecated Glib::StaticRecMutex is deprecated in favour of Glib::Threads::RecMutex, which can be used statically.
- */
-#define GLIBMM_STATIC_REC_MUTEX_INIT { G_STATIC_REC_MUTEX_INIT }
-
-/** Initializer macro for Glib::StaticRWLock.
- * @relates Glib::StaticRWLock
- * @hideinitializer
- *
- * @deprecated Glib::StaticRWLock is deprecated in favour of Glib::Threads::RWLock, which can be used statically.
- */
-#define GLIBMM_STATIC_RW_LOCK_INIT { G_STATIC_RW_LOCK_INIT }
-
-/** Initializer macro for Glib::StaticPrivate.
- * @relates Glib::StaticPrivate
- * @hideinitializer
- *
- * @deprecated Glib::StaticPrivate is deprecated in favour of Glib::Threads::Private, which can be used statically.
- */
-#define GLIBMM_STATIC_PRIVATE_INIT { G_STATIC_PRIVATE_INIT }
-
-namespace Glib
-{
-
-/** @deprecated Thread priorities no longer have any effect.
- */
-_WRAP_ENUM(ThreadPriority, GThreadPriority, NO_GTYPE)
-
-/*! @var ThreadPriority THREAD_PRIORITY_LOW
- * A priority lower than normal.
- */
-/*! @var ThreadPriority THREAD_PRIORITY_NORMAL
- * The default priority.
- */
-/*! @var ThreadPriority THREAD_PRIORITY_HIGH
- * A priority higher than normal.
- */
-/*! @var ThreadPriority THREAD_PRIORITY_URGENT
- * The highest priority.
- */
-
-/** Initializes the GLib thread system.
- * @deprecated Calling thread_init() is no longer necessary and no longer has any effect.
- */
-void thread_init(GThreadFunctions* vtable = nullptr);
-
-/** Returns whether the thread system is initialized.
- * @return @c true, if the thread system is initialized.
- * @deprecated This is no longer useful, because the thread system is always initialized.
- */
-bool thread_supported();
-
-/**
- * @deprecated Use Glib::Threads::NotLock instead.
- */
-enum NotLock { NOT_LOCK };
-
-/**
- * @deprecated Use Glib::Threads::TryLock instead.
- */
-enum TryLock { TRY_LOCK };
-
-class Mutex;
-class RecMutex;
-class RWLock;
-
-struct StaticRecMutex;
-struct StaticRWLock;
-
-
-/** Exception class for thread-related errors.
- * @deprecated Use Glib::Threads::ThreadError instead.
- */
-_WRAP_GERROR(ThreadError, GThreadError, G_THREAD_ERROR, NO_GTYPE)
-
-
-/** Represents a running thread.
- * An instance of this class can only be obtained with create(), self(),
- * or wrap(GThread*). It's not possible to delete a Thread object. If the
- * thread is @em not joinable, its resources will be freed automatically
- * when it exits. Otherwise, if the thread @em is joinable, you must call
- * join() to avoid a memory leak.
- *
- * @note g_thread_exit() is not wrapped, because that function exits a thread
- * without any cleanup. That's especially dangerous in C++ code, since the
- * destructors of automatic objects won't be invoked. Instead, you can throw
- * a Thread::Exit exception, which will be caught by the internal thread
- * entry function.
- *
- * @note You might have noticed that the thread entry slot doesn't have the
- * usual void* return value. If you want to return any data from your thread
- * you can pass an additional output argument to the thread's entry slot.
- *
- * @deprecated Use Glib::Threads::Thread instead.
- */
-class Thread
-{
-public:
-
- Thread(const Thread&) = delete;
- Thread& operator=(const Thread&) = delete;
-
- class Exit;
-
- //See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
- /** Creates a new thread with the priority <tt>THREAD_PRIORITY_NORMAL</tt>.
- * If @a joinable is @c true, you can wait for this thread's termination by
- * calling join(). Otherwise the thread will just disappear, when ready.
- *
- * The new thread executes the function or method @a slot points to. You can
- * pass additional arguments using sigc::bind(). If the thread was created
- * successfully, it is returned, otherwise a ThreadError exception is thrown.
- *
- * Because sigc::trackable is not thread safe, if the slot represents a
- * non-static class method (that is, it is created by sigc::mem_fun()), the
- * class concerned should not derive from sigc::trackable.
- *
- * @param slot A slot to execute in the new thread.
- * @param joinable This parameter is now ignored because Threads are now always joinable.
- * @return The new Thread* on success.
- * @throw Glib::ThreadError
- */
- static Thread* create(const sigc::slot<void()>& slot, bool joinable = true);
-
- /** Returns the Thread* corresponding to the calling thread.
- * @return The current thread.
- */
- static Thread* self();
-
- /** Waits until the thread finishes.
- * Waits until the thread finishes, i.e. the slot, as given to create(),
- * returns or g_thread_exit() is called by the thread. (Calling
- * g_thread_exit() in a C++ program should be avoided.) All resources of
- * the thread including the Glib::Thread object are released. The thread
- * must have been created with <tt>joinable&nbsp;=&nbsp;true</tt>.
- */
- void join();
-
- //See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
- /** Creates a new thread with the priority @a priority. The stack gets the
- * size @a stack_size or the default value for the current platform, if
- * @a stack_size is <tt>0</tt>.
- *
- * If @a joinable is @c true, you can wait for this thread's termination by
- * calling join(). Otherwise the thread will just disappear, when ready.
- * If @a bound is @c true, this thread will be scheduled in the system scope,
- * otherwise the implementation is free to do scheduling in the process
- * scope. The first variant is more expensive resource-wise, but generally
- * faster. On some systems (e.g. Linux) all threads are bound.
- *
- * The new thread executes the function or method @a slot points to. You can
- * pass additional arguments using sigc::bind(). If the thread was created
- * successfully, it is returned.
- *
- * Because sigc::trackable is not thread safe, if the slot represents a
- * non-static class method (that is, it is created by sigc::mem_fun()), the
- * class concerned should not derive from sigc::trackable.
- *
- * @note It is not guaranteed, that threads with different priorities really
- * behave accordingly. On some systems (e.g. Linux) only root can increase
- * priorities. On other systems (e.g. Solaris) there doesn't seem to be
- * different scheduling for different priorities. All in all try to avoid
- * being dependent on priorities. Use <tt>Glib::THREAD_PRIORITY_NORMAL</tt>
- * here as a default.
- *
- * @note Only use the extended
- * create(const sigc::slot<void()>&, unsigned long, bool, bool, ThreadPriority)
- * function, when you really can't use the simple
- * create(const sigc::slot<void()>&, bool)
- * instead. The latter overload does not take @a stack_size, @a bound and
- * @a priority as arguments, as they should only be used for cases, where
- * it is inevitable.
- *
- * @param slot A slot to execute in the new thread.
- * @param stack_size A stack size for the new thread, or <tt>0</tt>.
- * @param joinable Should this thread be joinable?
- * @param bound Should this thread be bound to a system thread?
- * @param priority A priority for the thread.
- * @return The new Thread* on success.
- * @throw Glib::ThreadError
- *
- * @deprecated Use the simpler create() method instead, because all Threads
- * are now joinable, and bounds and priority parameters now have no effect.
- */
- static Thread* create(const sigc::slot<void()>& slot, unsigned long stack_size,
- bool joinable, bool bound, ThreadPriority priority);
-
- /** Returns whether the thread is joinable.
- * @return Whether the thread is joinable.
- *
- * @deprecated All threads are now joinable.
- */
- bool joinable() const;
-
- /** Changes the priority of the thread to @a priority.
- * @note It is not guaranteed, that threads with different priorities really
- * behave accordingly. On some systems (e.g. Linux) only @c root can
- * increase priorities. On other systems (e.g. Solaris) there doesn't seem
- * to be different scheduling for different priorities. All in all try to
- * avoid being dependent on priorities.
- * @param priority A new priority for the thread.
- *
- * @deprecated Thread priorities no longer have any effect.
- */
- void set_priority(ThreadPriority priority);
-
- /** Returns the priority of the thread.
- * @return The thread's priority.
- *
- * @deprecated Thread priorities no longer have any effect.
- */
- ThreadPriority get_priority() const;
-
- /** Gives way to other threads waiting to be scheduled.
- * This function is often used as a method to make busy wait less evil. But
- * in most cases, you will encounter, there are better methods to do that.
- * So in general you shouldn't use this function.
- */
- static void yield();
-
- GThread* gobj() { return &gobject_; }
- const GThread* gobj() const { return &gobject_; }
-
-private:
- GThread gobject_;
-
- // Glib::Thread can neither be constructed nor deleted.
- Thread();
- void operator delete(void*, std::size_t);
-};
-
-/** %Exception class used to exit from a thread.
- * @code
- * throw Glib::Thread::Exit();
- * @endcode
- * Write this if you want to exit from a thread created by Thread::create().
- * Of course you must make sure not to catch Thread::Exit by accident, i.e.
- * when using <tt>catch(...)</tt> somewhere in your code.
- *
- * @deprecated Use Glib::Threads::Thread::Exit instead.
- */
-class Thread::Exit
-{};
-
-
-//TODO: Make sure that Glib::wrap() uses Glib::Threads::wrap() instead.
-
-/** @relates Glib::Thread
- *
- * @deprecated Use Glib::Threads::wrap(GThread*) instead.
- */
-Thread* wrap(GThread* gobject);
-
-struct StaticMutex;
-
-/** Like Glib::Mutex, but can be defined at compile time.
- * Use @c GLIBMM_STATIC_MUTEX_INIT to initialize a StaticMutex:
- * @code
- * Glib::StaticMutex mutex = GLIBMM_STATIC_MUTEX_INIT;
- * @endcode
- *
- * A StaticMutex can be used without calling Glib::thread_init(), it will
- * silently do nothing then. That will also work when using the implicit
- * conversion to Mutex&, thus you can safely use Mutex::Lock with a
- * StaticMutex.
- *
- * @deprecated Use Glib::Threads::Mutex instead, which can be used statically.
- */
-struct StaticMutex
-{
- void lock();
- bool trylock();
- void unlock();
-
- operator Mutex&();
-
- GStaticMutex* gobj() { return &gobject_; }
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
- // Must be public to allow initialization at compile time.
- GStaticMutex gobject_;
-#endif
-};
-
-/** Initializer macro for Glib::StaticMutex.
- * @relates Glib::StaticMutex
- * @hideinitializer
- *
- * @deprecated Glib::StaticMutex is deprecated in favour of Glib::Threads::Mutex, which can be used statically.
- */
-#define GLIBMM_STATIC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
-
-/** Represents a mutex (mutual exclusion).
- * It can be used to protect data against shared access. Try to use
- * Mutex::Lock instead of calling lock() and unlock() directly&nbsp;--
- * it will make your life much easier.
- *
- * @note Glib::Mutex is not recursive, i.e. a thread will deadlock, if it
- * already has locked the mutex while calling lock(). Use Glib::RecMutex
- * instead, if you need recursive mutexes.
- *
- * @deprecated Use Glib::Threads::Mutex instead.
- */
-class Mutex
-{
-public:
- class Lock;
-
- Mutex();
-
- Mutex(const Mutex&) = delete;
- Mutex& operator=(const Mutex&) = delete;
-
- ~Mutex();
-
- /** Locks the mutex.
- * If mutex is already locked by another thread, the current thread will
- * block until mutex is unlocked by the other thread.
- * @see Mutex::Lock
- */
- void lock();
-
- /** Tries to lock the mutex.
- * If the mutex is already locked by another thread, it immediately returns
- * @c false. Otherwise it locks the mutex and returns @c true.
- * @return Whether the mutex could be locked.
- * @see Mutex::Lock
- */
- bool trylock();
-
- /** Unlocks the mutex.
- * If another thread is blocked in a lock() call for this mutex, it will be
- * woken and can lock the mutex itself.
- * @see Mutex::Lock
- */
- void unlock();
-
- GMutex* gobj() { return gobject_; }
-
-private:
- GMutex* gobject_;
-};
-
-/** Utility class for exception-safe mutex locking.
- * @par Usage example:
- * @code
- * {
- * Glib::Mutex::Lock lock (mutex); // calls mutex.lock()
- * do_something();
- * } // the destructor calls mutex.unlock()
- * @endcode
- * As you can see, the compiler takes care of the unlocking. This is not
- * only exception safe but also much less error-prone. You could even
- * <tt>return</tt> while still holding the lock and it will be released
- * properly.
- *
- * @deprecated Use Glib::Threads::Mutex::Lock instead.
- */
-class Mutex::Lock
-{
-public:
- explicit inline Lock(Mutex& mutex);
- inline Lock(Mutex& mutex, NotLock);
- inline Lock(Mutex& mutex, TryLock);
- inline ~Lock();
-
- inline void acquire();
- inline bool try_acquire();
- inline void release();
- inline bool locked() const;
-
-private:
- Mutex& mutex_;
- bool locked_;
-
-
-};
-
-
-/** Like Glib::RecMutex, but can be defined at compile time.
- * Use @c GLIBMM_STATIC_REC_MUTEX_INIT to initialize a StaticRecMutex:
- * @code
- * Glib::StaticRecMutex mutex = GLIBMM_STATIC_REC_MUTEX_INIT;
- * @endcode
- * A StaticRecMutex can be used without calling Glib::thread_init(), it will
- * silently do nothing then. That will also work when using the implicit
- * conversion to RecMutex&, thus you can safely use RecMutex::Lock with a
- * StaticRecMutex.
- *
- * @deprecated Use Glib::Threads::RecMutex instead, which can be used statically.
- */
-struct StaticRecMutex
-{
- void lock();
- bool trylock();
- void unlock();
-
- void lock_full(unsigned int depth);
- unsigned int unlock_full();
-
- operator RecMutex&();
-
- GStaticRecMutex* gobj() { return &gobject_; }
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
- // Must be public to allow initialization at compile time.
- GStaticRecMutex gobject_;
-#endif
-};
-
-/**
- *
- * @deprecated Use Glib::Threads::RecMutex instead.
- */
-class RecMutex : public StaticRecMutex
-{
-public:
- class Lock;
-
- RecMutex();
- ~RecMutex();
-
-private:
- // noncopyable
- RecMutex(const RecMutex&);
- RecMutex& operator=(const RecMutex&);
-};
-
-/** Utility class for exception-safe locking of recursive mutexes.
- *
- * @deprecated Use Glib::Threads::RecMutex instead.
- */
-class RecMutex::Lock
-{
-public:
- explicit inline Lock(RecMutex& mutex);
- inline Lock(RecMutex& mutex, NotLock);
- inline Lock(RecMutex& mutex, TryLock);
-
- Lock(const RecMutex::Lock&) = delete;
- RecMutex::Lock& operator=(const RecMutex::Lock&) = delete;
-
- inline ~Lock();
-
- inline void acquire();
- inline bool try_acquire();
- inline void release();
- inline bool locked() const;
-
-private:
- RecMutex& mutex_;
- bool locked_;
-};
-
-
-/** Like Glib::RWLock, but can be defined at compile time.
- * Use @c GLIBMM_STATIC_RW_LOCK_INIT to initialize a StaticRWLock:
- * @code
- * Glib::StaticRWLock rw_lock = GLIBMM_STATIC_RW_LOCK_INIT;
- * @endcode
- * A StaticRWLock can be used without calling Glib::thread_init(), it will
- * silently do nothing then. That will also work when using the implicit
- * conversion to RWLock&, thus you can safely use RWLock::ReaderLock and
- * RWLock::WriterLock with a StaticRWLock.
- *
- * @deprecated Use Glib::Threads::RWLock instead, which can be used statically.
- */
-struct StaticRWLock
-{
- void reader_lock();
- bool reader_trylock();
- void reader_unlock();
-
- void writer_lock();
- bool writer_trylock();
- void writer_unlock();
-
- operator RWLock&();
-
- GStaticRWLock* gobj() { return &gobject_; }
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
- // Must be public to allow initialization at compile time.
- GStaticRWLock gobject_;
-#endif
-};
-
-/**
- *
- * @deprecated Use Glib::Threads::RWLock instead.
- */
-class RWLock : public StaticRWLock
-{
-public:
- class ReaderLock;
- class WriterLock;
-
- RWLock();
-
- RWLock(const RWLock&) = delete;
- RWLock& operator=(const RWLock&) = delete;
-
- ~RWLock();
-};
-
-/** Utility class for exception-safe locking of read/write locks.
- *
- * @deprecated Use Glib::Threads::RWLock::ReaderLock instead.
- */
-class RWLock::ReaderLock
-{
-public:
- explicit inline ReaderLock(RWLock& rwlock);
- inline ReaderLock(RWLock& rwlock, NotLock);
- inline ReaderLock(RWLock& rwlock, TryLock);
-
- ReaderLock(const RWLock::ReaderLock&) = delete;
- RWLock::ReaderLock& operator=(const RWLock::ReaderLock&) = delete;
-
- inline ~ReaderLock();
-
- inline void acquire();
- inline bool try_acquire();
- inline void release();
- inline bool locked() const;
-
-private:
- RWLock& rwlock_;
- bool locked_;
-};
-
-/** Utility class for exception-safe locking of read/write locks.
- *
- * @deprecated Use Glib::Threads::RWLock::WriterLock instead.
- */
-class RWLock::WriterLock
-{
-public:
- explicit inline WriterLock(RWLock& rwlock);
- inline WriterLock(RWLock& rwlock, NotLock);
- inline WriterLock(RWLock& rwlock, TryLock);
-
- WriterLock(const RWLock::WriterLock&) = delete;
- RWLock::WriterLock& operator=(const RWLock::WriterLock&) = delete;
-
- inline ~WriterLock();
-
- inline void acquire();
- inline bool try_acquire();
- inline void release();
- inline bool locked() const;
-
-private:
- RWLock& rwlock_;
- bool locked_;
-};
-
-/** An opaque data structure to represent a condition.
- * A @a Cond is an object that threads can block on, if they find a certain
- * condition to be false. If other threads change the state of this condition
- * they can signal the @a Cond, such that the waiting thread is woken up.
- * @par Usage example:
- * @code
- * Glib::Cond data_cond;
- * Glib::Mutex data_mutex;
- * void* current_data = nullptr;
- *
- * void push_data(void* data)
- * {
- * Glib::Mutex::Lock lock (data_mutex);
- *
- * current_data = data;
- * data_cond.signal();
- * }
- *
- * void* pop_data()
- * {
- * Glib::Mutex::Lock lock (data_mutex);
- *
- * while (!current_data)
- * data_cond.wait(data_mutex);
- *
- * void *const data = current_data;
- * current_data = nullptr;
- *
- * return data;
- * }
- * @endcode
- *
- * @deprecated Use Glib::Threads::Cond instead.
- */
-class Cond
-{
-public:
- Cond();
-
- Cond(const Cond&) = delete;
- Cond& operator=(const Cond&) = delete;
-
- ~Cond();
-
- /** If threads are waiting for this @a Cond, exactly one of them is woken up.
- * It is good practice to hold the same lock as the waiting thread, while calling
- * this method, though not required.
- *
- */
- void signal();
-
- /** If threads are waiting for this @a Cond, all of them are woken up.
- * It is good practice to hold the same lock as the waiting thread, while calling
- * this method, though not required.
- */
- void broadcast();
-
- /** Waits until this thread is woken up on this @a Cond.
- * The mutex is unlocked before falling asleep and locked again before resuming.
- *
- * @param mutex a @a Mutex that is currently locked.
- *
- * @note It is important to use the @a wait() and @a timed_wait() methods
- * only inside a loop, which checks for the condition to be true as it is not
- * guaranteed that the waiting thread will find it fulfilled, even if the signaling
- * thread left the condition in that state. This is because another thread can have
- * altered the condition, before the waiting thread got the chance to be woken up,
- * even if the condition itself is protected by a @a Mutex.
- */
- void wait(Mutex& mutex);
-
- /** 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.
- * The mutex is unlocked before falling asleep and locked again before resuming.
- *
- * @param mutex a @a Mutex that is currently locked.
- * @param abs_time a max time to wait.
- *
- * @note It is important to use the @a wait() and @a timed_wait() methods
- * only inside a loop, which checks for the condition to be true as it is not
- * guaranteed that the waiting thread will find it fulfilled, even if the signaling
- * thread left the condition in that state. This is because another thread can have
- * altered the condition, before the waiting thread got the chance to be woken up,
- * even if the condition itself is protected by a @a Mutex.
- */
- bool timed_wait(Mutex& mutex, const Glib::TimeVal& abs_time);
-
- GCond* gobj() { return gobject_; }
-
-private:
- GCond* gobject_;
-};
-
-
-/** Thread-local data pointer.
- *
- * @deprecated Use Glib::Threads::Private instead, which can be used statically.
- */
-template <class T>
-struct StaticPrivate
-{
- using DestroyNotifyFunc = void (*) (void*);
-
- static void delete_ptr(void* data);
-
- inline T* get();
- inline void set(T* data, DestroyNotifyFunc notify_func = &StaticPrivate<T>::delete_ptr);
-
- GStaticPrivate* gobj() { return &gobject_; }
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
- // Must be public to allow initialization at compile time.
- GStaticPrivate gobject_;
-#endif
-};
-
-/** Thread-local data pointer.
- *
- * @deprecated Use Glib::Threads::Private instead.
- */
-template <class T>
-class Private
-{
-public:
-
- Private(const Private<T>&) = delete;
- Private<T>& operator=(const Private<T>&) = delete;
-
- using DestructorFunc = void (*) (void*);
-
- static void delete_ptr(void* data);
-
- explicit inline Private(DestructorFunc destructor_func = &Private<T>::delete_ptr);
- inline T* get();
- inline void set(T* data);
-
- GPrivate* gobj() { return gobject_; }
-
-private:
- GPrivate* gobject_;
-};
-
-/** @} group Threads */
-
-/*! A glibmm thread example.
- * @example thread/thread.cc
- */
-
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-
-/***************************************************************************/
-/* inline implementation */
-/***************************************************************************/
-
-// internal
-/** @deprecated This was always for internal glibmm use and is now unecessary even inside glibmm.
- */
-void thread_init_impl();
-
-/**** Glib::Mutex::Lock ****************************************************/
-
-inline
-Mutex::Lock::Lock(Mutex& mutex)
-:
- mutex_ (mutex),
- locked_ (true)
-{
- mutex_.lock();
-}
-
-inline
-Mutex::Lock::Lock(Mutex& mutex, NotLock)
-:
- mutex_ (mutex),
- locked_ (false)
-{}
-
-inline
-Mutex::Lock::Lock(Mutex& mutex, TryLock)
-:
- mutex_ (mutex),
- locked_ (mutex.trylock())
-{}
-
-inline
-Mutex::Lock::~Lock()
-{
- if(locked_)
- mutex_.unlock();
-}
-
-inline
-void Mutex::Lock::acquire()
-{
- mutex_.lock();
- locked_ = true;
-}
-
-inline
-bool Mutex::Lock::try_acquire()
-{
- locked_ = mutex_.trylock();
- return locked_;
-}
-
-inline
-void Mutex::Lock::release()
-{
- mutex_.unlock();
- locked_ = false;
-}
-
-inline
-bool Mutex::Lock::locked() const
-{
- return locked_;
-}
-
-
-/**** Glib::RecMutex::Lock *************************************************/
-
-inline
-RecMutex::Lock::Lock(RecMutex& mutex)
-:
- mutex_ (mutex),
- locked_ (true)
-{
- mutex_.lock();
-}
-
-inline
-RecMutex::Lock::Lock(RecMutex& mutex, NotLock)
-:
- mutex_ (mutex),
- locked_ (false)
-{}
-
-inline
-RecMutex::Lock::Lock(RecMutex& mutex, TryLock)
-:
- mutex_ (mutex),
- locked_ (mutex.trylock())
-{}
-
-inline
-RecMutex::Lock::~Lock()
-{
- if(locked_)
- mutex_.unlock();
-}
-
-inline
-void RecMutex::Lock::acquire()
-{
- mutex_.lock();
- locked_ = true;
-}
-
-inline
-bool RecMutex::Lock::try_acquire()
-{
- locked_ = mutex_.trylock();
- return locked_;
-}
-
-inline
-void RecMutex::Lock::release()
-{
- mutex_.unlock();
- locked_ = false;
-}
-
-inline
-bool RecMutex::Lock::locked() const
-{
- return locked_;
-}
-
-
-/**** Glib::RWLock::ReaderLock *********************************************/
-
-inline
-RWLock::ReaderLock::ReaderLock(RWLock& rwlock)
-:
- rwlock_ (rwlock),
- locked_ (true)
-{
- rwlock_.reader_lock();
-}
-
-inline
-RWLock::ReaderLock::ReaderLock(RWLock& rwlock, NotLock)
-:
- rwlock_ (rwlock),
- locked_ (false)
-{}
-
-inline
-RWLock::ReaderLock::ReaderLock(RWLock& rwlock, TryLock)
-:
- rwlock_ (rwlock),
- locked_ (rwlock.reader_trylock())
-{}
-
-inline
-RWLock::ReaderLock::~ReaderLock()
-{
- if(locked_)
- rwlock_.reader_unlock();
-}
-
-inline
-void RWLock::ReaderLock::acquire()
-{
- rwlock_.reader_lock();
- locked_ = true;
-}
-
-inline
-bool RWLock::ReaderLock::try_acquire()
-{
- locked_ = rwlock_.reader_trylock();
- return locked_;
-}
-
-inline
-void RWLock::ReaderLock::release()
-{
- rwlock_.reader_unlock();
- locked_ = false;
-}
-
-inline
-bool RWLock::ReaderLock::locked() const
-{
- return locked_;
-}
-
-
-/**** Glib::RWLock::WriterLock *********************************************/
-
-inline
-RWLock::WriterLock::WriterLock(RWLock& rwlock)
-:
- rwlock_ (rwlock),
- locked_ (true)
-{
- rwlock_.writer_lock();
-}
-
-inline
-RWLock::WriterLock::WriterLock(RWLock& rwlock, NotLock)
-:
- rwlock_ (rwlock),
- locked_ (false)
-{}
-
-inline
-RWLock::WriterLock::WriterLock(RWLock& rwlock, TryLock)
-:
- rwlock_ (rwlock),
- locked_ (rwlock.writer_trylock())
-{}
-
-inline
-RWLock::WriterLock::~WriterLock()
-{
- if(locked_)
- rwlock_.writer_unlock();
-}
-
-inline
-void RWLock::WriterLock::acquire()
-{
- rwlock_.writer_lock();
- locked_ = true;
-}
-
-inline
-bool RWLock::WriterLock::try_acquire()
-{
- locked_ = rwlock_.writer_trylock();
- return locked_;
-}
-
-inline
-void RWLock::WriterLock::release()
-{
- rwlock_.writer_unlock();
- locked_ = false;
-}
-
-inline
-bool RWLock::WriterLock::locked() const
-{
- return locked_;
-}
-
-
-/**** Glib::StaticPrivate **************************************************/
-
-// static
-template <class T>
-void StaticPrivate<T>::delete_ptr(void* data)
-{
- delete static_cast<T*>(data);
-}
-
-/** This is only for use by glibmm itself.
- */
-void* StaticPrivate_get_helper(GStaticPrivate *private_key);
-
-template <class T> inline
-T* StaticPrivate<T>::get()
-{
- return static_cast<T*>(StaticPrivate_get_helper(&gobject_));
-}
-
-/** This is only for use by glibmm itself.
- */
-void StaticPrivate_set_helper(GStaticPrivate *private_key, gpointer data, GDestroyNotify notify);
-
-template <class T> inline
-void StaticPrivate<T>::set(T* data, typename StaticPrivate<T>::DestroyNotifyFunc notify_func)
-{
- StaticPrivate_set_helper(&gobject_, data, notify_func);
-}
-
-
-/**** Glib::Private ********************************************************/
-
-// static
-template <class T>
-void Private<T>::delete_ptr(void* data)
-{
- delete static_cast<T*>(data);
-}
-
-/** This is only for use by glibmm itself.
- */
-GPrivate* GPrivate_new_helper(GDestroyNotify notify);
-
-template <class T> inline
-Private<T>::Private(typename Private<T>::DestructorFunc destructor_func)
-:
- gobject_ (GPrivate_new_helper(destructor_func))
-{}
-
-template <class T> inline
-T* Private<T>::get()
-{
- return static_cast<T*>(g_private_get(gobject_));
-}
-
-template <class T> inline
-void Private<T>::set(T* data)
-{
- g_private_set(gobject_, data);
-}
-
-#endif /* DOXYGEN_SHOULD_SKIP_THIS */
-
-} // namespace Glib
-
diff --git a/glib/src/threads.ccg b/glib/src/threads.ccg
deleted file mode 100644
index 8b66493c..00000000
--- a/glib/src/threads.ccg
+++ /dev/null
@@ -1,302 +0,0 @@
-/* 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 Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser 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.h>
-
-/* Why reinterpret_cast<Thread*>(gobject) is needed:
- *
- * A Thread instance is in fact always a GThread instance.
- * Unfortunately, GThread cannot be a member of Thread,
- * because it is an opaque struct. Also, the C interface does not provide
- * any hooks to install a destroy notification handler, thus we cannot
- * wrap it dynamically either.
- *
- * The cast works because Thread does not have any member data, and
- * it is impossible to derive from it. This is ensured by not implementing
- * the (private) default constructor.
- * This trick is used also in classes declared as _CLASS_OPAQUE_REFCOUNTED.
- */
-
-namespace
-{
-
-extern "C" {
-
-static void*
-call_thread_entry_slot(void* data)
-{
- const auto slot = reinterpret_cast<sigc::slot_base*>(data);
-
- try
- {
- // Recreate the specific slot.
- (*static_cast<sigc::slot<void()>*>(slot))();
- }
- catch (Glib::Threads::Thread::Exit&)
- {
- // Just exit from the thread. The Threads::Thread::Exit exception
- // is our sane C++ replacement of g_thread_exit().
- }
- catch (...)
- {
- Glib::exception_handlers_invoke();
- }
-
- delete slot;
- return nullptr;
-}
-
-} // extern "C"
-
-} // anonymous namespace
-
-namespace Glib
-{
-
-namespace Threads
-{
-
-/**** Glib::Threads::Thread ************************************************/
-
-// static
-Thread*
-Thread::create(const sigc::slot<void()>& slot, const std::string& name)
-{
- // Make a copy of slot on the heap.
- const auto slot_copy = new sigc::slot<void()>(slot);
-
- GError* error = nullptr;
- auto thread = g_thread_try_new(
- name.empty() ? nullptr : name.c_str(), &call_thread_entry_slot, slot_copy, &error);
-
- if (error)
- {
- delete slot_copy;
- Glib::Error::throw_exception(error);
- }
- if (!thread)
- {
- delete slot_copy;
- }
- return reinterpret_cast<Thread*>(thread);
-}
-
-// static
-Thread*
-Thread::create(const sigc::slot<void()>& slot)
-{
- return create(slot, std::string());
-}
-
-// static
-Thread*
-Thread::self()
-{
- return reinterpret_cast<Thread*>(g_thread_self());
-}
-
-void
-Thread::join()
-{
- g_thread_join(reinterpret_cast<GThread*>(this));
-}
-
-// static
-void
-Thread::yield()
-{
- g_thread_yield();
-}
-
-GThread*
-Thread::gobj()
-{
- return reinterpret_cast<GThread*>(this);
-}
-
-const GThread*
-Thread::gobj() const
-{
- return reinterpret_cast<const GThread*>(this);
-}
-
-Thread*
-wrap(GThread* gobject)
-{
- return reinterpret_cast<Thread*>(gobject);
-}
-
-/**** Glib::Threads::Mutex *************************************************/
-
-Mutex::Mutex()
-{
- g_mutex_init(&gobject_);
-}
-
-Mutex::~Mutex()
-{
- g_mutex_clear(&gobject_);
-}
-
-void
-Mutex::lock()
-{
- g_mutex_lock(&gobject_);
-}
-
-bool
-Mutex::trylock()
-{
- return g_mutex_trylock(&gobject_);
-}
-
-void
-Mutex::unlock()
-{
- g_mutex_unlock(&gobject_);
-}
-
-Mutex*
-wrap(GMutex* gobject)
-{
- return reinterpret_cast<Mutex*>(gobject);
-}
-
-/**** Glib::Threads::RecMutex **********************************************/
-
-RecMutex::RecMutex()
-{
- g_rec_mutex_init(&gobject_);
-}
-
-RecMutex::~RecMutex()
-{
- g_rec_mutex_clear(&gobject_);
-}
-
-void
-RecMutex::lock()
-{
- g_rec_mutex_lock(&gobject_);
-}
-
-bool
-RecMutex::trylock()
-{
- return g_rec_mutex_trylock(&gobject_);
-}
-
-void
-RecMutex::unlock()
-{
- g_rec_mutex_unlock(&gobject_);
-}
-
-RecMutex*
-wrap(GRecMutex* gobject)
-{
- return reinterpret_cast<RecMutex*>(gobject);
-}
-
-/**** Glib::Threads::RWLock ************************************************/
-
-void
-RWLock::reader_lock()
-{
- g_rw_lock_reader_lock(&gobject_);
-}
-
-bool
-RWLock::reader_trylock()
-{
- return g_rw_lock_reader_trylock(&gobject_);
-}
-
-void
-RWLock::reader_unlock()
-{
- g_rw_lock_reader_unlock(&gobject_);
-}
-
-void
-RWLock::writer_lock()
-{
- g_rw_lock_writer_lock(&gobject_);
-}
-
-bool
-RWLock::writer_trylock()
-{
- return g_rw_lock_writer_trylock(&gobject_);
-}
-
-void
-RWLock::writer_unlock()
-{
- g_rw_lock_writer_unlock(&gobject_);
-}
-
-RWLock::RWLock()
-{
- g_rw_lock_init(&gobject_);
-}
-
-RWLock::~RWLock()
-{
- g_rw_lock_clear(&gobject_);
-}
-
-/**** Glib::Threads::Cond **************************************************/
-
-Cond::Cond()
-{
- g_cond_init(&gobject_);
-}
-
-Cond::~Cond()
-{
- g_cond_clear(&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::wait_until(Mutex& mutex, gint64 end_time)
-{
- return g_cond_wait_until(&gobject_, mutex.gobj(), end_time);
-}
-
-} // namespace Threads
-
-} // namespace Glib
diff --git a/glib/src/threads.hg b/glib/src/threads.hg
deleted file mode 100644
index afd8877f..00000000
--- a/glib/src/threads.hg
+++ /dev/null
@@ -1,932 +0,0 @@
-/* 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 Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-_DEFS(glibmm,glib)
-_CONFIGINCLUDE(glibmmconfig.h)
-
-_IS_DEPRECATED // This whole file is deprecated.
-
-#m4 _PUSH(SECTION_CC_PRE_INCLUDES)
-// Don't let glibmm.h include thread.h. Pretend that it's already included.
-// glib.h can then be included with G_DISABLE_DEPRECATED defined, and
-// the compiler can react if deprecated glib functions are used.
-#define _GLIBMM_THREAD_H
-#m4 _POP()
-
-#include <glib.h>
-#include <glibmm/error.h>
-#include <sigc++/sigc++.h>
-#include <string>
-#include <cstddef>
-
-namespace Glib
-{
-
-/**
- * @deprecated The entire Glib::Threads API is deprecated in favor of the
- * standard C++ concurrency API in C++11 and C++14.
- */
-namespace Threads
-{
-//The GMMPROC_EXTRA_NAMESPACE() macro is a hint to generate_wrap_init.pl to put it in the Threads sub-namespace
-_GMMPROC_EXTRA_NAMESPACE(Threads)
-
-/** @defgroup Threads Threads
- * %Thread abstraction; including threads, different mutexes,
- * conditions and thread private data.
- *
- * @deprecated The entire Glib::Threads API is deprecated in favor of the
- * standard C++ concurrency API in C++11 and C++14.
- * @{
- */
-
-/// @deprecated Please use std::lock_guard or std::unique_lock instead.
-enum NotLock { NOT_LOCK };
-
-/// @deprecated Please use std::lock_guard or std::unique_lock instead.
-enum TryLock { TRY_LOCK };
-
-class Mutex;
-class RecMutex;
-class RWLock;
-
-/** %Exception class for thread-related errors.
- *
- * @deprecated Please use std::lock_guard or std::unique_lock instead.
- */
-_WRAP_GERROR(ThreadError, GThreadError, G_THREAD_ERROR, NO_GTYPE)
-
-
-/** Represents a running thread.
- * An instance of this class can only be obtained with create(), self(),
- * or wrap(GThread*). It's not possible to delete a Thread object.
- * You must call join() to avoid a memory leak.
- *
- * @note g_thread_exit() is not wrapped, because that function exits a thread
- * without any cleanup. That's especially dangerous in C++ code, since the
- * destructors of automatic objects won't be invoked. Instead, you can throw
- * a Threads::Thread::Exit exception, which will be caught by the internal thread
- * entry function.
- *
- * @note The thread entry slot doesn't have the void* return value that a
- * GThreadFunc has. If you want to return any data from your thread,
- * you can pass an additional output argument to the thread's entry slot.
- *
- * @deprecated Please use std::thread instead.
- */
-class Thread
-{
-public:
-
- Thread(const Thread&) = delete;
- Thread& operator=(const Thread&) = delete;
-
- class Exit;
-
- //See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
- // TODO: At the next ABI break, consider changing const sigc::slot<void()>& slot
- // to const std::function<void()>& func, if it can be assumed that all supported
- // compilers understand the C++11 template class std::function<>.
- /** Creates a new thread.
- * You can wait for this thread's termination by calling join().
- *
- * The new thread executes the function or method @a slot points to. You can
- * pass additional arguments using sigc::bind(). If the thread was created
- * successfully, it is returned, otherwise a Threads::ThreadError exception is thrown.
- *
- * Because sigc::trackable is not thread-safe, if the slot represents a
- * non-static class method and is created by sigc::mem_fun(), the class concerned
- * should not derive from sigc::trackable. You can use, say, boost::bind() or,
- * in C++11, std::bind() or a C++11 lambda expression instead of sigc::mem_fun().
- *
- * @param slot A slot to execute in the new thread.
- * @return The new Thread* on success.
- * @throw Glib::Threads::ThreadError
- */
- static Thread* create(const sigc::slot<void()>& slot);
-
- // TODO: At next ABI break, remove the single parameter create
- // method and default name to std::string()
-
- /** Creates a new named thread.
- * You can wait for this thread's termination by calling join().
- *
- * The new thread executes the function or method @a slot points to. You can
- * pass additional arguments using sigc::bind(). If the thread was created
- * successfully, it is returned, otherwise a Threads::ThreadError exception is thrown.
- *
- * Because sigc::trackable is not thread-safe, if the slot represents a
- * non-static class method and is created by sigc::mem_fun(), the class concerned
- * should not derive from sigc::trackable. You can use, say, boost::bind() or,
- * in C++11, std::bind() or a C++11 lambda expression instead of sigc::mem_fun().
- *
- * The @a name can be useful for discriminating threads in a debugger.
- * It is not used for other purposes and does not have to be unique.
- * Some systems restrict the length of @a name to 16 bytes.
- *
- * @param slot A slot to execute in the new thread.
- * @param name A name for the new thread.
- * @return The new Thread* on success.
- * @throw Glib::Threads::ThreadError
- *
- * @newin{2,36}
- */
- static Thread* create(const sigc::slot<void()>& slot, const std::string& name);
-
- /** Returns the Thread* corresponding to the calling thread.
- * @return The current thread.
- */
- static Thread* self();
-
- /** Waits until the thread finishes.
- * Waits until the thread finishes, i.e. the slot, as given to create(),
- * returns or g_thread_exit() is called by the thread. (Calling
- * g_thread_exit() in a C++ program should be avoided.) All resources of
- * the thread including the Glib::Threads::Thread object are released.
- */
- void join();
-
- /** Gives way to other threads waiting to be scheduled.
- * This function is often used as a method to make busy wait less evil. But
- * in most cases, you will encounter, there are better methods to do that.
- * So in general you shouldn't use this function.
- */
- static void yield();
-
- GThread* gobj();
- const GThread* gobj() const;
-
-private:
- // Glib::Thread can neither be constructed nor deleted.
- Thread();
- void operator delete(void*, std::size_t);
-};
-
-/** %Exception class used to exit from a thread.
- * @code
- * throw Glib::Threads::Thread::Exit();
- * @endcode
- * Write this if you want to exit from a thread created by Threads::Thread::create().
- * Of course you must make sure not to catch Threads::Thread::Exit by accident, i.e.
- * when using <tt>catch(...)</tt> somewhere in your code.
- *
- * @deprecated Please use std::thread instead.
- */
-class Thread::Exit
-{};
-
-/** A C++ wrapper for the C object.
- *
- * @param gobject The C instance.
- * @return The C++ wrapper.
- *
- * @relates Glib::Threads::Thread
- *
- * @deprecated Please use std::thread instead.
- */
-Thread* wrap(GThread* gobject);
-
-/** Represents a mutex (mutual exclusion).
- * It can be used to protect data against shared access. Try to use
- * Mutex::Lock instead of calling lock() and unlock() directly&nbsp;--
- * it will make your life much easier.
- *
- * @note Glib::Threads::Mutex is not recursive, i.e. a thread will deadlock, if it
- * already has locked the mutex while calling lock(). Use Glib::Threads::RecMutex
- * instead, if you need recursive mutexes.
- *
- * @deprecated Please use std::mutex instead.
- */
-class Mutex
-{
-public:
- class Lock;
-
- Mutex();
-
- Mutex(const Mutex&) = delete;
- Mutex& operator=(const Mutex&) = delete;
-
- ~Mutex();
-
- /** Locks the mutex.
- * If mutex is already locked by another thread, the current thread will
- * block until mutex is unlocked by the other thread.
- * @see Mutex::Lock
- */
- void lock();
-
- /** Tries to lock the mutex.
- * If the mutex is already locked by another thread, it immediately returns
- * @c false. Otherwise it locks the mutex and returns @c true.
- * @return Whether the mutex could be locked.
- * @see Mutex::Lock
- */
- bool trylock();
-
- /** Unlocks the mutex.
- * If another thread is blocked in a lock() call for this mutex, it will be
- * woken and can lock the mutex itself.
- * @see Mutex::Lock
- */
- void unlock();
-
- GMutex* gobj() { return &gobject_; }
-
-private:
- GMutex gobject_;
-};
-
-/** Utility class for exception-safe mutex locking.
- * @par Usage example:
- * @code
- * {
- * Glib::Threads::Mutex::Lock lock(mutex); // calls mutex.lock()
- * do_something();
- * } // the destructor calls mutex.unlock()
- * @endcode
- * As you can see, the compiler takes care of the unlocking. This is not
- * only exception-safe but also much less error-prone. You could even
- * <tt>return</tt> while still holding the lock and it will be released
- * properly.
- *
- * @deprecated Please use std::lock_guard or std::unique_lock instead.
- */
-class Mutex::Lock
-{
-public:
- explicit inline Lock(Mutex& mutex);
- inline Lock(Mutex& mutex, NotLock);
- inline Lock(Mutex& mutex, TryLock);
-
- Lock(const Mutex::Lock&) = delete;
- Mutex::Lock& operator=(const Mutex::Lock&) = delete;
-
- inline ~Lock();
-
- inline void acquire();
- inline bool try_acquire();
- inline void release();
- inline bool locked() const;
-
-private:
- Mutex& mutex_;
- bool locked_;
-};
-
-/** A C++ wrapper for the C object.
- * Do not use operator delete on the returned pointer. If the caller owns the
- * GMutex object, the caller must destroy it in the same way as if this function
- * had not been called.
- *
- * @param gobject The C instance.
- * @result The GMutex* cast to a Glib::Threads::Mutex*.
- *
- * @relates Glib::Threads::Mutex
- */
-Mutex* wrap(GMutex* gobject);
-
-/** This represents a recursive mutex.
- * It is similar to a Mutex with the difference
- * that it is possible to lock a RecMutex multiple times in the same
- * thread without deadlock. When doing so, care has to be taken to
- * unlock the recursive mutex as often as it has been locked.
- *
- * @deprecated Please use std::recursive_mutex instead.
- */
-class RecMutex
-{
-public:
- class Lock;
-
- RecMutex();
-
- RecMutex(const RecMutex&) = delete;
- RecMutex& operator=(const RecMutex&) = delete;
-
- ~RecMutex();
-
- void lock();
- bool trylock();
- void unlock();
-
- GRecMutex* gobj() { return &gobject_; }
-
-private:
- GRecMutex gobject_;
-};
-
-/** Utility class for exception-safe locking of recursive mutexes.
- *
- * @deprecated Please use std::lock_guard or std::unique_lock instead.
- */
-class RecMutex::Lock
-{
-public:
- explicit inline Lock(RecMutex& mutex);
- inline Lock(RecMutex& mutex, NotLock);
- inline Lock(RecMutex& mutex, TryLock);
-
- Lock(const RecMutex::Lock&) = delete;
- RecMutex::Lock& operator=(const RecMutex::Lock&) = delete;
-
- inline ~Lock();
-
- inline void acquire();
- inline bool try_acquire();
- inline void release();
- inline bool locked() const;
-
-private:
- RecMutex& mutex_;
- bool locked_;
-};
-
-/** A C++ wrapper for the C object.
- * Do not use operator delete on the returned pointer. If the caller owns the
- * GRecMutex object, the caller must destroy it in the same way as if this function
- * had not been called.
- *
- * @param gobject The C instance.
- * @result The GRecMutex* cast to a Glib::Threads::RecMutex*.
- *
- * @relates Glib::Threads::RecMutex
- */
-RecMutex* wrap(GRecMutex* gobject);
-
-/** This represents a reader-writer lock.
- * It is similar to a Mutex in that it allows
- * multiple threads to coordinate access to a shared resource.
- *
- * The difference to a mutex is that a reader-writer lock discriminates
- * between read-only ('reader') and full ('writer') access. While only
- * one thread at a time is allowed write access (by holding the 'writer'
- * lock via writer_lock()), multiple threads can gain
- * simultaneous read-only access (by holding the 'reader' lock via
- * reader_lock()).
- *
- * @deprecated Please use std::lock_guard or std::unique_lock instead, with std::shared_timed_mutex.
- */
-class RWLock
-{
-public:
- class ReaderLock;
- class WriterLock;
-
- RWLock();
-
- RWLock(const RWLock&) = delete;
- RWLock& operator=(const RWLock&) = delete;
-
- ~RWLock();
-
- void reader_lock();
- bool reader_trylock();
- void reader_unlock();
-
- void writer_lock();
- bool writer_trylock();
- void writer_unlock();
-
- GRWLock* gobj() { return &gobject_; }
-
-private:
- GRWLock gobject_;
-};
-
-/** Utility class for exception-safe locking of read/write locks.
- *
- * @deprecated Please use std::lock_guard or std::unique_lock instead, with std::shared_timed_mutex.
- */
-class RWLock::ReaderLock
-{
-public:
- explicit inline ReaderLock(RWLock& rwlock);
- inline ReaderLock(RWLock& rwlock, NotLock);
- inline ReaderLock(RWLock& rwlock, TryLock);
-
- ReaderLock(const RWLock::ReaderLock&) = delete;
- RWLock::ReaderLock& operator=(const RWLock::ReaderLock&) = delete;
-
- inline ~ReaderLock();
-
- inline void acquire();
- inline bool try_acquire();
- inline void release();
- inline bool locked() const;
-
-private:
- RWLock& rwlock_;
- bool locked_;
-};
-
-/** Utility class for exception-safe locking of read/write locks.
- *
- * @deprecated Please use std::lock_guard or std::unique_lock instead, with std::shared_timed_mutex.
- */
-class RWLock::WriterLock
-{
-public:
- explicit inline WriterLock(RWLock& rwlock);
- inline WriterLock(RWLock& rwlock, NotLock);
- inline WriterLock(RWLock& rwlock, TryLock);
-
- WriterLock(const RWLock::WriterLock&) = delete;
- RWLock::WriterLock& operator=(const RWLock::WriterLock&) = delete;
-
- inline ~WriterLock();
-
- inline void acquire();
- inline bool try_acquire();
- inline void release();
- inline bool locked() const;
-
-private:
- RWLock& rwlock_;
- bool locked_;
-};
-
-/** An opaque data structure to represent a condition.
- * A @a Cond is an object that threads can block on, if they find a certain
- * condition to be false. If other threads change the state of this condition
- * they can signal the @a Cond, such that the waiting thread is woken up.
- *
- * @deprecated Please use std::condition_variable instead.
- *
- * @par Usage example:
- * @code
- * Glib::Threads::Cond data_cond;
- * Glib::Threads::Mutex data_mutex;
- * void* current_data = nullptr;
- *
- * void push_data(void* data)
- * {
- * Glib::Threads::Mutex::Lock lock(data_mutex);
- *
- * current_data = data;
- * data_cond.signal();
- * }
- *
- * void* pop_data()
- * {
- * Glib::Threads::Mutex::Lock lock(data_mutex);
- *
- * while (!current_data)
- * data_cond.wait(data_mutex);
- *
- * void* const data = current_data;
- * current_data = nullptr;
- *
- * return data;
- * }
- * @endcode
- */
-class Cond
-{
-public:
- Cond();
-
- Cond(const Cond&) = delete;
- Cond& operator=(const Cond&) = delete;
-
- ~Cond();
-
- /** If threads are waiting for this @a Cond, exactly one of them is woken up.
- * It is good practice to hold the same lock as the waiting thread, while calling
- * this method, though not required.
- */
- void signal();
-
- /** If threads are waiting for this @a Cond, all of them are woken up.
- * It is good practice to hold the same lock as the waiting threads, while calling
- * this method, though not required.
- */
- void broadcast();
-
- /** Waits until this thread is woken up on this @a Cond.
- * The mutex is unlocked before falling asleep and locked again before resuming.
- *
- * @param mutex A @a Mutex that is currently locked.
- *
- * @note It is important to use the @a wait() and @a wait_until() methods
- * only inside a loop, which checks for the condition to be true as it is not
- * guaranteed that the waiting thread will find it fulfilled, even if the signaling
- * thread left the condition in that state. This is because another thread can have
- * altered the condition, before the waiting thread got the chance to be woken up,
- * even if the condition itself is protected by a @a Mutex.
- */
- void wait(Mutex& mutex);
-
- /** Waits until this thread is woken up on this @a Cond, but not longer
- * than until the time specified by @a end_time.
- * The mutex is unlocked before falling asleep and locked again before resuming.
- *
- * @par Usage example:
- * Extending the example presented in the documentation of class Cond.
- * @code
- * void* pop_data_timed()
- * {
- * Glib::Threads::Mutex::Lock lock(data_mutex);
- *
- * // Wait at most 5 seconds.
- * const gint64 end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
- * while (!current_data)
- * if (!data_cond.wait_until(data_mutex, end_time)
- * return nullptr; // timeout
- *
- * void* const data = current_data;
- * current_data = nullptr;
- *
- * return data;
- * }
- * @endcode
- * The end time is calculated once, before entering the loop, and reused.
- * This is the motivation behind the use of absolute time. If a relative time
- * of 5 seconds were passed directly to the call and a spurious wakeup
- * occurred, the program would have to start over waiting again, which would
- * lead to a total wait time of more than 5 seconds.
- *
- * @param mutex A @a Mutex that is currently locked.
- * @param end_time The monotonic time to wait until, in microseconds.
- * See g_get_monotonic_time().
- * @return <tt>true</tt> if the condition variable was signalled (or in the case
- * of a spurious wakeup), <tt>false</tt> if @a end_time has passed.
- *
- * @note It is important to use the @a wait() and @a wait_until() methods
- * only inside a loop, which checks for the condition to be true as it is not
- * guaranteed that the waiting thread will find it fulfilled, even if the signaling
- * thread left the condition in that state. This is because another thread can have
- * altered the condition, before the waiting thread got the chance to be woken up,
- * even if the condition itself is protected by a @a Mutex.
- */
- bool wait_until(Mutex& mutex, gint64 end_time);
-
- GCond* gobj() { return &gobject_; }
-
-private:
- GCond gobject_;
-};
-
-/** Thread-local data pointer.
- *
- * It is recommended that all instances of this class are statically allocated.
- * The first time an instance is used (get(), set() or replace() is called)
- * glib allocates a scarce OS resource that cannot be deallocated.
- *
- * @deprecated Please use the thread_local keyword instead.
- */
-template <class T>
-class Private
-{
-public:
- Private(const Private<T>&) = delete;
- Private<T>& operator=(const Private<T>&) = delete;
-
- using DestructorFunc = void (*) (void*);
-
- /** Deletes static_cast<T*>(data)
- */
- static void delete_ptr(void* data);
-
- /** Constructor.
- *
- * @param destructor_func Function pointer, or <tt>nullptr</tt>. If @a destructor_func is not <tt>nullptr</tt>
- * and the stored data pointer is not <tt>nullptr</tt>, this function is called when replace()
- * is called and when the thread exits.
- */
- explicit inline Private(DestructorFunc destructor_func = &Private<T>::delete_ptr);
-
- /** Gets the pointer stored in the calling thread.
- *
- * @return If no value has yet been set in this thread, <tt>nullptr</tt> is returned.
- */
- inline T* get();
-
- /** Sets the pointer in the calling thread without calling <tt>destructor_func()</tt>.
- */
- inline void set(T* data);
-
- /** Sets the pointer in the calling thread and calls <tt>destructor_func()</tt>.
- * If a function pointer (and not <tt>nullptr</tt>) was specified in the constructor, and
- * the stored data pointer before the call to replace() is not <tt>nullptr</tt>, then
- * <tt>destructor_func()</tt> is called with this old pointer value.
- *
- * @newin{2,32}
- */
- inline void replace(T* data);
-
- GPrivate* gobj() { return gobject_; }
-
-private:
- GPrivate gobject_;
-};
-
-/** @} group Threads */
-
-/*! A glibmm thread example.
- * @example thread/thread.cc
- */
-
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
-
-/***************************************************************************/
-/* inline implementation */
-/***************************************************************************/
-
-/**** Glib::Threads::Mutex::Lock *******************************************/
-
-inline
-Mutex::Lock::Lock(Mutex& mutex)
-:
- mutex_ (mutex),
- locked_ (true)
-{
- mutex_.lock();
-}
-
-inline
-Mutex::Lock::Lock(Mutex& mutex, NotLock)
-:
- mutex_ (mutex),
- locked_ (false)
-{}
-
-inline
-Mutex::Lock::Lock(Mutex& mutex, TryLock)
-:
- mutex_ (mutex),
- locked_ (mutex.trylock())
-{}
-
-inline
-Mutex::Lock::~Lock()
-{
- if(locked_)
- mutex_.unlock();
-}
-
-inline
-void Mutex::Lock::acquire()
-{
- mutex_.lock();
- locked_ = true;
-}
-
-inline
-bool Mutex::Lock::try_acquire()
-{
- locked_ = mutex_.trylock();
- return locked_;
-}
-
-inline
-void Mutex::Lock::release()
-{
- mutex_.unlock();
- locked_ = false;
-}
-
-inline
-bool Mutex::Lock::locked() const
-{
- return locked_;
-}
-
-
-/**** Glib::Threads::RecMutex::Lock ****************************************/
-
-inline
-RecMutex::Lock::Lock(RecMutex& mutex)
-:
- mutex_ (mutex),
- locked_ (true)
-{
- mutex_.lock();
-}
-
-inline
-RecMutex::Lock::Lock(RecMutex& mutex, NotLock)
-:
- mutex_ (mutex),
- locked_ (false)
-{}
-
-inline
-RecMutex::Lock::Lock(RecMutex& mutex, TryLock)
-:
- mutex_ (mutex),
- locked_ (mutex.trylock())
-{}
-
-inline
-RecMutex::Lock::~Lock()
-{
- if(locked_)
- mutex_.unlock();
-}
-
-inline
-void RecMutex::Lock::acquire()
-{
- mutex_.lock();
- locked_ = true;
-}
-
-inline
-bool RecMutex::Lock::try_acquire()
-{
- locked_ = mutex_.trylock();
- return locked_;
-}
-
-inline
-void RecMutex::Lock::release()
-{
- mutex_.unlock();
- locked_ = false;
-}
-
-inline
-bool RecMutex::Lock::locked() const
-{
- return locked_;
-}
-
-
-/**** Glib::Threads::RWLock::ReaderLock ************************************/
-
-inline
-RWLock::ReaderLock::ReaderLock(RWLock& rwlock)
-:
- rwlock_ (rwlock),
- locked_ (true)
-{
- rwlock_.reader_lock();
-}
-
-inline
-RWLock::ReaderLock::ReaderLock(RWLock& rwlock, NotLock)
-:
- rwlock_ (rwlock),
- locked_ (false)
-{}
-
-inline
-RWLock::ReaderLock::ReaderLock(RWLock& rwlock, TryLock)
-:
- rwlock_ (rwlock),
- locked_ (rwlock.reader_trylock())
-{}
-
-inline
-RWLock::ReaderLock::~ReaderLock()
-{
- if(locked_)
- rwlock_.reader_unlock();
-}
-
-inline
-void RWLock::ReaderLock::acquire()
-{
- rwlock_.reader_lock();
- locked_ = true;
-}
-
-inline
-bool RWLock::ReaderLock::try_acquire()
-{
- locked_ = rwlock_.reader_trylock();
- return locked_;
-}
-
-inline
-void RWLock::ReaderLock::release()
-{
- rwlock_.reader_unlock();
- locked_ = false;
-}
-
-inline
-bool RWLock::ReaderLock::locked() const
-{
- return locked_;
-}
-
-
-/**** Glib::Threads::RWLock::WriterLock ************************************/
-
-inline
-RWLock::WriterLock::WriterLock(RWLock& rwlock)
-:
- rwlock_ (rwlock),
- locked_ (true)
-{
- rwlock_.writer_lock();
-}
-
-inline
-RWLock::WriterLock::WriterLock(RWLock& rwlock, NotLock)
-:
- rwlock_ (rwlock),
- locked_ (false)
-{}
-
-inline
-RWLock::WriterLock::WriterLock(RWLock& rwlock, TryLock)
-:
- rwlock_ (rwlock),
- locked_ (rwlock.writer_trylock())
-{}
-
-inline
-RWLock::WriterLock::~WriterLock()
-{
- if(locked_)
- rwlock_.writer_unlock();
-}
-
-inline
-void RWLock::WriterLock::acquire()
-{
- rwlock_.writer_lock();
- locked_ = true;
-}
-
-inline
-bool RWLock::WriterLock::try_acquire()
-{
- locked_ = rwlock_.writer_trylock();
- return locked_;
-}
-
-inline
-void RWLock::WriterLock::release()
-{
- rwlock_.writer_unlock();
- locked_ = false;
-}
-
-inline
-bool RWLock::WriterLock::locked() const
-{
- return locked_;
-}
-
-/**** Glib::Threads::Private<T> ********************************************/
-
-// static
-template <class T>
-void Private<T>::delete_ptr(void* data)
-{
- delete static_cast<T*>(data);
-}
-
-template <class T> inline
-Private<T>::Private(typename Private<T>::DestructorFunc destructor_func)
-{
- // gobject_ = G_PRIVATE_INIT(destructor_func);
- // does not compile with --enable-warnings=fatal.
- // GPrivate is a struct, and G_PRIVATE_INIT is an initializer of type { ... }.
- // G_PRIVATE_INIT can be used only in initializations.
- const GPrivate temp = G_PRIVATE_INIT(destructor_func);
- gobject_ = temp;
-}
-
-template <class T> inline
-T* Private<T>::get()
-{
- return static_cast<T*>(g_private_get(&gobject_));
-}
-
-template <class T> inline
-void Private<T>::set(T* data)
-{
- g_private_set(&gobject_, data);
-}
-
-template <class T> inline
-void Private<T>::replace(T* data)
-{
- g_private_replace(&gobject_, data);
-}
-
-#endif /* DOXYGEN_SHOULD_SKIP_THIS */
-
-} //namespace Threads
-
-} // namespace Glib