g_object_ref_sink() replaces gtk_object_sink() 

Please make this substitution

James, 


On Thu, 2008-02-28 at 00:04 -0500, James Scott Jr wrote:

> On Wed, 2008-02-27 at 21:03 -0500, Mark Rodriguez wrote:
> 
> > James,
> > 
> > >  When doe s the error occur?
> > >  0. When program starts
> > >  1. When shutting down
> > >  2. When creating the text_view the first time
> > >  3. When creating the text_view the Nth time
> > >
> > >  I will assume it happens durin shutdown (#1).
> > 
> > Yes you are correct. In the "real" application, the application
> > doesn't exit. It destroys the canvas and re-uses it with new controls.
> > Rather than debug that [monster], I reduced the application to
> > something more manageable that exhibit the same behavior.
> > 
> > >  Yes, it should be handled like any other widget.  The only special thing 
> > > is
> > > its text_buffer!  Consider gtk_text_view_new_with_buffer(), one is created
> > > automatically for when using the gtk_text_view_new() api.  I don't think
> > > creating the GtkTextBuffer first would make any difference -- however, 
> > > that
> > > where you are now.  So try creating the GtkTextBuffer first, then use the
> > > ...with_buffer() api to create the view.  This may produce a different
> > > result.
> > 
> > Interesting. I tried a few different things today and was able to get
> > the application to work as expected without crashing, but I don't like
> > the solution as now it appears I'm leaking memory. Any thoughts on why
> > if g_object_unref is called the application complains about the double
> > free? I modified the code as follows (mainly the button_click_event
> > handler was changed to handle the text buffer and to require clicking
> > the 'Quit' button twice for exiting the app - this was just done for
> > visibility reasons).
> > 
> 
> ref's are strange things: When I run into this anomaly I do the
> following, reasoning that I must have only had a weak reference, and
> g_object_unref got confused -- anyway this normally works for me.
> 
> /* creation code ... */
> ...
>    buffer = gtk_text_buffer_new(NULL);
>    if (buffer != NULL) {
>              g_object_ref (G_OBJECT(buffer));
>              gtk_object_sink (G_OBJECT(buffer));   
>    }
> 
> sinking it ensures that you have a full fledged reference that a later
> unref will honor.  
> 
> If your creating and deleting this text_view as needed, you will have to
> find the root cause of these messages.  I notice that you prep'ed the
> main() to use threads.  Your problem maybe related to how your using
> threads when creating/destroying the text view.  I would suggest
> exploring this type of change.  
> 
> 1a. Only create/destroy in the main gtk/gdk thread.
> 
> 1b. Fire off a g_timeout_add( 500000, (GSourceFunc)fn_create_routine(),
> gpointer); where "gboolean fn_create_routine(gpointer gp);" calls the
> normal gtk_window_new() stuff to create a dialog or the window you plan
> to use the text_view in.  All this gets you out of the normal gtk signal
> chain of events.  signals iterate on themselves and I've seen unwinds
> cause random errors - like your double-free.
> 
> 1c. Do essentially the same to destroy the window.
> 
> 2a. I guess I don't actually delete/destroy main windows once created, I
> just hide them and present them again when needed.
> 2b. Or if I do destroy them, i keep the buffer and/or tree_model in a
> allocated memory structure.  Thus gtk_text_view_new_with_buffer() is the
> type of call I most often use to create text_views.
> 
> 3.  You seem to be _show() ing objects before adding them to something.
> Look at vbox; you create it, show it, then add it to the main.window.
> The recommended style is to create, add, show.   I don't think causes
> any immediate problems but it could be polluting something- anyway this
> strikes me as something worth cleaning up.
> 
> 
> James,
> 
> 
> 
> 
> > [code]
> > GtkWidget *main_window, *text_view, *box, *button;
> > GtkTextBuffer* buffer;
> > 
> > static void destroy_event(GtkWidget* widget, void* data)
> > {
> >     gtk_main_quit();
> > }
> > 
> > static void button_click_event(void)
> > {
> >     if (text_view != NULL)
> >     {
> >             gtk_container_remove(GTK_CONTAINER(box), text_view);
> >             text_view = NULL;
> >             // leaking memory???
> > //          g_object_unref(G_OBJECT(buffer));
> >             buffer = NULL;
> >     }
> >     else
> >     {
> >             gtk_widget_destroy(main_window);
> >             main_window = NULL;
> >     }
> > }
> > 
> > int main(int argc, char* argv[])
> > {
> >     // initialize multi-threading within GLib
> >     g_thread_init(NULL);
> > 
> >     // initialize multi-threading within GDK
> >     gdk_threads_init();
> > 
> >     // acquire thread lock
> >     gdk_threads_enter();
> >     gtk_init(&argc, &argv);
> > 
> >     // create main window
> >     main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
> >     if (main_window == NULL)
> >             abort();
> >     g_signal_connect(G_OBJECT(main_window), "destroy",
> > G_CALLBACK(destroy_event), NULL);
> >     gtk_widget_show(main_window);
> > 
> >     box = gtk_vbox_new(FALSE, 5);
> >     if (box == NULL)
> >             abort();
> >     gtk_widget_show(box);
> >     gtk_container_add(GTK_CONTAINER(main_window), box);
> > 
> >     buffer = gtk_text_buffer_new(NULL);
> >     if (buffer == NULL)
> >             abort();
> > 
> >     text_view = gtk_text_view_new_with_buffer(buffer);
> >     if (text_view == NULL)
> >             abort();
> >     gtk_widget_show(text_view);
> >     gtk_box_pack_start(GTK_BOX(box), text_view, TRUE, TRUE, 5);
> > 
> >     button = gtk_button_new_with_label("Quit");
> >     if (button == NULL)
> >             abort();
> >     g_signal_connect(G_OBJECT(button), "clicked",
> > G_CALLBACK(button_click_event), NULL);
> >     gtk_widget_show(button);
> >     gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 5);
> > 
> >     // run the main loop
> >     gtk_main();
> > 
> >     // release thread lock
> >     gdk_threads_leave();
> > 
> >     return 0;
> > }
> > [/code]
> > 
> > 
> _______________________________________________
> gtk-app-devel-list mailing list
> gtk-app-devel-list@gnome.org
> http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list
_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to