[glibmm] Glib::ObjectBase: Replace extra_object_base_data map by instance data



commit 3911557cb62ed055f16ece0a7a58cbbabe35ef6b
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Thu Nov 24 19:13:55 2016 +0100

    Glib::ObjectBase: Replace extra_object_base_data map by instance data
    
    * glib/glibmm/class.[cc|h]: Remove the clone_custom_type() overload without
    an interface_class_vector_type argument.
    * glib/glibmm/interface.cc:
    * glib/glibmm/object.cc:
    * glib/glibmm/objectbase.[cc|h]: Replace the std::map containing
    ExtraObjectBaseData with instance data in ObjectBase. The map was just a way
    of avoiding an ABI break, but now we can break ABI.
    The new data is a std::unique_ptr<Class::interface_class_vector_type> rather
    than a Class::interface_class_vector_type. It's a vector which is used only
    during a short period during object construction, and only for custom objects.
    With a pointer to the vector, it need not be created for the majority of
    objects, and if it is created, it can be deleted when it's no longer needed.
    * gio/src/application.ccg:
    * glib/glibmm/main.cc: Add #include <mutex> that should have been there before,
    but now became necessary, when it was removed from objectbase.h.

 gio/src/application.ccg   |    1 +
 glib/glibmm/class.cc      |    6 ------
 glib/glibmm/class.h       |   15 ---------------
 glib/glibmm/interface.cc  |    5 ++---
 glib/glibmm/main.cc       |    1 +
 glib/glibmm/object.cc     |   30 ++++--------------------------
 glib/glibmm/objectbase.cc |   23 ++++++++---------------
 glib/glibmm/objectbase.h  |   21 ++++-----------------
 8 files changed, 20 insertions(+), 82 deletions(-)
---
diff --git a/gio/src/application.ccg b/gio/src/application.ccg
index 785d050..97f1c27 100644
--- a/gio/src/application.ccg
+++ b/gio/src/application.ccg
@@ -21,6 +21,7 @@
 #include <giomm/init.h>
 #include <cstring> // std::memset()
 #include <map>
+#include <mutex>
 #include <vector>
 
 namespace // anonymous
diff --git a/glib/glibmm/class.cc b/glib/glibmm/class.cc
index 75b7d13..2f76aba 100644
--- a/glib/glibmm/class.cc
+++ b/glib/glibmm/class.cc
@@ -85,12 +85,6 @@ Class::register_derived_type(GType base_type, GTypeModule* module)
 }
 
 GType
-Class::clone_custom_type(const char* custom_type_name) const
-{
-  return clone_custom_type(custom_type_name, interface_class_vector_type());
-}
-
-GType
 Class::clone_custom_type(
   const char* custom_type_name, const interface_class_vector_type& interface_classes) const
 {
diff --git a/glib/glibmm/class.h b/glib/glibmm/class.h
index bc5a06a..813b467 100644
--- a/glib/glibmm/class.h
+++ b/glib/glibmm/class.h
@@ -1,9 +1,6 @@
-// -*- c++ -*-
 #ifndef _GLIBMM_CLASS_H
 #define _GLIBMM_CLASS_H
 
-/* $Id$ */
-
 /* Copyright 2001 Free Software Foundation
  * Copyright (C) 1998-2002 The gtkmm Development Team
  *
@@ -54,18 +51,6 @@ public:
 
   inline GType get_type() const;
 
-  // TODO: Remove this method at the next ABI/API break.
-  /** Register a static custom GType, derived from the parent of this class's type.
-   * The parent type of the registered custom type is the same C class as the parent
-   * of the get_type() type. If a type with the specified name is already registered,
-   * nothing is done. register_derived_type() must have been called.
-   * @param custom_type_name The name of the registered type is
-   *        "gtkmm__CustomObject_" + canonic(custom_type_name), where canonic()
-   *        replaces special characters with '+'.
-   * @return The registered type.
-   */
-  GType clone_custom_type(const char* custom_type_name) const;
-
   /// The type that holds pointers to the interfaces of custom types.
   using interface_class_vector_type = std::vector<const Interface_Class*>;
 
diff --git a/glib/glibmm/interface.cc b/glib/glibmm/interface.cc
index 0ce998b..62878d6 100644
--- a/glib/glibmm/interface.cc
+++ b/glib/glibmm/interface.cc
@@ -96,10 +96,9 @@ Interface::Interface(const Interface_Class& interface_class)
     }
     else // gobject_ == nullptr
     {
-      // The GObject is not instantiated yet. Add to the custom_interface_classes
+      // The GObject is not instantiated yet. Add to the custom_interface_classes_
       // and add the interface in the Glib::Object constructor.
-      std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
-      extra_object_base_data[this].custom_interface_classes.emplace_back(&interface_class);
+      custom_interface_classes_->emplace_back(&interface_class);
     }
   }
 }
diff --git a/glib/glibmm/main.cc b/glib/glibmm/main.cc
index 27464d3..c065b51 100644
--- a/glib/glibmm/main.cc
+++ b/glib/glibmm/main.cc
@@ -23,6 +23,7 @@
 #include <glibmm/iochannel.h>
 #include <algorithm>
 #include <map> // Needed until the next ABI break.
+#include <mutex>
 
 namespace
 {
diff --git a/glib/glibmm/object.cc b/glib/glibmm/object.cc
index e7f6f88..c4e0a6f 100644
--- a/glib/glibmm/object.cc
+++ b/glib/glibmm/object.cc
@@ -194,21 +194,10 @@ Object::Object()
 
   if (custom_type_name_ && !is_anonymous_custom_())
   {
-    Class::interface_class_vector_type custom_interface_classes;
-
-    {
-      std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
-      const extra_object_base_data_type::iterator iter = extra_object_base_data.find(this);
-      if (iter != extra_object_base_data.end())
-      {
-        custom_interface_classes = iter->second.custom_interface_classes;
-        extra_object_base_data.erase(iter);
-      }
-    }
-
     object_class_.init();
     // This creates a type that is derived (indirectly) from GObject.
-    object_type = object_class_.clone_custom_type(custom_type_name_, custom_interface_classes);
+    object_type = object_class_.clone_custom_type(custom_type_name_, *custom_interface_classes_);
+    custom_interface_classes_.reset(nullptr);
   }
 
   void* const new_object = g_object_newv(object_type, 0, nullptr);
@@ -227,20 +216,9 @@ Object::Object(const Glib::ConstructParams& construct_params)
 
   if (custom_type_name_ && !is_anonymous_custom_())
   {
-    Class::interface_class_vector_type custom_interface_classes;
-
-    {
-      std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
-      const extra_object_base_data_type::iterator iter = extra_object_base_data.find(this);
-      if (iter != extra_object_base_data.end())
-      {
-        custom_interface_classes = iter->second.custom_interface_classes;
-        extra_object_base_data.erase(iter);
-      }
-    }
-
     object_type =
-      construct_params.glibmm_class.clone_custom_type(custom_type_name_, custom_interface_classes);
+      construct_params.glibmm_class.clone_custom_type(custom_type_name_, *custom_interface_classes_);
+    custom_interface_classes_.reset(nullptr);
   }
 
   // Create a new GObject with the specified array of construct properties.
diff --git a/glib/glibmm/objectbase.cc b/glib/glibmm/objectbase.cc
index d2a252d..15c8197 100644
--- a/glib/glibmm/objectbase.cc
+++ b/glib/glibmm/objectbase.cc
@@ -40,24 +40,25 @@ namespace Glib
 
 /**** Glib::ObjectBase *****************************************************/
 
-// static data members
-ObjectBase::extra_object_base_data_type ObjectBase::extra_object_base_data;
-std::mutex ObjectBase::extra_object_base_data_mutex;
-
 ObjectBase::ObjectBase()
 : gobject_(nullptr),
   custom_type_name_(anonymous_custom_type_name),
-  cpp_destruction_in_progress_(false)
+  cpp_destruction_in_progress_(false),
+  custom_interface_classes_(nullptr)
 {
 }
 
 ObjectBase::ObjectBase(const char* custom_type_name)
-: gobject_(nullptr), custom_type_name_(custom_type_name), cpp_destruction_in_progress_(false)
+: gobject_(nullptr), custom_type_name_(custom_type_name),
+  cpp_destruction_in_progress_(false),
+  custom_interface_classes_(custom_type_name_ ? new Class::interface_class_vector_type : nullptr)
 {
 }
 
 ObjectBase::ObjectBase(const std::type_info& custom_type_info)
-: gobject_(nullptr), custom_type_name_(custom_type_info.name()), cpp_destruction_in_progress_(false)
+: gobject_(nullptr), custom_type_name_(custom_type_info.name()),
+  cpp_destruction_in_progress_(false),
+  custom_interface_classes_(new Class::interface_class_vector_type)
 {
 }
 
@@ -154,14 +155,6 @@ ObjectBase::~ObjectBase() noexcept
   // we have to call g_object_unref() on our own.
   //
 
-  // Just a precaution. Unless a derived class's ctor has thrown an exception,
-  // 'this' should have been erased from extra_object_base_data by
-  // Glib::Object's constructor.
-  {
-    std::lock_guard<std::mutex> lock(extra_object_base_data_mutex);
-    extra_object_base_data.erase(this);
-  }
-
   if (GObject* const gobject = gobject_)
   {
 #ifdef GLIBMM_DEBUG_REFCOUNTING
diff --git a/glib/glibmm/objectbase.h b/glib/glibmm/objectbase.h
index c1aabbe..ce7243d 100644
--- a/glib/glibmm/objectbase.h
+++ b/glib/glibmm/objectbase.h
@@ -28,9 +28,7 @@
 #include <glibmm/debug.h>
 #include <sigc++/trackable.h>
 #include <typeinfo>
-#include <map> // Needed until the next ABI break.
-#include <memory> // Not used by ObjectBase any more, but user code may rely on it being here.
-#include <mutex>
+#include <memory>
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 extern "C" {
@@ -224,20 +222,9 @@ protected:
 
   bool is_anonymous_custom_() const;
 
-  // TODO: At the next ABI break, replace extra_object_base_data by a non-static
-  // data member.
-  // This is a new data member that can't be added as instance data to
-  // ObjectBase now, because it would break ABI.
-  struct ExtraObjectBaseData
-  {
-    Class::interface_class_vector_type custom_interface_classes;
-  };
-
-  using extra_object_base_data_type = std::map<const ObjectBase*, ExtraObjectBaseData>;
-  static extra_object_base_data_type extra_object_base_data;
-  // ObjectBase instances may be used in different threads.
-  // Accesses to extra_object_base_data must be thread-safe.
-  static std::mutex extra_object_base_data_mutex;
+  // Vector of pointers to the interfaces of custom types.
+  // Used only during the construction of named custom types.
+  std::unique_ptr<Class::interface_class_vector_type> custom_interface_classes_;
 
 public:
   //  is_derived_() must be public, so that overridden vfuncs and signal handlers can call it


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]