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

From: Gerd Möllmann <[email-masked]>
Date: Thu, 02 Jan 2025 15:03:54 +0100

Alan Third <[email-masked]> writes:

> 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.

OK, let's see if Po Lu remembers.

>> 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.

What I meant was the the NSApplication::run in ns_select_1 in Stefan's
case seems to call something complaining about being called in the wrong
thread. I guess it would also complain if there were an event in the
queue. I don't know. This whole code gets on my nerves :-).