3

ディスパッチャを使用するマルチスレッド コードがいくつかあります。gtk スレッドでディスパッチャーを作成/破棄する際には注意が必要でした。しかし、そこからでも破壊できないらしい。このコードを参照してください (これはシングル スレッドでもあります)。何か不足していますか?

#include <gtkmm.h>
#include <iostream>
using namespace std;

class HelloWorld:public Gtk::Window {
 public:

 Glib::Dispatcher* disp;
 Glib::Dispatcher disp2;
sigc::connection conn;

 void onDisp(){
  cout << "Hello by disp" << endl;
}


 HelloWorld():m_button("Hello"),m_destr("Destr") {
  disp=new Glib::Dispatcher();
  conn=disp->connect(sigc::mem_fun(*this,&HelloWorld::onDisp));      
  disp2.connect(sigc::mem_fun(*this,&HelloWorld::on_work));

 m_button.signal_clicked().connect(sigc::mem_fun(*this,&HelloWorld::on_button_clicked));
  m_destr.signal_clicked().connect(sigc::mem_fun(*this,&HelloWorld::on_destr_clicked));
  v.add(m_button);
  v.add(m_destr);
  add(v);
  show_all_children();
}


protected:

void on_work(){
 usleep(1*1E5);
}

void on_button_clicked(){

   for (size_t i=0;i<100;i++){
if (disp!=NULL){
  (*disp)();
}
disp2();
   }
 }

 void on_destr_clicked() {
   conn.disconnect();
   delete disp;
   disp=NULL;
 }

Gtk::Button m_button;
Gtk::Button m_destr;
Gtk::VBox v;


};

int main (int argc, char *argv[]) {
 Gtk::Main kit(argc, argv);

 HelloWorld helloworld;
//Shows the window and returns when it is closed.
 Gtk::Main::run(helloworld);

 return 0;
}

===環境=== Ubuntu 11.10、gtkmm 2.24.2-1、libglib 2.30.0

===GDB====

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff70f6ee9 in Glib::DispatchNotifier::pipe_io_handler(Glib::IOCondition) () from /usr/lib/libglibmm-2.4.so.1
(gdb) bt
#0  0x00007ffff70f6ee9 in Glib::DispatchNotifier::pipe_io_handler(Glib::IOCondition) () from /usr/lib/libglibmm-2.4.so.1
#1  0x00007ffff70f8dcc in Glib::IOSource::dispatch(sigc::slot_base*) () from /usr/lib/libglibmm-2.4.so.1
#2  0x00007ffff70f89df in Glib::Source::dispatch_vfunc(_GSource*, int (*)(void*), void*) () from /usr/lib/libglibmm-2.4.so.1
#3  0x00007ffff4e68a5d in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#4  0x00007ffff4e69258 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5  0x00007ffff4e69792 in g_main_loop_run () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#6  0x00007ffff5751db7 in gtk_main () from /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0
#7  0x00007ffff7824326 in Gtk::Main::run(Gtk::Window&) () from /usr/lib/libgtkmm-2.4.so.1
#8  0x0000000000442f9a in main (argc=1, argv=0x7fffffffe368) at gtkmmWindow.cpp:66

====VALGRIND====

 Invalid read of size 8
==5254==    at 0x5931E81:
Glib::DispatchNotifier::pipe_io_handler(Glib::IOCondition) (in
/usr/lib/libglibmm-2.4.so.1.3.0)
==5254==    by 0x5933DCB: Glib::IOSource::dispatch(sigc::slot_base*) (in
/usr/lib/libglibmm-2.4.so.1.3.0)
==5254==    by 0x59339DE: Glib::Source::dispatch_vfunc(_GSource*, int
(*)(void*), void*) (in /usr/lib/libglibmm-2.4.so.1.3.0)
==5254==    by 0x7B35A5C: g_main_context_dispatch (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3000.0)
==5254==    by 0x7B36257: ??? (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3000.0)
==5254==    by 0x7B36791: g_main_loop_run (in
/lib/x86_64-linux-gnu/libglib-2.0.so.0.3000.0)
==5254==    by 0x70E6DB6: gtk_main (in
/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.6)
==5254==    by 0x530B325: Gtk::Main::run(Gtk::Window&) (in
/usr/lib/libgtkmm-2.4.so.1.1.0)
==5254==    by 0x442F99: main (gtkmmWindow.cpp:66)
==5254==  Address 0xd1ad9e8 is 8 bytes inside a block of size 24 free'd
==5254==    at 0x4C27FF2: operator delete(void*) (vg_replace_malloc.c:387)
==5254==    by 0x5B584E8: sigc::signal_base::~signal_base() (in
/usr/lib/libsigc-2.0.so.0.0.0)
==5254==    by 0x443A45: HelloWorld::on_destr_clicked() (gtkmmWindow.cpp:50)
==5254==    by 0x4442B4: sigc::bound_mem_functor0<void,
HelloWorld>::operator()() const (in
/home/fabio/research/software/bin/gui/gtkmmWindow.greenplanet)
==5254==    by 0x4441DF: sigc::adaptor_functor<sigc::bound_mem_functor0<void,
HelloWorld> >::operator()() const (adaptor_trait.h:251)
==5254==    by 0x444096:
sigc::internal::slot_call0<sigc::bound_mem_functor0<void, HelloWorld>,
void>::call_it(sigc::internal::slot_rep*) (slot.h:103)
==5254==    by 0x5938B07:
Glib::SignalProxyNormal::slot0_void_callback(_GObject*, void*) (in
/usr/lib/libglibmm-2.4.so.1.3.0)
==5254==    by 0x78AF0A3: g_closure_invoke (in
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3000.0)
==5254==    by 0x78C11F4: ??? (in
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3000.0)
==5254==    by 0x78CA6B0: g_signal_emit_valist (in
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3000.0)
==5254==    by 0x78CA851: g_signal_emit (in
/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3000.0)
==5254==    by 0x7040904: ??? (in
/usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0.2400.6)
4

0 に答える 0