Forking from inside a GTK loop

From within a GTK loop, I need to fork independent processes, that the
main process must forget about.

If after fork() I call exec(), thus eventually calling a new instance
of the Ruby interpreter, all goes OK.

If, instead, I call a Ruby method, I can then leave the main loop and
get back to the system prompt, but the GTK window will not disappear
until the daemon completes.

Look at the attached test program. If I run it, and then click on the
provided button, the sub-process that sleeps for a long time will be
started and appropriately daemonized, and I will be back to the shell
prompt, but the small window will not disappear from my screen until
either the process terminates or I kill it. It is not repainted
anymore (remains all grey), but it remains there nevertheless.

Am I overlooking something?

I use Linux (current kernel), the latest Ruby from SVN and the latest
Ruby-gnome2 from git.

Carlo

On 25 September 2011 10:33, Carlo E. Prelz [email protected] wrote:

From within a GTK loop, I need to fork independent processes, that the
main process must forget about.

If after fork() I call exec(), thus eventually calling a new instance
of the Ruby interpreter, all goes OK.

If, instead, I call a Ruby method, I can then leave the main loop and
get back to the system prompt, but the GTK window will not disappear
until the daemon completes.

It’s because a forked process shares the file descriptors of the
parent - so your background thread still shares the parent’s open
connection to the X Server.

As far as the X Server is concerned, the client connection is still
open.

If you make sure that you explicitly destroy your windows when you
exit, that would help here.

ie. After the mainloop exits, call something like:

Gtk::Window.toplevels.each(&:destroy)
Gdk::Display.default.flush

to destroy all the windows.

Alternatively you could try something dodgy with file descriptors in
the fork’d process - and manually closing them. But that’s less
portable and a bit hacky…

HTH,

Geoff.

Random Musing - http://www.frafferz.com/

Subject: Re: [ruby-gnome2-devel-en] Forking from inside a GTK loop
Date: dom 25 set 11 06:26:27 +0100

Quoting Geoff Y. ([email protected]):

It’s because a forked process shares the file descriptors of the
parent - so your background thread still shares the parent’s open
connection to the X Server.

As far as the X Server is concerned, the client connection is still
open.

Ah! I thought Process::daemon cared for closing file descriptors, thus
I did not search in that direction… Now I see that Process::daemon
only closes stdin, stdout and stderr.

If you make sure that you explicitly destroy your windows when you
exit, that would help here.

ie. After the mainloop exits, call something like:

Gtk::Window.toplevels.each(&:destroy)
Gdk::Display.default.flush

to destroy all the windows.

Works perfectly.

Thanks a lot!

Carlo

  •     Se la Strada e la sua Virtu' non fossero state messe da 
    

parte,

  • K * Carlo E. Prelz - [email protected] che bisogno ci
    sarebbe
    •           di parlare tanto di amore e di rettitudine? 
      

(Chuang-Tzu)