Mike Martin wrote:
> Hi
>
> I was always under the impression that a foreach loop iterated over a
> list sequentially, which in every other case at least seems to happen.
>
> However I have the following code

     foreach file
         run command on file

> Which runs the following sub-routine (abrev) for each file ($files above)
>
> sub run_cmd {
> $pid=open($file, "-|","$cmd{$subname} 2>&1") or die "Failed running
> perl subprocess\n";

This forks a child that runs concurrently....

   [snip text buffer setup]

> our $tag=  Glib::IO->add_watch ( fileno($file), ['in', 'hup'], sub {
        [snip]
        }
        );

This installs a callback to be run by the main loop when data arrives on the
file handle connected to the child's output, or when that file hangs up.


> }

And then you return.


Which means that all run_cmd() actually does is fork the child and set up the
main loop to listen to it.  It does not wait, irrespective of what the
callback does.


> However the sub is run for each file in parallel. Anyone have any idea
> how to force sequential mode?

You need to keep the UI responsive while this is happening, so you must run a
main loop.  You can run a main loop at the end of run_cmd() to keep the
control flow stopped there until either the child completes and kills the main
loop, or a cancel button causes you to kill the child and quit that nested
main loop.  E.g.:

  sub run_cmd  {

      my $file = open_child_process (...);

      Glib::IO->add_watch (fileno ($file), ['in', 'hup'], sub {
                     my (undef, $cond) = @_;
                     if (user_wants_to_cancel ()) {
                         kill_child ();
                         # let this proceed naturally; we'll get another
                         # call with HUP next time around.
                     }
                     if ($cond >= 'in') {
                         handle_the_input_data ();
                     }
                     if ($cond >= 'hup') {
                         close ($file);
                         # Kill the nested main loop, see below
                         Gtk2->main_quit ();
                         return FALSE;
                     }
                     return TRUE;
                });

      # Now wait here for the IO watch to kill this nested main loop.
      Gtk2->main ();

    }



-- 
muppet <scott at asofyet dot org>

_______________________________________________
gtk-perl-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtk-perl-list

Reply via email to