On Sun, 2006-12-03 at 19:05 +0000, Chris Vine wrote:
> On Sunday 03 December 2006 10:26, Braden McDaniel wrote:
> > I have a GMainLoop that I want to run in its own thread. But I seem to b
> > doing something horribly wrong with the event source I'm trying to
> > attach to it (all as part of the same thread). My thread function
> > includes this code:
> >
> >         GMainContext * main_context = g_main_context_new();
> >         GMainLoop * main_loop = g_main_loop_new(main_context, false);
> >
> >         GSource * quit = g_idle_source_new();
> >         g_source_set_callback(quit,
> >                               
> > ::openvrml_player_command_channel_loop_quit_event,
> >                               main_loop,
> >                               notify);
> >         guint source_id = g_source_attach(quit, main_context);
> >         g_assert(source_id != 0);
> >
> >         g_main_loop_run(main_loop);
> >
> >         g_source_unref(quit);
> >         g_main_loop_unref(main_loop);
> >         g_main_context_unref(main_context);
> >
> > If I do not attach the event source, the code runs. But if I do attach
> > it, as above, I crash as soon as I start to run the main loop:
> 
> Wouldn't unreferencing main_context cause it to be freed?  (And does 
> g_main_loop_run() increement the reference count of main_loop?  If not then 
> unreferencing main_loop that will also destroy the main loop).  The call to 
> g_source_unref() is correct (g_source_attach will increment the reference 
> count of quit).

I'm not getting past the call to g_main_loop_run, so the *_unref calls
aren't the problem.

I've gotten closer to the problem; but it's just mysteriouser.

The callback looks like this:

        gboolean openvrml_player_command_channel_loop_quit_event(const gpointer 
data)
        {
            GMainLoop * const main_loop = static_cast<GMainLoop *>(data);
        
            if (::quit_flag.value()) {
                g_main_loop_quit(main_loop);
                return false;
            }
            return true;
        }

quit_flag is just a boolean flag protected by a mutex:

        class flag : boost::noncopyable {
            mutable boost::mutex mutex_;
            bool value_;
        
        public:
            flag(bool init = false);
        
            bool value() const;
            void value(bool val);
        };

It appears that the core dump happens in the first call to
openvrml_player_command_channel_loop_quit_event. But here things get
murky because the problem seems to be very timing-sensitive. If I put a
print statement at the beginning of
openvrml_player_command_channel_loop_quit_event, it starts working. And
if I instead put a print statement at the beginning of flag::value(), it
starts working.

This points, I think, to something being wrong with the state of
quit_flag at the time I try to use it in
openvrml_player_command_channel_loop_quit_event--like it's not fully
initialized. Though I don't understand why that would be the case--my
thread is being started from main() quit_flag is a global variable (in
the same translation unit as main()).

I'll continue to experiment.

-- 
Braden McDaniel                           e-mail: <[EMAIL PROTECTED]>
<http://endoframe.com>                    Jabber: <[EMAIL PROTECTED]>


_______________________________________________
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