After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 407711 - Attempts to register same type multiple times.
Attempts to register same type multiple times.
Status: RESOLVED OBSOLETE
Product: glibmm
Classification: Bindings
Component: general
2.8.x
Other All
: Normal normal
: ---
Assigned To: gtkmm-forge
gtkmm-forge
Depends on: 409043
Blocks:
 
 
Reported: 2007-02-14 02:22 UTC by Paul Davis
Modified: 2018-05-22 12:06 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Make Glib::Value<> register custom types dynamically (6.36 KB, patch)
2007-02-17 20:10 UTC, Daniel Elstner
needs-work Details | Review

Description Paul Davis 2007-02-14 02:22:19 UTC
I've got a class derived from Gtk::TreeModel::ColumnRecord defined in a plugin.

If I load the plugin multiple times, Glibmm gives this error:

glibmm-WARNING **: file value_custom.cc: (Glib::custom_boxed_type_register): The type name `glibmm__CustomBoxed_N3cas13_MachineCoordE' has been registered already.
This is not supposed to happen -- please send a mail with detailed information about your platform to gtkmm-list@gnome.org.  Thanks.

I don't have a test case worked up, but I might be able to work one up later if I have time.
Comment 1 Daniel Elstner 2007-02-14 04:14:25 UTC
This warning is triggered when the static member variable in Glib::Value_Boxed<> that holds the GType has a zero value, but upon registration the GType appears to have been already registered.  When I added this warning, the only situation I had in mind where this could happen was if the linker doesn't correctly merge static member data of template classes across multiple translation units.

I didn't consider the possibility of dynamically loaded plugins, though.  Now as I think about it, it's obvious why it breaks:  The static member data goes away with the module, and reappears zero-initialized.

Urgh, that's a tough one to solve.  Just skipping the second registration doesn't cut it, as the function pointers back to the template methods are now different, too.  We can't just unregister a statically registered type, either.  It'll be necessary to use a GTypePlugin, specifically GTypeModule, in order to support dynamic loading and unloading.

http://developer.gnome.org/doc/API/2.0/gobject/GTypeModule.html

If we can actually pull this off -- without breaking ABI --, it would be wise to perform some measurements to gauge the impact on TreeModel performance.  I vaguely remember having read somewhere that dynamic types involve additional mutex locks.

Uh-oh.
Comment 2 Daniel Elstner 2007-02-14 04:36:44 UTC
One possible way to handle this could be to provide a different implementation of Glib::Value_Boxed<> when compiling a plugin.  This would require the plugin to be compiled with a global -D preprocessor macro defined to the unique name of the plugin.  Also, it would be necessary to make absolutely sure that none of the Gtk::TreeModel::Column<> stuff turns up in any public header file.
Comment 3 Murray Cumming 2007-02-14 09:49:02 UTC
I wonder if this is fixed by bug #383340. That's in the latest gtkmm 2.10 tarball, and in svn for all branches.
Comment 4 Paul Davis 2007-02-14 10:20:57 UTC
As a disclaimer I know absolutely nothing about this part of the API, but after reading through the comments in bug #383340 it doesn't sound like the same problem.

I'm not calling Gtk::Main( int argc, char* argv[] ) in the plugin. The Gtk 'context' exists before and after the plugin is loaded/unloaded.

In other words, imagine a window with a button. I click the button. The plugin loads, opens a window that has a treeview (with the offending ColumnRecord class). I close the window, the plugin is unloaded. If the main window 'load plugin' button is clicked again I get the message.

I hope thats not overly confusing...

Earlier I glanced at value_custom.cc and found where the description is printed in custom_boxed_type_register(), but grepping glibmm and gtkmm I didn't find any actual calls to that function so I couldn't trace beyond where the warning gets displayed.

Just skipping the second registration
doesn't cut it, as the function pointers back to the template methods are now
different, too.

I'm not entirely sure what this sentence means. But like I said I don't know the api. The way I understand the custom_boxed_type_register is that it registers an allocate/deallocate/copy function with glib. If these are provided by a plugin, then the addresses *probably* change after an unload/load cycle.  Granted I haven't the slightest how its called, but why can't we just register the new allocate/deallocate functions and change the message to "this registration invalidates the previous." ? It seems like the current warning is just a sanity check. So instead of returning the currently registered type, we re-register the type, and make the sanity check "You've re-registered a type, if you haven't unloaded a static type and reloaded it, you need to talk to the gtkmm mailing list"

Keep in mind I have absolutely no idea about the specifics. I could see the C api not allowing this and a host of other reasons that this might not work. But its just a thought.
Comment 5 Daniel Elstner 2007-02-14 17:28:49 UTC
Murray: No, that seems to be an entirely different problem to me as well.

> Earlier I glanced at value_custom.cc and found where the description is printed
> in custom_boxed_type_register(), but grepping glibmm and gtkmm I didn't find
> any actual calls to that function so I couldn't trace beyond where the warning
> gets displayed.

It's right there in value_custom.h (Value<T>::value_type). By the way, I just realized that the offending class is Value<T>, not Value_Boxed<T>.  Anyway, if you look at the function in question you'll probably see right away what the sentence about pointers to template methods means.

> Granted I haven't the slightest how its called, but why can't we just register
> the new allocate/deallocate functions and change the message to "this
> registration invalidates the previous."?

That's exactly what I'm getting at in my first reply.  For that, it'd be necessary to unregister the old type.  We cannot do that for statically registered types.  We will have to change to the code to register the type by means of a GTypePlugin, which exists exactly for this purpose.
Comment 6 Paul Davis 2007-02-15 03:32:09 UTC
Just a minor follow up.

Putting the ModelColumns class definition in a shared library didn't work out for me.  The error is still being triggered when an instance of the class is created in the plugin the second time.

Luckily I can break this type out into its member variables which are all standard types into individual columns in the TreeView

In other words, its still broken but I'm still not in a hurry for a fix.
Comment 7 Daniel Elstner 2007-02-15 16:25:09 UTC
I reckon that's because the shared library is loaded/unloaded together with the plugin, right?  If so, it should probably work if the main application depends on that library, too.
Comment 8 Paul Davis 2007-02-15 22:07:35 UTC
The shared library is loaded with the main application.  Although, the main application never instantiates a copy of this particular class.

The error is triggered when the plugin calls the Gtk::TreeModel::ColumnRecord constructor the second time.
Comment 9 Daniel Elstner 2007-02-15 22:25:27 UTC
Hmm weird.  Are you sure the library isn't actually loaded on demand?  Well, I don't know a lot about the behavior of normal shared libs in conjunction with dynamically loaded plugins.  Maybe it get's mapped into a different address space or something, dunno.  What happens if you call any function from that library in the main program?
Comment 10 Paul Davis 2007-02-15 23:06:46 UTC
The library is loaded and used extensively, but this particular class is never used except from within the plugin.

I did some looking into exactly how this gets instantiated. In gtkmm the files treemodelcolumn.h and treemodelcolumn.cc are where this particular message is getting triggered.

The question here is, how to tell gtkmm to register via GTypeModule as apposed to the normal method?

Ideally, this would be determined automatically, but nothing really comes to mind on how that would work.

This is some rather confusing stuff.
Comment 11 Daniel Elstner 2007-02-17 20:10:45 UTC
Created attachment 82750 [details] [review]
Make Glib::Value<> register custom types dynamically

I had a go at this and changed the Glib::Value<> implementation to register custom types dynamically, using a custom GTypeModule.  Unfortunately, I hit a bug in GLib (#409043) which prevents this from working.  The non-working patch is attached for reference.
Comment 12 GNOME Infrastructure Team 2018-05-22 12:06:47 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glibmm/issues/3.