Avoid glibmm GSource bug/crash (#697727)
The glibmm GSource wrappers have a bug where they do not do reference counting properly, and have a race condition where the background thread can try to touch the source after the main thread has already processed and destroyed it. This results in writes to freed memory and sometimes this causes crashes or other erratic behavior. Avoid using the glibmm wrappers and use glib directly. See bug #561885 for details of the glibmm bug. Bug #697727 - Segfault in livecd Gparted v 0.15.0-3 when copying partition
This commit is contained in:
parent
50ca2e5f13
commit
c36934aca5
|
@ -40,12 +40,12 @@ class copy_blocks {
|
|||
Glib::Timer timer_total;
|
||||
bool success;
|
||||
Glib::ustring error_message;
|
||||
bool set_progress_info();
|
||||
void copy_thread();
|
||||
bool cancel;
|
||||
bool cancel_safe;
|
||||
void set_cancel( bool force );
|
||||
public:
|
||||
bool set_progress_info();
|
||||
copy_blocks( const Glib::ustring & in_src_device,
|
||||
const Glib::ustring & in_dst_device,
|
||||
Sector src_start,
|
||||
|
|
|
@ -94,6 +94,12 @@ static bool mainquit(copy_blocks *cb)
|
|||
return false;
|
||||
}
|
||||
|
||||
static gboolean _set_progress_info( gpointer data )
|
||||
{
|
||||
copy_blocks *cb = (copy_blocks *)data;
|
||||
return cb->set_progress_info();
|
||||
}
|
||||
|
||||
void copy_blocks::copy_thread()
|
||||
{
|
||||
if ( ped_device_open( lp_device_src ) &&
|
||||
|
@ -132,9 +138,7 @@ void copy_blocks::copy_thread()
|
|||
copy_block();
|
||||
if ( timer_progress_timeout .elapsed() >= 0.5 )
|
||||
{
|
||||
Glib::signal_idle().connect( sigc::mem_fun(
|
||||
*this,
|
||||
©_blocks::set_progress_info) );
|
||||
g_idle_add( _set_progress_info, this );
|
||||
timer_progress_timeout.reset();
|
||||
}
|
||||
}
|
||||
|
@ -151,9 +155,7 @@ void copy_blocks::copy_thread()
|
|||
}
|
||||
|
||||
//set progress bar current info on completion
|
||||
Glib::signal_idle().connect( sigc::mem_fun(
|
||||
*this,
|
||||
©_blocks::set_progress_info) );
|
||||
g_idle_add( _set_progress_info, this );
|
||||
g_idle_add( (GSourceFunc)mainquit, this );
|
||||
}
|
||||
|
||||
|
|
10
src/Utils.cc
10
src/Utils.cc
|
@ -453,6 +453,12 @@ static void set_locale()
|
|||
setenv( "LC_ALL", "C", 1 );
|
||||
}
|
||||
|
||||
static void _store_exit_status( GPid pid, gint status, gpointer data )
|
||||
{
|
||||
utils_execute_command_status *sp = (utils_execute_command_status *)data;
|
||||
sp->store_exit_status( pid, status );
|
||||
}
|
||||
|
||||
int Utils::execute_command( const Glib::ustring & command,
|
||||
Glib::ustring & output,
|
||||
Glib::ustring & error,
|
||||
|
@ -482,9 +488,7 @@ int Utils::execute_command( const Glib::ustring & command,
|
|||
}
|
||||
fcntl( out, F_SETFL, O_NONBLOCK );
|
||||
fcntl( err, F_SETFL, O_NONBLOCK );
|
||||
Glib::signal_child_watch().connect( sigc::mem_fun(
|
||||
status, &utils_execute_command_status::store_exit_status ),
|
||||
pid );
|
||||
g_child_watch_add( pid, _store_exit_status, &status );
|
||||
output.clear();
|
||||
error.clear();
|
||||
//Lock mutex so we have time to setup pipecapture for output and error streams
|
||||
|
|
Loading…
Reference in New Issue