Subject: Re: bug#75275: 30.0.92; `make-thread` bug on macOS 15.2

From: Alan Third <[email-masked]>
Date: Thu, 2 Jan 2025 13:53:58 +0000

On Thu, Jan 02, 2025 at 02:05:44PM +0100, Gerd Möllmann wrote:
> Alan Third <[email-masked]> writes:
> 
> > No, none of that needs to run when we're not in the main thread.
> > fd_handler run pselect in a separate thread because the NS main thread
> > has to run the ns main thread run loop to handle incoming IO from the
> > window system.
> >
> > The NS run loop can emulate parts of pselect, but not the whole thing,
> > so we are required to run both the NS runloop and pselect
> > simultaneously, hence fd_handler. If we don't need to run the runloop,
> > i.e. we're in a non-main thread, then we can just run pselect directly
> > and ignore fd_handler.
> 
> So IIUC, you'd write this in ns_select_1
> 
>   if (![NSThread isMainThread]
>       || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0))
>     thread_select (pselect, nfds, readfds, writefds,
> 		   exceptfds, timeout, sigmask);
> 
> as return "return thread_select(...)"?

I don't know. The code that in Emacs 29 looked like:

  if (NSApp == nil
      || ![NSThread isMainThread]
      || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0))
    return thread_select (pselect, nfds, readfds, writefds,
			  exceptfds, timeout, sigmask);
  else
    {
      struct timespec t = {0, 0};
      thread_select (pselect, 0, NULL, NULL, NULL, &t, sigmask);
    }

Now looks like:

  /* emacs -nw doesn't have an NSApp, so we're done.  */
  if (NSApp == nil)
    return thread_select (pselect, nfds, readfds, writefds, exceptfds,
			  timeout, sigmask);

  if (![NSThread isMainThread]
      || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0))
    thread_select (pselect, nfds, readfds, writefds,
		   exceptfds, timeout, sigmask);
  else
    {
      struct timespec t = {0, 0};
      thread_select (pselect, 0, NULL, NULL, NULL, &t, sigmask);
    }

and I don't know why. The change (9370a4763aa) has no bug report
listed and I'm pretty sure I wasn't asked about it, so I have to
assume Po Lu had some reason for the main thread and timeout checks to
result in falling-through to the rest of the function.

> One strange thing about threads having their own event queue is that the
> message Stefan sees comes from the NSApplicaiton::run in ns_select_1. Be
> that at it may.

Indeed, ns_select_1 is being run in a sub-thread and it therefore runs
a thread-specific run queue which has no events in it. It requires an
event to be sent to it so it will stop but none ever is because we
only ever send events to the main thread's event queue.

-- 
Alan Third