[gparted/psusi/refactor: 2/19] Use a full fledged nested main loop while waiting and pulsing progress bars (#685740)
- From: Phillip Susi <psusi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gparted/psusi/refactor: 2/19] Use a full fledged nested main loop while waiting and pulsing progress bars (#685740)
- Date: Mon, 11 Mar 2013 23:13:50 +0000 (UTC)
commit 156e9e2840005ce9754f84ea09c1299a34444f60
Author: Phillip Susi <psusi ubuntu com>
Date: Mon Jan 14 21:20:49 2013 -0500
Use a full fledged nested main loop while waiting and pulsing progress bars (#685740)
Win_Gparted and Dialog_Progress were looping on Gtk::Main::events_pending()
and iteration() with usleeps in between. Use a full mainloop instead and
a proper timeout to trigger pulsebar updates instead of usleeps.
Part of Bug 685740 - Refactor to use asynchronous command execution
include/Dialog_Progress.h | 5 ++-
include/Win_GParted.h | 3 +-
src/Dialog_Progress.cc | 41 +++++++++++++-----------
src/Win_GParted.cc | 74 ++++++++++++++++++++------------------------
4 files changed, 60 insertions(+), 63 deletions(-)
---
diff --git a/include/Dialog_Progress.h b/include/Dialog_Progress.h
index e3be49e..a580ddb 100644
--- a/include/Dialog_Progress.h
+++ b/include/Dialog_Progress.h
@@ -57,6 +57,7 @@ private:
void on_response( int response_id ) ;
bool on_delete_event( GdkEventAny * event ) ;
+ bool pulsebar_pulse();
Gtk::Label label_current ;
Gtk::Label label_current_sub ;
@@ -91,11 +92,11 @@ private:
std::vector<Operation *> operations ;
OperationDetail operationdetail ;
- bool running, succes, cancel, pulse ;
+ bool succes, cancel;
pthread_t pthread ;
double fraction ;
unsigned int t, warnings ;
-
+ sigc::connection pulsetimer;
Glib::Dispatcher dispatcher_update_gui_elements ;
Glib::ustring label_current_sub_text ;
};
diff --git a/include/Win_GParted.h b/include/Win_GParted.h
index d9a2e41..15a4f34 100644
--- a/include/Win_GParted.h
+++ b/include/Win_GParted.h
@@ -259,8 +259,7 @@ private:
std::vector<Gtk::Label *> device_info ;
//stuff for progress overview and pulsebar
- Glib::Thread *thread ;
- bool pulse ;
+ bool pulsebar_pulse();
};
} //GParted
diff --git a/src/Dialog_Progress.cc b/src/Dialog_Progress.cc
index dd314e8..6e3fe2f 100644
--- a/src/Dialog_Progress.cc
+++ b/src/Dialog_Progress.cc
@@ -152,8 +152,6 @@ void Dialog_Progress::on_signal_update( const OperationDetail & operationdetail
break ;
}
- pulse = operationdetail .fraction < 0 ;
-
//update the gui elements..
this ->operationdetail = operationdetail ;
@@ -161,6 +159,11 @@ void Dialog_Progress::on_signal_update( const OperationDetail & operationdetail
label_current_sub_text = operationdetail .get_description() ;
dispatcher_update_gui_elements() ;
+ if ( operationdetail.fraction >= 0 ) {
+ pulsetimer.disconnect();
+ progressbar_current.set_fraction( operationdetail.fraction > 1.0 ? 1.0 :
operationdetail.fraction );
+ } else if( !pulsetimer.connected() )
+ pulsetimer = Glib::signal_timeout().connect( sigc::mem_fun(*this,
&Dialog_Progress::pulsebar_pulse), 100 );
}
else//it's an new od which needs to be added to the model.
{
@@ -183,13 +186,16 @@ void Dialog_Progress::dispatcher_on_update_gui_elements()
{
label_current_sub .set_markup( "<i>" + label_current_sub_text + "</i>\n" ) ;
- if ( operationdetail .fraction >= 0 )
- progressbar_current .set_fraction( operationdetail .fraction > 1.0 ? 1.0 : operationdetail
.fraction ) ;
-
//To ensure progress bar height remains the same, add a space in case message is empty
progressbar_current .set_text( operationdetail .progress_text + " " ) ;
}
+bool Dialog_Progress::pulsebar_pulse()
+{
+ progressbar_current.pulse();
+ return true;
+}
+
void Dialog_Progress::on_signal_show()
{
for ( t = 0 ; t < operations .size() && succes && ! cancel ; t++ )
@@ -211,19 +217,8 @@ void Dialog_Progress::on_signal_show()
treeview_operations .set_cursor( static_cast<Gtk::TreePath>( treerow ) ) ;
//and start..
- running = true ;
pthread_create( & pthread, NULL, Dialog_Progress::static_pthread_apply_operation, this );
-
- while ( running )
- {
- if ( pulse )
- progressbar_current .pulse() ;
-
- while ( Gtk::Main::events_pending() )
- Gtk::Main::iteration();
- usleep( 100000 ) ;
- }
-
+ Gtk::Main::run();
//set status (succes/error) for this operation
operations[ t ] ->operation_detail .set_status( succes ? STATUS_SUCCES : STATUS_ERROR ) ;
}
@@ -236,6 +231,8 @@ void Dialog_Progress::on_signal_show()
this ->get_action_area() ->remove( * children .back() ) ;
this ->add_button( Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE );
+ pulsetimer.disconnect();
+
if ( cancel )
{
progressbar_current .set_text( _("Operation cancelled") ) ;
@@ -299,13 +296,19 @@ void Dialog_Progress::on_cell_data_description( Gtk::CellRenderer * renderer, co
static_cast<Gtk::TreeRow>( *iter )[ treeview_operations_columns .operation_description ] ;
}
+static bool _mainquit( void *dummy )
+{
+ Gtk::Main::quit();
+ return false;
+}
+
void * Dialog_Progress::static_pthread_apply_operation( void * p_dialog_progress )
{
Dialog_Progress *dp = static_cast<Dialog_Progress *>( p_dialog_progress ) ;
dp ->succes = dp ->signal_apply_operation .emit( dp ->operations[ dp ->t ] ) ;
- dp ->running = false ;
+ g_idle_add( (GSourceFunc)_mainquit, NULL );
return NULL ;
}
@@ -328,7 +331,7 @@ void Dialog_Progress::on_cancel()
{
pthread_cancel( pthread ) ;
cancel = true ;
- running = false ;
+ Gtk::Main::quit();
succes = false ;
}
}
diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc
index 0c8302d..4e3e859 100644
--- a/src/Win_GParted.cc
+++ b/src/Win_GParted.cc
@@ -53,7 +53,6 @@ Win_GParted::Win_GParted( const std::vector<Glib::ustring> & user_devices )
selected_partition .Reset() ;
new_count = 1;
current_device = 0 ;
- pulse = false ;
OPERATIONSLIST_OPEN = true ;
gparted_core .set_user_devices( user_devices ) ;
@@ -608,8 +607,22 @@ void Win_GParted::refresh_combo_devices()
combo_devices .set_active( current_device ) ;
}
+bool Win_GParted::pulsebar_pulse()
+{
+ pulsebar.pulse();
+ Glib::ustring tmp_msg = gparted_core .get_thread_status_message() ;
+ if ( tmp_msg != "" ) {
+ statusbar.pop();
+ statusbar.push( tmp_msg );
+ }
+
+ return true;
+}
+
void Win_GParted::show_pulsebar( const Glib::ustring & status_message )
{
+ sigc::connection pulsetimer;
+
pulsebar .show();
statusbar .push( status_message) ;
@@ -621,20 +634,10 @@ void Win_GParted::show_pulsebar( const Glib::ustring & status_message )
treeview_detail .set_sensitive( false ) ;
drawingarea_visualdisk .set_sensitive( false ) ;
- //the actual 'pulsing'
- while ( pulse )
- {
- pulsebar .pulse();
- while ( Gtk::Main::events_pending() )
- Gtk::Main::iteration();
- usleep( 100000 );
- Glib::ustring tmp_msg = gparted_core .get_thread_status_message() ;
- if ( tmp_msg != "" )
- statusbar .push( tmp_msg ) ;
- }
-
- thread ->join() ;
-
+ // connect pulse update timer
+ pulsetimer = Glib::signal_timeout().connect( sigc::mem_fun(*this, &Win_GParted::pulsebar_pulse), 100
);
+ Gtk::Main::run();
+ pulsetimer.disconnect();
pulsebar .hide();
statusbar .pop() ;
@@ -1199,13 +1202,12 @@ void Win_GParted::on_show()
void Win_GParted::thread_refresh_devices()
{
gparted_core .set_devices( devices ) ;
- pulse = false ;
+ Gtk::Main::quit();
}
void Win_GParted::menu_gparted_refresh_devices()
{
- pulse = true ;
- thread = Glib::Thread::create( sigc::mem_fun( *this, &Win_GParted::thread_refresh_devices ), true ) ;
+ Glib::Thread::create( sigc::mem_fun( *this, &Win_GParted::thread_refresh_devices ), false );
show_pulsebar( _("Scanning all devices...") ) ;
@@ -2012,7 +2014,7 @@ void Win_GParted::thread_unmount_partition( bool * succes, Glib::ustring * error
else
*error = "<i>" + Glib::build_path( "\n", errors ) + "</i>" ;
- pulse = false ;
+ Gtk::Main::quit();
}
void Win_GParted::thread_mount_partition( Glib::ustring mountpoint, bool * succes, Glib::ustring * error )
@@ -2023,8 +2025,7 @@ void Win_GParted::thread_mount_partition( Glib::ustring mountpoint, bool * succe
*succes = ! Utils::execute_command( "mount -v " + selected_partition .get_path() + " \"" + mountpoint
+ "\"",
dummy,
*error ) ;
-
- pulse = false ;
+ Gtk::Main::quit();
}
void Win_GParted::thread_toggle_swap( bool * succes, Glib::ustring * error )
@@ -2039,8 +2040,7 @@ void Win_GParted::thread_toggle_swap( bool * succes, Glib::ustring * error )
*succes = ! Utils::execute_command( "swapon -v " + selected_partition .get_path() + " &&
sync",
dummy,
*error ) ;
-
- pulse = false ;
+ Gtk::Main::quit();
}
void Win_GParted::thread_toggle_lvm2_pv( bool * success, Glib::ustring * error )
@@ -2056,8 +2056,7 @@ void Win_GParted::thread_toggle_lvm2_pv( bool * success, Glib::ustring * error )
*success = ! Utils::execute_command( "lvm vgchange -a y " + selected_partition
.get_mountpoint(),
dummy,
*error ) ;
-
- pulse = false ;
+ Gtk::Main::quit();
}
// Runs gpart in a thread
@@ -2065,7 +2064,7 @@ void Win_GParted::thread_guess_partition_table()
{
this->gpart_output="";
this->gparted_core.guess_partition_table(devices[ current_device ], this->gpart_output);
- pulse=false;
+ Gtk::Main::quit();
}
void Win_GParted::toggle_busy_state()
@@ -2116,12 +2115,10 @@ void Win_GParted::toggle_busy_state()
bool succes = false ;
Glib::ustring error ;
- pulse = true ;
-
if ( selected_partition .filesystem == GParted::FS_LINUX_SWAP )
{
- thread = Glib::Thread::create( sigc::bind<bool *, Glib::ustring *>(
- sigc::mem_fun( *this, &Win_GParted::thread_toggle_swap ), &succes, &error ), true ) ;
+ Glib::Thread::create( sigc::bind<bool *, Glib::ustring *>(
+ sigc::mem_fun( *this, &Win_GParted::thread_toggle_swap ), &succes, &error ), false );
show_pulsebar(
String::ucompose(
@@ -2145,8 +2142,8 @@ void Win_GParted::toggle_busy_state()
}
else if ( selected_partition .filesystem == GParted::FS_LVM2_PV )
{
- thread = Glib::Thread::create( sigc::bind<bool *, Glib::ustring *>(
- sigc::mem_fun( *this, &Win_GParted::thread_toggle_lvm2_pv ), &succes, &error ), true
) ;
+ Glib::Thread::create( sigc::bind<bool *, Glib::ustring *>(
+ sigc::mem_fun( *this, &Win_GParted::thread_toggle_lvm2_pv ), &succes, &error ), false
);
show_pulsebar(
String::ucompose(
@@ -2173,8 +2170,8 @@ void Win_GParted::toggle_busy_state()
}
else if ( selected_partition .busy )
{
- thread = Glib::Thread::create( sigc::bind<bool *, Glib::ustring *>(
- sigc::mem_fun( *this, &Win_GParted::thread_unmount_partition ), &succes, &error ),
true ) ;
+ Glib::Thread::create( sigc::bind<bool *, Glib::ustring *>(
+ sigc::mem_fun( *this, &Win_GParted::thread_unmount_partition ), &succes, &error ),
false );
show_pulsebar( String::ucompose( _("Unmounting %1"), selected_partition .get_path() ) ) ;
@@ -2228,14 +2225,12 @@ void Win_GParted::activate_mount_partition( unsigned int index )
bool succes = false ;
Glib::ustring error ;
- pulse = true ;
-
- thread = Glib::Thread::create( sigc::bind<Glib::ustring, bool *, Glib::ustring *>(
+ Glib::Thread::create( sigc::bind<Glib::ustring, bool *, Glib::ustring *>(
sigc::mem_fun( *this, &Win_GParted::thread_mount_partition ),
selected_partition .get_mountpoints()[ index ],
&succes,
&error ),
- true ) ;
+ false );
show_pulsebar( String::ucompose( _("mounting %1 on %2"),
selected_partition .get_path(),
@@ -2380,8 +2375,7 @@ void Win_GParted::activate_attempt_rescue_data()
messageDialog.hide();
- pulse=true;
- this->thread = Glib::Thread::create( sigc::mem_fun( *this, &Win_GParted::thread_guess_partition_table
), true ) ;
+ Glib::Thread::create( sigc::mem_fun( *this, &Win_GParted::thread_guess_partition_table ), false );
/*TO TRANSLATORS: looks like Searching for file systems on /deb/sdb */
show_pulsebar(String::ucompose( _("Searching for file systems on %1"), devices[ current_device ]
.get_path()));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]