Strange behavior with GTK::ProgressBar when updating outside the main thread.

View: New views
5 Messages — Rating Filter:   Alert me  

Strange behavior with GTK::ProgressBar when updating outside the main thread.

by Steve Scott-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

I had this strange problem with updating a progressbar with a callback from a thread.  My app starts with a Gtk::Window and when an event occurs a basic dialog box with two buttons is displayed.  The two buttons are "copy" and "close".  Inside the dialog I create a thread as shown below:

void g_FileCopyDialog::copyFrom()
{

 Glib::Thread *const thread = Glib::Thread::create(sigc::mem_fun(*file, &DirectFile::runCopyThread), true );

// it does not join....

}

This is run after the dialog is shown (.show()) through the Gtk:Window.  Basiclly "file" is a object that handles file copies. I also have a callback in g_FileCopyDialog:

// callback method
void g_FileCopyDialog::progressBarUpdate(unsigned int position, unsigned int max )
{

    gdk_threads_enter();
    m_pcopyprogressbar->set_fraction( (double) position/max );
    gdk_threads_leave();

    while( Gtk::Main::events_pending() )
        Gtk::Main::iteration();

}

With this setup the progress bar does not update.  But if I just press the "Close" button (which doesn't close the dialog.  I didnt setup the event yet) while the file is copying it will show the progress bar working.  This was driving me nuts, and I spent almost a day trying to get it working right.   Finally after trying all different things I decided to try updating the progress bar after I created the thread like this:

void g_FileCopyDialog::copyFrom()
{

 Glib::Thread *const thread = Glib::Thread::create(sigc::mem_fun(*file, &DirectFile::runCopyThread), true );

// it does not join....

 progressBarUpdate(1, 10000 ); // for some reason this makes the progress bar work like it should?????

}

If i just update once after the thread is kicked off it works like it should.  Can anyone enlighten me on why this occuring?


Thanks,

Steve


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Strange behavior with GTK::ProgressBar when updating outside the main thread.

by Fabrício Godoy :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi, I don't understood the code flow very well.
Maybe the problem is that you need to ask to main thread to update de progressbar.
A test case should be welcome.


2009/10/27 Steve Scott <sjscott007@...>
Hi,

I had this strange problem with updating a progressbar with a callback from a thread.  My app starts with a Gtk::Window and when an event occurs a basic dialog box with two buttons is displayed.  The two buttons are "copy" and "close".  Inside the dialog I create a thread as shown below:

void g_FileCopyDialog::copyFrom()
{

 Glib::Thread *const thread = Glib::Thread::create(sigc::mem_fun(*file, &DirectFile::runCopyThread), true );

// it does not join....

}

This is run after the dialog is shown (.show()) through the Gtk:Window.  Basiclly "file" is a object that handles file copies. I also have a callback in g_FileCopyDialog:

// callback method
void g_FileCopyDialog::progressBarUpdate(unsigned int position, unsigned int max )
{

    gdk_threads_enter();
    m_pcopyprogressbar->set_fraction( (double) position/max );
    gdk_threads_leave();

    while( Gtk::Main::events_pending() )
        Gtk::Main::iteration();

}

With this setup the progress bar does not update.  But if I just press the "Close" button (which doesn't close the dialog.  I didnt setup the event yet) while the file is copying it will show the progress bar working.  This was driving me nuts, and I spent almost a day trying to get it working right.   Finally after trying all different things I decided to try updating the progress bar after I created the thread like this:

void g_FileCopyDialog::copyFrom()
{

 Glib::Thread *const thread = Glib::Thread::create(sigc::mem_fun(*file, &DirectFile::runCopyThread), true );

// it does not join....

 progressBarUpdate(1, 10000 ); // for some reason this makes the progress bar work like it should?????

}

If i just update once after the thread is kicked off it works like it should.  Can anyone enlighten me on why this occuring?


Thanks,

Steve


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list




--
Evite spam use o campo Cco
http://emailfalso.blogspot.com/2009/04/voce-sabe-o-que-e-cco.html

_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Parent Message unknown Fwd: Strange behavior with GTK::ProgressBar when updating outside the main thread.

by Steve Scott-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Fabricio,

I got a Gtk:Window (This is my main window).  I also have a dialog box( which is still part of the main thread, and created by my main window).  In the dialog I create a new thread and register with the new thread a callback(e.g. g_FileCopyDialog::progressBarUpdate). So it looks like this:

Thread 1 - Main Gtk App (MainWindow, g_FileCopyDialog)
Thread 2 - File COPY THREAD.  This is a thread created in g_FileCopyDialog, (DirectFile::runCopyThread)

Thread 1 registers the a callback to thread 1 via: file->copy_progress.connect( sigc::mem_fun(*this, &g_FileCopyDialog::progressBarUpdate) );

Thread 1 creates the file copy thread via:   Glib::Thread *const thread = Glib::Thread::create(sigc::
mem_fun(*file, &DirectFile::runCopyThread), true );

Thread 1 does NOT join thread 2 after its created

Thread 2 will then "run"  and call g_FileCopyDialog::progressBarUpdate every time 512 bytes are copied.  This works like a charm.

The problem is that even though the g_FileCopyDialog::progressBarUpdate is being called everytime like it should,  the progress bar does not update unless I call m_pcopyprogressbar->set_fraction( .01) first with some fictionous value in THREAD 1.

I can post the entire gtk::dialog and the DirectFile class if you want me too, but i tried not to post everything to keep it simple.

Let me know,

Steve


2009/10/27 Fabrício Godoy <skarllot@...>

Hi, I don't understood the code flow very well.
Maybe the problem is that you need to ask to main thread to update de progressbar.
A test case should be welcome.





_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Strange behavior with GTK::ProgressBar when updating outside the main thread.

by Chris Vine :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, 27 Oct 2009 13:49:54 -0500
Steve Scott <sjscott007@...> wrote:

> I got a Gtk:Window (This is my main window).  I also have a dialog
> box( which is still part of the main thread, and created by my main
> window).  In the dialog I create a new thread and register with the
> new thread a callback(e.g. g_FileCopyDialog::progressBarUpdate). So
> it looks like this:
>
> Thread 1 - Main Gtk App (MainWindow, g_FileCopyDialog)
> Thread 2 - File COPY THREAD.  This is a thread created in
> g_FileCopyDialog, (DirectFile::runCopyThread)
>
> Thread 1 registers the a callback to thread 1 via:
> file->copy_progress.connect( sigc::mem_fun(*this,
> &g_FileCopyDialog::progressBarUpdate) );
>
> Thread 1 creates the file copy thread via:   Glib::Thread *const
> thread = Glib::Thread::create(sigc::
> mem_fun(*file, &DirectFile::runCopyThread), true );
>
> Thread 1 does NOT join thread 2 after its created
>
> Thread 2 will then "run"  and call
> g_FileCopyDialog::progressBarUpdate every time 512 bytes are copied.
> This works like a charm.
>
> The problem is that even though the
> g_FileCopyDialog::progressBarUpdate is being called everytime like it
> should,  the progress bar does not update unless I call
> m_pcopyprogressbar->set_fraction( .01) first with some fictionous
> value in THREAD 1.

You are almost certainly doing something wrong with the way your
threads interface with gtkmm and libsigc++.  It may well not be the
cause of your problem but I notice for example (so far as I can make
sense of your explanation) that you connect a signal 'copy_press' to a
slot representing g_FileCopyDialog::progressBarUpdate() in thread 1, and
appear to emit that signal in thread 2 (you say that thread 2 will "call
g_FileCopyDialog::progressBarUpdate every time 512 bytes are copied").
That in itself is going to lead to trouble because libsigc++ is not
thread safe and you would need a synchronising mutex to be locked every
time that the signal object is manipulated in some way, including when
it is emitted. sigc::trackable is also not thread safe and can be a
cause of various side effects (and cannot sensibly be protected by an
external mutex).

Using the GDK global lock will not save you with respect to libsigc++,
even if you are using the global lock correctly.  You will probably be a
lot better off using Glib::Dispatcher.

Chris


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: Strange behavior with GTK::ProgressBar when updating outside the main thread.

by Steve Scott-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Chris,

You were right on with using Gtk::Dispatcher.  Once I converted everything over it work as it should.  No more strange things occurring.  I had quite a few changes to make thats what took me so long to respond.

Thanks again for your help.

Steve

On Tue, Oct 27, 2009 at 8:09 PM, Chris Vine <chris@...> wrote:
On Tue, 27 Oct 2009 13:49:54 -0500
Steve Scott <sjscott007@...> wrote:
> I got a Gtk:Window (This is my main window).  I also have a dialog
> box( which is still part of the main thread, and created by my main
> window).  In the dialog I create a new thread and register with the
> new thread a callback(e.g. g_FileCopyDialog::progressBarUpdate). So
> it looks like this:
>
> Thread 1 - Main Gtk App (MainWindow, g_FileCopyDialog)
> Thread 2 - File COPY THREAD.  This is a thread created in
> g_FileCopyDialog, (DirectFile::runCopyThread)
>
> Thread 1 registers the a callback to thread 1 via:
> file->copy_progress.connect( sigc::mem_fun(*this,
> &g_FileCopyDialog::progressBarUpdate) );
>
> Thread 1 creates the file copy thread via:   Glib::Thread *const
> thread = Glib::Thread::create(sigc::
> mem_fun(*file, &DirectFile::runCopyThread), true );
>
> Thread 1 does NOT join thread 2 after its created
>
> Thread 2 will then "run"  and call
> g_FileCopyDialog::progressBarUpdate every time 512 bytes are copied.
> This works like a charm.
>
> The problem is that even though the
> g_FileCopyDialog::progressBarUpdate is being called everytime like it
> should,  the progress bar does not update unless I call
> m_pcopyprogressbar->set_fraction( .01) first with some fictionous
> value in THREAD 1.

You are almost certainly doing something wrong with the way your
threads interface with gtkmm and libsigc++.  It may well not be the
cause of your problem but I notice for example (so far as I can make
sense of your explanation) that you connect a signal 'copy_press' to a
slot representing g_FileCopyDialog::progressBarUpdate() in thread 1, and
appear to emit that signal in thread 2 (you say that thread 2 will "call
g_FileCopyDialog::progressBarUpdate every time 512 bytes are copied").
That in itself is going to lead to trouble because libsigc++ is not
thread safe and you would need a synchronising mutex to be locked every
time that the signal object is manipulated in some way, including when
it is emitted. sigc::trackable is also not thread safe and can be a
cause of various side effects (and cannot sensibly be protected by an
external mutex).

Using the GDK global lock will not save you with respect to libsigc++,
even if you are using the global lock correctly.  You will probably be a
lot better off using Glib::Dispatcher.

Chris




_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list