From 3911557cb62ed055f16ece0a7a58cbbabe35ef6b Mon Sep 17 00:00:00 2001 From: Kjell Ahlstedt Date: Thu, 24 Nov 2016 19:13:55 +0100 Subject: 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 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 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 785d050b..97f1c27d 100644 --- a/gio/src/application.ccg +++ b/gio/src/application.ccg @@ -21,6 +21,7 @@ #include #include // std::memset() #include +#include #include namespace // anonymous diff --git a/glib/glibmm/class.cc b/glib/glibmm/class.cc index 75b7d131..2f76aba8 100644 --- a/glib/glibmm/class.cc +++ b/glib/glibmm/class.cc @@ -84,12 +84,6 @@ Class::register_derived_type(GType base_type, GTypeModule* module) g_free(derived_name); } -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 bc5a06ab..813b467c 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; diff --git a/glib/glibmm/interface.cc b/glib/glibmm/interface.cc index 0ce998bf..62878d62 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 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 27464d3e..c065b510 100644 --- a/glib/glibmm/main.cc +++ b/glib/glibmm/main.cc @@ -23,6 +23,7 @@ #include #include #include // Needed until the next ABI break. +#include namespace { diff --git a/glib/glibmm/object.cc b/glib/glibmm/object.cc index e7f6f88f..c4e0a6f4 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 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 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 d2a252d8..15c81973 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 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 c1aabbe9..ce7243df 100644 --- a/glib/glibmm/objectbase.h +++ b/glib/glibmm/objectbase.h @@ -28,9 +28,7 @@ #include #include #include -#include // Needed until the next ABI break. -#include // Not used by ObjectBase any more, but user code may rely on it being here. -#include +#include #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; - 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 custom_interface_classes_; public: // is_derived_() must be public, so that overridden vfuncs and signal handlers can call it -- cgit v1.2.1