Subject: Re: bug#24091: 24.5; High CPU usage at startup while hidden

From: [email-masked]
Date: Thu, 28 Jul 2016 21:45:55 -0400

tags 24091 confirmed
found 24091 25.1-rc1
quit

aiken <[email-masked]> writes:

> Noam: I think my settings are fairly standard, but another way to
> reproduce the effect of Emacs launching in a workspace that you're not
> currently in (which seems to be the main issue) is to add something like
> "assign [class="Emacs24"] 9" to your i3 config. (I've tried this and it
> does reproduce the high CPU usage.)

Thanks, with this I'm able to reproduce also with the latest emacs-25.
I sent SIGSTOP to get a backtrace and found it was in
x_make_frame_visible (src/xterm.c).

Stepping through it with gdb, I saw it's getting stuck in this loop:

    /* Process X events until a MapNotify event has been seen.  */
    while (!FRAME_VISIBLE_P (f))
      {
        /* Force processing of queued events.  */
        x_sync (f);

        /* If on another desktop, the deiconify/map may be ignored and the
           frame never becomes visible.  XMonad does this.
           Prevent an endless loop.  */
        if (FRAME_ICONIFIED_P (f) &&  ++tries > 100)
          break;

       /* This hack is still in use at least for Cygwin.  See
           http://lists.gnu.org/archive/html/emacs-devel/2013-12/msg00351.html.

           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.  */
            int old_poll_suppress_count = poll_suppress_count;
            poll_suppress_count = 1;
            poll_for_input_1 ();
            poll_suppress_count = old_poll_suppress_count;
          }

        if (XPending (FRAME_X_DISPLAY (f)))
          {
            XEvent xev;
            XNextEvent (FRAME_X_DISPLAY (f), &xev);
            x_dispatch_event (&xev, FRAME_X_DISPLAY (f));
          }
      }

I guess we would like Emacs to hit this case:

        /* If on another desktop, the deiconify/map may be ignored and the
           frame never becomes visible.  XMonad does this.
           Prevent an endless loop.  */
        if (FRAME_ICONIFIED_P (f) &&  ++tries > 100)
          break;

But it seems that FRAME_ICONIFIED_P is returning false, because I see
that tries is never incremented.