Glib::TimeoutSource and Glib::IOSource



I'm in the process of porting a set of programs from ACE to glibmm.

In one of the apps I use a TimeoutSource to determine if its been
too long since we've seen data on an IOSource.  If that's the case
I reset some hardware and sign the IOSource up again ... or so
I had hoped to do ... I wind up with segfaults.

code is something on the order of:

fd = open("/dev/foo", O_RDONLY);
iosrc = Glib::IOSource::create(fd, Glib::IO_IN | Glib::IO_PRI);
iosrc->connect(sigc::mem_fun(*this, &BufReader::InputCB));
iosrc->attach();
timeoutsrc->attach();   // callback checks that InputCB() runs often enough

all is well until we determine that hardware is hung.
at that time I:

iosrc->destroy();
close(fd);
open again, just as above ...

at first I thought my problem was that I'm destroying a source
while another is being dispatched ... after some time fiddling
with different variations of the problem, I believe that it has
something to do with reference counting.  In particular I believe
things get out of whack when an attached source is destroyed:

#include <iostream>
#include <glibmm/main.h>

bool timercb() { return true; }

void
DoIt(const char *msg, Glib::RefPtr<Glib::TimeoutSource> &src)
{
    std::cerr << msg << '\n';
    std::cerr << "  creating\n";     src = Glib::TimeoutSource::create(1000);
    std::cerr << "  connecting\n";   src->connect(sigc::ptr_fun(timercb));
    std::cerr << "  attaching\n";    src->attach();
    std::cerr << "  destroying\n";   src->destroy();
}

int
main(int argc, char *argv[])
{
    Glib::RefPtr<Glib::MainLoop> l = Glib::MainLoop::create();

    Glib::RefPtr<Glib::TimeoutSource> ts;
    DoIt("ONCE", ts);
    DoIt("TWICE", ts);

    l->run();

    return 0;
}

results in the following for glibmm 0.15.0 and 0.17.2 on
my FreeBSD 6.0 system with gcc 3.4.4:

ONCE
  creating
  connecting
  attaching
  destroying
TWICE
  creating
  connecting
Segmentation fault (core dumped)

#0  0x28096832 in {anonymous}::glibmm_source_get_callback_data ()
   from /usr/X11R6/lib/libglibmm-2.0.so.6
#1  0x28098921 in Glib::Source::connect_generic ()
   from /usr/X11R6/lib/libglibmm-2.0.so.6
#2  0x2809909e in Glib::TimeoutSource::connect ()
   from /usr/X11R6/lib/libglibmm-2.0.so.6
#3  0x8048cea in DoIt (msg=0x804939f "TWICE", src= 0xbfbfe99c)
    at fifotest.cc:11
#4  0x8048e00 in main (argc=1, argv=0xbfbfea04) at fifotest.cc:23


In some variations of the problem I have run into glib assertions
that src != NULL at the time the Glib::RefPtr<Glib::IOSource> was
overwritten with result from IOSource::create() call.

commenting out either the attach() or the destroy() circumvents
the segfault, but unless I'm completely misunderstanding something
I need to call both - commenting out destroy() in the example
above results in two callbacks every second.

I will much appreciate someone telling me if and how I'm misusing
glibmm, if the sample program bombs on their system as well, or
anything else along those lines.

Thanks ahead of time.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]