Re: open/fork from a callback hang the windows (gtk2::helper)



2015-01-16 8:14 GMT+01:00 Brian Manning <cpan xaoc org>:
On Thu, Jan 15, 2015 at 9:21 AM, Prunk Dump <prunkdump gmail com> wrote:
But if I fork the command with "open" in a callback, the gtkmain
thread hangs until the command finish. I'm sure that the open call is
non-blocking.

sub my_callback {

   my $fd = FileHandle->new()
   open($fd, "mycommand | ") or quitCallback("can't fork")

}
--> hang on return

I don't really understand why. Maybe Gtk make the callbacks with new
threads and wait the result with waitpid ?

No, threads aren't the answer here.

I'm guessing that your script hangs because you never read from the
opened filehandle in your callback, so "mycommand" never exits because
it's waiting for it's data to be read.

On all gtk2::helper examples I've found, the "open" call is made
before Gtk2->main. How can I do if the windows is already displayed
and if I'm inside gtkmain ?

There's an example in the Gtk-Perl FAQ that uses
Gtk2::Helper->add_watch after the GUI has been displayed;

https://wiki.gnome.org/Attic/GTK2-Perl/FrequentlyAskedQuestions#How_do_I_keep_my_GUI_updating_while_doing_a_long_file_read.3F

Instead of calling open() in the callback as in your code snippet, you
make the open() call by itself, assign the filehandle created by the
open() call to a $variable, then add a watch on that filehandle
$variable via Gtk2::Helper->add_watch/Glib::IO->add_watch.
Gtk2::Helper->add_watch is just a wrapper around Glib::IO->add_watch
anyways.

Jeffery also suggested previously using IPC::open3 and
Glib::IO->add_watch to accomplish the same thing.

The FAQ also has an example of using the "threads" module, if you're
really trying to use threads, but using open() and adding a watch to
the filehandle will do what I think you are asking for, with less
pain.

Thanks,

Brian

http://perldoc.perl.org/functions/open.html
http://perldoc.perl.org/perlipc.html#Using-open()-for-IPC


Thank you very much for your help !!!

After some experiments using your propositions I finally found the
problem ! In the callback function I have created a local variable to
store the file handle :

sub my_callback {
   my $fd = FileHandle->new()
   open($fd, "mycommand | ") or quitCallback("can't fork")
}
--> hang on return

So when perl return it want to free the local $fd file descritor and
it can't because it is used for pipe redirection. Even if I pass the
local variable to the gtk2::helper->add_watch callback the problem
persist :

sub my_callback {
   my $fd = FileHandle->new()
   open($fd, "mycommand | ") or quitCallback("can't fork")
   $tag = Gtk2::Helper->add_watch($fd->fileno, 'in', sub {
watcher_callback( $fd, $tag ); });
}
--> hang on return

But changing the $fd variable for a global variable fix the problem !!!

my $globalFd;
my $globalTag;
sub my_callback {
   my $globalFd = FileHandle->new()
   open($globalFd, "mycommand | ") or quitCallback("can't fork")
   $globalTag = Gtk2::Helper->add_watch($globalFd->fileno, 'in', sub {
watcher_callback( $globalFd, $globalTag ); });
}

Thank you very much again !

Baptiste.


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