On Sat, Feb 14, 2009 at 09:27:53PM +0000, Thomas Adam wrote:
> For too long a time now, I have been getting annoying freezes when
> resizing a window. I've been able to track the problem down to
> module_list.c as per the following check:
>
> if (!FD_ISSET(channel, &writeSet))
> {
> char *name;
>
> name = get_pipe_name(module);
> /* Doh! Something has gone wrong - get
> * rid of the offender! */
> fvwm_msg(
> ERR, "FlushMessageQueue",
> "Failed to write descriptor to"
> " '%s':\n"
> "- select rc=%d\n"
> "- terminate signal=%c\n",
> name, rc, isTerminated ?
> 'Y' : 'N');
> module_kill(module);
>
> return;
> }
>
> I would argue such a check is redundant, since the freeze happens as
> soon as I start to resize a window, which is stupid since nothing has
> gone wrong at the point. Indeed, a simple "return;" at the beginning
> of the blocks alleviates the issue -- is this check even relevant?
Yes, it is. Fvwm is trying to send a message to a module ...
a = write(MOD_WRITEFD(module), &dptr[obj->done],
obj->size - obj->done);
if (a >=0)
...
... that is not accepting input at that time ...
else if (errno == EWOULDBLOCK || errno == EAGAIN)
{
...
... and waits for the module pipe to become writeable.
do
{
/* Wait until the pipe accepts further
* input */
timeout.tv_sec = moduleTimeout;
timeout.tv_usec = 0;
FD_ZERO(&writeSet);
FD_SET(channel, &writeSet);
rc = fvwmSelect(
channel + 1, NULL, &writeSet,
NULL, &timeout);
/* retry if select() failed with EINTR
*/
} while ((rc < 0) && !isTerminated &&
(errno == EINTR));
...
If that does not happen, the module is marked for destruction:
if (!FD_ISSET(channel, &writeSet))
{
char *name;
name = get_pipe_name(module);
/* Doh! Something has gone wrong - get
* rid of the offender! */
fvwm_msg(
ERR, "FlushMessageQueue",
"Failed to write descriptor to"
" '%s':\n"
"- select rc=%d\n"
"- terminate signal=%c\n",
name, rc, isTerminated ?
'Y' : 'N');
module_kill(module);
return;
}
I don't understand how putting a "return" after the
"if (!FD_ISSET(...))" fixes your problem as the code that is
executed inside the if block should always complete without
waiting.
--
I think you either running some bad module that crashes or hangs
at random times, or a module that tries to send a synchronous
command as a reaction to some fvwm message occuring about at the
same time as the messages. The log message should tell you which
module was killed.
To get a hold on the problem, I suggest you try to find out which
messages fvwm and the module exchange. (Do we have some module
message debugging code?).
Ciao
Dominik ^_^ ^_^
--
Dominik Vogt