GNU bug report logs - #70032
30.0.50; thread-yield inconsistency with macOS GUI and other platforms

Previous Next

Package: emacs;

Reported by: Daniel Pettersson <daniel <at> dpettersson.net>

Date: Wed, 27 Mar 2024 15:45:02 UTC

Severity: normal

Found in version 30.0.50

Full log


Message #11 received at 70032 <at> debbugs.gnu.org (full text, mbox):

From: Gerd Möllmann <gerd.moellmann <at> gmail.com>
To: Daniel Pettersson <daniel <at> dpettersson.net>
Cc: eliz <at> gnu.org, 70032 <at> debbugs.gnu.org
Subject: Re: 30.0.50; thread-yield inconsistency with macOS GUI and other
 platforms
Date: Wed, 30 Oct 2024 05:50:48 +0100
Daniel Pettersson <daniel <at> dpettersson.net> writes:

> Now that I am already being a nuisance, I might as well try to resurrect
> this bug as well.  I have tried to create a patch for this issue, but
> failed.  I do not understand the internals of emacs threads well enough,
> I am happy to try to give it a go but I would require some pointers to
> get me started.

In bug#72496 I wrote something that I think might be helpful to
underwtand how this works in NS. I nowadays build Emacs --without-ns.

  In GNU Emacs 31.0.50 (build 1, aarch64-apple-darwin23.6.0, NS
   appkit-2487.70 Version 14.6 (Build 23G80)) of 2024-08-05 built on
   pro2.fritz.box
  Repository revision: c7d9cd722e5a7042a52c92f8497f903bfe9870b8

  This is one of the problems on macOS that I'm experiencing quite
  often. I have no idea what is causing this, and I haven't found a way
  to make it reproducible. I guess I should file a bug report anyway.

  Let me first try to describe briefly how NS GUI event handling works
  in Emacs.

  The whole story starts with get_input_pending which calls gobble_input
  which calls a terminal's read_socket_hook, which is ns_read_socket in
  macOS. ns_read_socket calls [NSApplication run] to process macOS GUI
  events.

  The problem starts with [NSApplication run] being an endless loop that
  gets the next event, and dispatches it by calling the application's
  sendEvent method. The only way to make the run loop terminate is by
  calling [NSApplication stop]. This sets a flag that [NSApplicatoin
  run] is supposed to check and then return, so that we eventually
  return to ns_read_socket.

  We call [NSApplicaton stop] in our [EmacsApp sendEvent] method. To get
  there, we post special application-defined events to the application
  which [NSApplication run] processes and dispatches via sendEvent which
  calls stop and makes [NSApplication run] return to its caller. Note
  that stop only sets a flag, so we need to process another event to
  make run terminate. That's at least my understanding.

  We are posting these events all over the place, not only before
  ns_read_socket calls [NSApplication run]. And, to complicate matters,
  whether or not ns_send_appdefined actually posts an event depends on a
  global boolean variable. IOW, it's impenetrable.

  (I'm also leaving out the generation of input_events for Emacs here,
  which is another can of worms.)

  Problem is that this not always works. More specifically, this code in
  ns_read_socket_1

            /* Run and wait for events.  We must always send one NX_APPDEFINED event
               to ourself, otherwise [NXApp run] will never exit.  */
            send_appdefined = YES;
            ns_send_appdefined (-1);

            [NSApp run];

  gets stuck in the GUI event loop, and the last line never returns. The
  effect being that Emacs freezes without a beach ball of death. It
  processes Cocoa events but Emacs never sees any input_events.






This bug report was last modified 227 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.