Hi,

I've found that the infinite loop where emacs goes is in the file xterm.c:

    for (count = input_signal_count + 10;
>          input_signal_count < count && !FRAME_VISIBLE_P (f);)
>       {
>         /* Force processing of queued events.  */
>         x_sync (f);
>
>         /* Machines that do polling rather than SIGIO have been
>            observed to go into a busy-wait here.  So we'll fake an
>            alarm signal to let the handler know that there's something
>            to be read.  We used to raise a real alarm, but it seems
>            that the handler isn't always enabled here.  This is
>            probably a bug.  */
>         if (input_polling_used ())
>           {
>             /* It could be confusing if a real alarm arrives while
>                processing the fake one.  Turn it off and let the
>                handler reset it.  */
>             extern void poll_for_input_1 P_ ((void));
>             int old_poll_suppress_count = poll_suppress_count;
>             poll_suppress_count = 1;
>             poll_for_input_1 ();
>             poll_suppress_count = old_poll_suppress_count;
>           }
>
>         /* See if a MapNotify event has been processed.  */
>         FRAME_SAMPLE_VISIBILITY (f);
>       }
>


Seems to be that "if (input_polling_used ())" prevents from this infinite
loop, but there is a problem with the function input_polling_used ():
It is defined in keyboard.c:

int
> input_polling_used ()
> {
> #ifdef POLL_FOR_INPUT
>   /* XXX This condition was (read_socket_hook && !interrupt_input),
>      but read_socket_hook is not global anymore.  Let's pretend that
>      it's always set. */
>   return !interrupt_input;
> #else
>   return 0
> #endif
> }
>

And interrupt_input depends on two things:

#ifdef INTERRUPT_INPUT
>   interrupt_input = 1;
> #else
>   interrupt_input = 0;
> #endif
>

in s/bsd-common.h INTERRUPT_INPUT is undefined, but in s/gnu-kfreebsd.h it
is defined, but I think the problem isn't here.

I think the problem is this:

from keyboard.c:

#ifdef SIGIO
> /* Note SIGIO has been undef'd if FIONREAD is missing.  */
> #ifdef HAVE_X_WINDOWS
>   if (x_display_list != NULL)
>     {
>       /* When using X, don't give the user a real choice,
>          because we haven't implemented the mechanisms to support it.  */
> #ifdef NO_SOCK_SIGIO
>       new_interrupt_input = 0;
> #else /* not NO_SOCK_SIGIO */
>       new_interrupt_input = 1;
> #endif /* NO_SOCK_SIGIO */
>     }
>   else
> #endif /* HAVE_X_WINDOWS */
>     new_interrupt_input = !NILP (interrupt);
> #else /* not SIGIO */
>   new_interrupt_input = 0;
> #endif /* not SIGIO */
>
>   if (new_interrupt_input != interrupt_input)
>     {
> #ifdef POLL_FOR_INPUT
>       stop_polling ();
> #endif
> #ifndef DOS_NT
>       /* this causes startup screen to be restored and messes with the
> mouse */
>       reset_all_sys_modes ();
> #endif
>       interrupt_input = new_interrupt_input;
> #ifndef DOS_NT
>       init_all_sys_modes ();
> #endif
>
> #ifdef POLL_FOR_INPUT
>       poll_suppress_count = 1;
>       start_polling ();
> #endif
>     }
>   return Qnil;
> }
>
>
new_interrupt_input value is determined by "new_interrupt_input = !NILP
(interrupt);" , and interrupt_input is overwrited  with new_interrupt_input.

So in order to break the infinite loop, new_interrupt_input value should be
0, because "input_polling_used ()" returns !interrupt_input, but
new_interrupt_input value is always 1.

In order to avoid this, we could add in s/gnu-kfreebsd.h this as a
workaround:

#define BROKEN_FIONREAD
>

because in keyboard.c:

/* Allow m- file to inhibit use of FIONREAD.  */
> #ifdef BROKEN_FIONREAD
> #undef FIONREAD
> #endif
>
> /* We are unable to use interrupts if FIONREAD is not available,
>    so flush SIGIO so we won't try.  */
> #if !defined (FIONREAD)
> #ifdef SIGIO
> #undef SIGIO
> #endif
> #endif
>

and because "new_interrupt_input = !NILP (interrupt);" only if SIGIO is
defined.

This is a very bad solution, I think, but I have no enough knowledge to find
any better way to solve this problem.
I have tested this, and it worked for me.

Cheers!

PD:Another possibility is to fix new_interrupt_input value always to 0, only
in GNU/kFreeBSD, but I think the main problem is in "new_interrupt_input =
!NILP (interrupt);", although, I couldn't find where is NILP definition
PD2: I'm a complete newbie in this, I'm sorry if I've wrote something silly
:)

Reply via email to