[glibmm] Build: Use Threads::Private hen thread_local keyword is not supported.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] Build: Use Threads::Private hen thread_local keyword is not supported.
- Date: Mon, 28 Mar 2016 20:04:13 +0000 (UTC)
commit 63c9c986ceb1e66c418f5863d74f078f0ec567ed
Author: Tom Schoonjans <Tom Schoonjans diamond ac uk>
Date: Mon Mar 28 16:05:01 2016 +0100
Build: Use Threads::Private hen thread_local keyword is not supported.
This fix is necessary for compilation of glibmm on OS X, as the clang
compiler that currently ships with XCode currently does not support this
keyword. Bug #759791
configure.ac | 6 ++++++
glib/glibmm/dispatcher.cc | 29 +++++++++++++++++++++++++++++
glib/glibmm/exceptionhandler.cc | 19 +++++++++++++++++++
3 files changed, 54 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 52a001e..70f61ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -106,6 +106,12 @@ GLIBMM_CXX_CAN_USE_NAMESPACES_INSIDE_EXTERNC
GLIBMM_CXX_ALLOWS_STATIC_INLINE_NPOS
GLIBMM_C_STD_TIME_T_IS_NOT_INT32
+# check for thread_local support
+AC_MSG_CHECKING([whether the thread_local keyword is supported])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([thread_local int i=0;], [])],
+ AC_DEFINE([GLIBMM_THREAD_LOCAL_ENABLED], [1], [thread_local keyword is available])
+ AC_MSG_RESULT([yes]) , AC_MSG_RESULT([no]))
+
MM_ARG_ENABLE_DOCUMENTATION
MM_ARG_WITH_TAGFILE_DOC([libstdc++.tag], [mm-common-libstdc++])
MM_ARG_WITH_TAGFILE_DOC([libsigc++-2.0.tag], [sigc++-2.0])
diff --git a/glib/glibmm/dispatcher.cc b/glib/glibmm/dispatcher.cc
index 8525fbe..9ee3b0c 100644
--- a/glib/glibmm/dispatcher.cc
+++ b/glib/glibmm/dispatcher.cc
@@ -15,6 +15,10 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#ifndef GLIBMM_THREAD_LOCAL_ENABLED
+#include <glibmm/threads.h>
+#endif
+
#include <glibmm/dispatcher.h>
#include <glibmm/exceptionhandler.h>
#include <glibmm/fileutils.h>
@@ -143,7 +147,11 @@ protected:
explicit DispatchNotifier(const Glib::RefPtr<MainContext>& context);
private:
+#ifdef GLIBMM_THREAD_LOCAL_ENABLED
static thread_local DispatchNotifier* thread_specific_instance_;
+#else
+ static Glib::Threads::Private<DispatchNotifier> thread_specific_instance_;
+#endif
std::set<const Dispatcher*> deleted_dispatchers_;
@@ -166,7 +174,12 @@ private:
/**** Glib::DispatchNotifier ***********************************************/
// static
+
+#ifdef GLIBMM_THREAD_LOCAL_ENABLED
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_(),
@@ -269,12 +282,20 @@ DispatchNotifier*
DispatchNotifier::reference_instance(
const Glib::RefPtr<MainContext>& context, const Dispatcher* dispatcher)
{
+#ifdef GLIBMM_THREAD_LOCAL_ENABLED
DispatchNotifier* instance = thread_specific_instance_;
+#else
+ DispatchNotifier* instance = thread_specific_instance_.get();
+#endif
if (!instance)
{
instance = new DispatchNotifier(context);
+#ifdef GLIBMM_THREAD_LOCAL_ENABLED
thread_specific_instance_ = instance;
+#else
+ thread_specific_instance_.replace(instance);
+#endif
}
else
{
@@ -302,7 +323,11 @@ DispatchNotifier::reference_instance(
void
DispatchNotifier::unreference_instance(DispatchNotifier* notifier, const Dispatcher* dispatcher)
{
+#ifdef GLIBMM_THREAD_LOCAL_ENABLED
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);
@@ -319,8 +344,12 @@ DispatchNotifier::unreference_instance(DispatchNotifier* notifier, const Dispatc
{
g_return_if_fail(instance->ref_count_ == 0); // could be < 0 if messed up
+#ifdef GLIBMM_THREAD_LOCAL_ENABLED
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 c12e199..7311bbe 100644
--- a/glib/glibmm/exceptionhandler.cc
+++ b/glib/glibmm/exceptionhandler.cc
@@ -19,6 +19,9 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#ifndef GLIBMM_THREAD_LOCAL_ENABLED
+#include <glibmm/threads.h>
+#endif
#include <glibmmconfig.h>
#include <glibmm/error.h>
#include <glibmm/exceptionhandler.h>
@@ -33,7 +36,11 @@ typedef sigc::signal<void> HandlerList;
// Each thread has its own list of exception handlers
// to avoid thread synchronization problems.
+#ifdef GLIBMM_THREAD_LOCAL_ENABLED
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)
@@ -85,12 +92,20 @@ namespace Glib
sigc::connection
add_exception_handler(const sigc::slot<void>& slot)
{
+#ifdef GLIBMM_THREAD_LOCAL_ENABLED
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_THREAD_LOCAL_ENABLED
thread_specific_handler_list = handler_list;
+#else
+ thread_specific_handler_list.set(handler_list);
+#endif
}
handler_list->slots().push_front(slot);
@@ -114,7 +129,11 @@ 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_THREAD_LOCAL_ENABLED
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->slots().begin();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]