mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2026-10-24 00:49:00 +03:00
g_type_ensure has a large comment saying _get_type shouldn't be marked with G_GNUC_CONST because it has side-effects on the first run, but it's OK if you consistently call g_type_ensure first. Unfortunately, this isn't accurate. GCC trunk (observed at r17-1725-ge259a182e1f100) now analyses points-to information more effectively and propagates its findings, so it sees the function modifies some global state, concludes that can't be possible (because of the const attribute), and deletes the stores. pure unfortunately is unsuitable for *_get_type too as it has a side-effect (writes to global memory). Mesa had a similar issue which I fixed recently [0]. glib and glibmm likely want the (not-yet-implemented) 'idempotent' attribute instead [1]. In fact, this exact problem is what motivated that request! :) ebassi mentions an alternative to the current setup as well, using atomics [2]. This problem has gone back many years but the compiler has finally fully outsmarted us here, so give in. [0] https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/42361 [1] https://gcc.gnu.org/PR32911 [2] https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4249#note_2583110 Fixes: https://gitlab.gnome.org/GNOME/glib/-/work_items/3984 Signed-off-by: Sam James <sam@gentoo.org>
131 lines
4.8 KiB
C
131 lines
4.8 KiB
C
/* GObject - GLib Type, Object, Parameter and Signal Library
|
|
* Copyright (C) 2000 Red Hat, Inc.
|
|
*
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
*
|
|
* 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#ifndef __G_TYPE_PLUGIN_H__
|
|
#define __G_TYPE_PLUGIN_H__
|
|
|
|
#if !defined (__GLIB_GOBJECT_H_INSIDE__) && !defined (GOBJECT_COMPILATION)
|
|
#error "Only <glib-object.h> can be included directly."
|
|
#endif
|
|
|
|
#include <gobject/gtype.h>
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
/* --- type macros --- */
|
|
#define G_TYPE_TYPE_PLUGIN (g_type_plugin_get_type ())
|
|
#define G_TYPE_PLUGIN(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), G_TYPE_TYPE_PLUGIN, GTypePlugin))
|
|
#define G_TYPE_PLUGIN_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), G_TYPE_TYPE_PLUGIN, GTypePluginClass))
|
|
#define G_IS_TYPE_PLUGIN(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), G_TYPE_TYPE_PLUGIN))
|
|
#define G_IS_TYPE_PLUGIN_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), G_TYPE_TYPE_PLUGIN))
|
|
#define G_TYPE_PLUGIN_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), G_TYPE_TYPE_PLUGIN, GTypePluginClass))
|
|
|
|
|
|
/* --- typedefs & structures --- */
|
|
typedef struct _GTypePluginClass GTypePluginClass;
|
|
/**
|
|
* GTypePluginUse:
|
|
* @plugin: the #GTypePlugin whose use count should be increased
|
|
*
|
|
* The type of the @use_plugin function of #GTypePluginClass, which gets called
|
|
* to increase the use count of @plugin.
|
|
*/
|
|
typedef void (*GTypePluginUse) (GTypePlugin *plugin);
|
|
/**
|
|
* GTypePluginUnuse:
|
|
* @plugin: the #GTypePlugin whose use count should be decreased
|
|
*
|
|
* The type of the @unuse_plugin function of #GTypePluginClass.
|
|
*/
|
|
typedef void (*GTypePluginUnuse) (GTypePlugin *plugin);
|
|
/**
|
|
* GTypePluginCompleteTypeInfo:
|
|
* @plugin: the #GTypePlugin
|
|
* @g_type: the #GType whose info is completed
|
|
* @info: the #GTypeInfo struct to fill in
|
|
* @value_table: the #GTypeValueTable to fill in
|
|
*
|
|
* The type of the @complete_type_info function of #GTypePluginClass.
|
|
*/
|
|
typedef void (*GTypePluginCompleteTypeInfo) (GTypePlugin *plugin,
|
|
GType g_type,
|
|
GTypeInfo *info,
|
|
GTypeValueTable *value_table);
|
|
/**
|
|
* GTypePluginCompleteInterfaceInfo:
|
|
* @plugin: the #GTypePlugin
|
|
* @instance_type: the #GType of an instantiatable type to which the interface
|
|
* is added
|
|
* @interface_type: the #GType of the interface whose info is completed
|
|
* @info: the #GInterfaceInfo to fill in
|
|
*
|
|
* The type of the @complete_interface_info function of #GTypePluginClass.
|
|
*/
|
|
typedef void (*GTypePluginCompleteInterfaceInfo) (GTypePlugin *plugin,
|
|
GType instance_type,
|
|
GType interface_type,
|
|
GInterfaceInfo *info);
|
|
/**
|
|
* GTypePluginClass:
|
|
* @use_plugin: Increases the use count of the plugin.
|
|
* @unuse_plugin: Decreases the use count of the plugin.
|
|
* @complete_type_info: Fills in the #GTypeInfo and
|
|
* #GTypeValueTable structs for the type. The structs are initialized
|
|
* with `memset(s, 0, sizeof (s))` before calling this function.
|
|
* @complete_interface_info: Fills in missing parts of the #GInterfaceInfo
|
|
* for the interface. The structs is initialized with
|
|
* `memset(s, 0, sizeof (s))` before calling this function.
|
|
*
|
|
* The #GTypePlugin interface is used by the type system in order to handle
|
|
* the lifecycle of dynamically loaded types.
|
|
*/
|
|
struct _GTypePluginClass
|
|
{
|
|
/*< private >*/
|
|
GTypeInterface base_iface;
|
|
|
|
/*< public >*/
|
|
GTypePluginUse use_plugin;
|
|
GTypePluginUnuse unuse_plugin;
|
|
GTypePluginCompleteTypeInfo complete_type_info;
|
|
GTypePluginCompleteInterfaceInfo complete_interface_info;
|
|
};
|
|
|
|
|
|
/* --- prototypes --- */
|
|
GOBJECT_AVAILABLE_IN_ALL
|
|
GType g_type_plugin_get_type (void);
|
|
GOBJECT_AVAILABLE_IN_ALL
|
|
void g_type_plugin_use (GTypePlugin *plugin);
|
|
GOBJECT_AVAILABLE_IN_ALL
|
|
void g_type_plugin_unuse (GTypePlugin *plugin);
|
|
GOBJECT_AVAILABLE_IN_ALL
|
|
void g_type_plugin_complete_type_info (GTypePlugin *plugin,
|
|
GType g_type,
|
|
GTypeInfo *info,
|
|
GTypeValueTable *value_table);
|
|
GOBJECT_AVAILABLE_IN_ALL
|
|
void g_type_plugin_complete_interface_info (GTypePlugin *plugin,
|
|
GType instance_type,
|
|
GType interface_type,
|
|
GInterfaceInfo *info);
|
|
|
|
G_END_DECLS
|
|
|
|
#endif /* __G_TYPE_PLUGIN_H__ */
|