Subject: FVWM: Re: race on module-death still here

From: Mark Crimmins <[email-masked]>
Date: Sat, 25 May 1996 15:59:48 -0400

To follow up on myself:

I'm having problems with fvwm2 (42) racing when tkgoodstuff (my fvwm
module) stops and starts a few times).

Below I attach the strace output.  The wait and select calls are
apparantly from My_XNextEvent, and the write apparently is in
FlushQueue.  This code isn't transparent to me, so I'm hoping someone
will read this who knows what might be going on.  Could it be that
fvwm thinks it still has to write to a pipe to a child (module) that
in fact does not exist?  In the module docs it says fvwm assumes a
module has died only when it gets a read error on the read pipe.  In
my traces, it looks like fvwm is trying to write and not read; is
there a bug in how fvwm knows whether modules have died?

Thanks for any advice,
Mark

>wait4(-1, NULL, WNOHANG, NULL)          = 0
>select(256, [3 9 13], [12], NULL, NULL) = 1 (out [12])
>write(12, "\377\377\377\377\0\4\0\0\t\0\0\000"..., 36) = -1 EAGAIN (Try again)
>ioctl(3, FIONREAD, [0])                 = 0
>wait4(-1, NULL, WNOHANG, NULL)          = 0
>select(256, [3 9 13], [12], NULL, NULL) = 1 (out [12])
>write(12, "\377\377\377\377\0\4\0\0\t\0\0\000"..., 36) = -1 EAGAIN (Try again)
>ioctl(3, FIONREAD, [0])                 = 0
>wait4(-1, NULL, WNOHANG, NULL)          = 0
>select(256, [3 9 13], [12], NULL, NULL) = 1 (out [12])
>
>(etc.)
>
>When I kill tkgoodstuff (having killed other instances before), it
>changes to this: 
>
>select(256, [3 13], [12], NULL, NULL)   = 1 (out [12])
>write(12, "\377\377\377\377\0\4\0\0\t\0\0\000"..., 36) = -1 EAGAIN (Try again)
>ioctl(3, FIONREAD, [0])                 = 0
>wait4(-1, NULL, WNOHANG, NULL)          = -1 ECHILD (No child processes)
>select(256, [3 13], [12], NULL, NULL)   = 1 (out [12])
>write(12, "\377\377\377\377\0\4\0\0\t\0\0\000"..., 36) = -1 EAGAIN (Try again)
>ioctl(3, FIONREAD, [0])                 = 0
>wait4(-1, NULL, WNOHANG, NULL)          = -1 ECHILD (No child processes)
>select(256, [3 13], [12], NULL, NULL)   = 1 (out [12])
>write(12, "\377\377\377\377\0\4\0\0\t\0\0\000"..., 36) = -1 EAGAIN (Try again)
>ioctl(3, FIONREAD, [0])                 = 0
>wait4(-1, NULL, WNOHANG, NULL)          = -1 ECHILD (No child processes)
>select(256, [3 13], [12], NULL, NULL)   = 1 (out [12])
>
>(etc.)
>
>Mark
>--
>Visit the official FVWM web page at <URL:http://www.hpc.uh.edu/fvwm/>.
>To unsubscribe from the list, send "unsubscribe fvwm" in the body of a
>message to [email-masked].
>To report problems, send mail to [email-masked].
>
--
Visit the official FVWM web page at <URL:http://www.hpc.uh.edu/fvwm/>.
To unsubscribe from the list, send "unsubscribe fvwm" in the body of a
message to [email-masked].
To report problems, send mail to [email-masked].

---

From: Mark Crimmins <[email-masked]>
Date: Mon, 27 May 1996 11:54:59 -0400

Well, I have a patch that doesn't really fix things, but lets me work
around the bug that (so far) only bothers tkgoodstuff.

I've tracked down the bug: the race condition happens when a few
instances of tkgoodstuff have left child processes when they exited.
Fvwm doesn't notice that the tkgoodstuff instances are gone until
until the child processes (of the dead and gone tkgoodstuff processes)
exit.  The race condition goes away when the child processes exit (at
that point, the call to KillModule gets made).

This doesn't happen with FvwmButtons because FvwmButtons doesn't fork
children (but tells fvwm to).

I don't know if there is any better way of sensing module death than
the one fvwm currently uses.  If there is one, it would be best to use
it, of course.  But in any case, one workaround that would make me
happy would be for fvwm to allow a module to tell fvwm to kill it.
Here's a patch that allows this (the module sends "KillMe"):

*** ../fvwm-2.0.42/fvwm/module.c	Tue Apr  2 11:53:31 1996
--- fvwm/module.c	Mon May 27 11:53:28 1996
***************
*** 304,309 ****
--- 304,315 ----
        extern int Context;
        FvwmWindow *tmp_win;
  
+       if(mystrncasecmp(text,"KillMe",6)==0) 
+ 	{
+           KillModule(channel,12);
+           return;
+ 	}
+ 
        /* If a module does XUngrabPointer(), it can now get proper Popups */
        if(mystrncasecmp(text,"popup",5)==0)
  	  Event.xany.type = ButtonPress;

I hope you (Chuck) will consider this.

Thanks, and bandwidth apologies,
Mark