[gparted/psusi/refactor] fixup! Reduce threading (#685740)



commit 79ba586d0ce05ae265169f6c7adeb886acb272ea
Author: Phillip Susi <psusi ubuntu com>
Date:   Thu Feb 28 19:40:22 2013 -0500

    fixup! Reduce threading (#685740)
    
    The GParted GUI would occasionally hang in scanning devices, or when
    applying operations.  When this occurred, it appears that the spawned
    command had completed before gparted could connect to the input/output
    signal.
    
    With modern GNU/Linux distributions this problem occurs very
    rarely.  Fortunately the problem would regularly occur in my openSUSE
    11.2 virtual machine.  This permitted Phillip and me to debug and
    address the problem.
    
    Part of Bug 685740 - Refactor to use asynchronous command execution

 include/PipeCapture.h |    1 +
 src/FileSystem.cc     |    2 ++
 src/PipeCapture.cc    |    5 +++++
 src/Utils.cc          |    7 ++++++-
 4 files changed, 14 insertions(+), 1 deletions(-)
---
diff --git a/include/PipeCapture.h b/include/PipeCapture.h
index 440e345..b141bc8 100644
--- a/include/PipeCapture.h
+++ b/include/PipeCapture.h
@@ -18,6 +18,7 @@ class PipeCapture
        bool OnReadable( Glib::IOCondition condition );
 public:
        PipeCapture( int fd, Glib::ustring &buffer );
+       void connect_signal( int fd );
        ~PipeCapture();
        sigc::signal<void> eof;
        sigc::signal<void> update;
diff --git a/src/FileSystem.cc b/src/FileSystem.cc
index 74cc6ed..0895bd0 100644
--- a/src/FileSystem.cc
+++ b/src/FileSystem.cc
@@ -123,6 +123,8 @@ int FileSystem::execute_command( const Glib::ustring & command, OperationDetail
        errorcapture.update.connect( sigc::bind( sigc::ptr_fun( relay_update ),
                                                 &(children[children.size() - 1]),
                                                 &error ) );
+       outputcapture.connect_signal( out );
+       errorcapture.connect_signal( err );
 
        operationdetail.get_last_child().signal_cancel.connect(
                sigc::bind(
diff --git a/src/PipeCapture.cc b/src/PipeCapture.cc
index c764c9c..f7e409e 100644
--- a/src/PipeCapture.cc
+++ b/src/PipeCapture.cc
@@ -8,6 +8,11 @@ PipeCapture::PipeCapture( int fd, Glib::ustring &string ) : buff( string ), back
        // tie fd to string
        // make channel
        channel = Glib::IOChannel::create_from_fd( fd );
+}
+
+void PipeCapture::connect_signal( int fd )
+{
+       // connect handler to signal input/output
        connection = Glib::signal_io().connect(
                sigc::mem_fun( *this, &PipeCapture::OnReadable ),
                fd,
diff --git a/src/Utils.cc b/src/Utils.cc
index 9a3b238..694cf0e 100644
--- a/src/Utils.cc
+++ b/src/Utils.cc
@@ -468,17 +468,22 @@ int Utils::execute_command( const Glib::ustring & command,
                                            pid );
        output.clear();
        error.clear();
+       //Lock mutex so we have time to setup pipecapture for output and error streams
+       //  before connecting the input/output signal handler
+       if( !status.foreground )
+               status.mutex.lock();
        PipeCapture outputcapture( out, output );
        PipeCapture errorcapture( err, error );
        outputcapture.eof.connect( sigc::mem_fun(
                 status, &utils_execute_command_status::execute_command_eof ));
        errorcapture.eof.connect( sigc::mem_fun(
                 status, &utils_execute_command_status::execute_command_eof ));
+       outputcapture.connect_signal( out );
+       errorcapture.connect_signal( err );
 
        if( status.foreground)
                Gtk::Main::run();
        else {
-               status.mutex.lock();
                status.cond.wait( status.mutex );
                status.mutex.unlock();
        }


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