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

Reply via email to