Subject: Re: bug#25265: make-thread crashes in OS X 10.6

From: Alan Third <[email-masked]>
Date: Fri, 30 Dec 2016 18:45:32 +0000

On Thu, Dec 29, 2016 at 07:12:54PM +0200, Eli Zaretskii wrote:
> > Date: Wed, 28 Dec 2016 19:36:33 +0000
> > From: Alan Third <[email-masked]>
> > Cc: [email-masked], [email-masked]
> > 
> > I’m slowly beginning to understand what’s going on in ns_select. It
> > seems the idea is that it should detect both input on file descriptors
> > (using pselect in the background), and NS events coming from [NSApp
> > run].
> 
> What do "NS events" include?  Do they include, for example, keyboard
> input?

As far as I can tell it’s mouse and keyboard input, as well as
messages from the ‘window manager’, telling it to close the frame,
etc.

> > There is another thread that runs in a loop (fd_handler), and when
> > it’s signalled from ns_select, it runs pselect. At the same time
> > ns_select sets up a timer, then it calls [NSApp run].
> 
> (I think ns_select only sets up a timer when there are no descriptors
> to watch, to avoid waking up the fd_handler thread in that case.)
> 
> So this means there are 2 jobs to be done here: the pselect call and
> the [NSApp run] call.

Correct on both counts.

> > If there’s NS input, it’s processed by the NSApp loop
> 
> Processed how?  Shouldn't Emacs be involved in this processing?  IOW,
> these events should be read by Emacs, via the read_socket_hook.

Ah! Is this the missing piece of the puzzle? When the [NSApp run] loop
receives an event, say keyboard input, it creates an emacs_event and
then raises SIGIO (via hold_event). SIGIO causes ns_read_socket to be
run, which ALSO tries to run [NSApp run].

Am I right in thinking that raising SIGIO will cause ns_read_socket to
be potentially run immediately? Asynchronously?

I’ve just commented out the section of ns_read_socket that calls
[NSApp run] and I can’t see any difference in behaviour. I suspect
that someone’s doubled up on it when they didn’t need to.

> One possible solution might be to let only one thread, say the main
> thread, to call [NSApp run].  The other threads, when they get into
> ns_select, will behave as if Emacs runs in non-GUI mode, and will only
> call pselect.  Not sure what this will mean from the POV of all
> threads being equal (since the delicate dance between ns_select and
> ns_read_socket is still unclear to me), but at least it might avoid
> crashes and hangs.  Can you try something like that?

Yes, I will. Am I right in thinking that if we remove all the NSApp
junk from ns_select it will literally just be calling pselect with
the same arguments?

So, my plan of action:

Run [NSApp run] in it’s own thread with no flow control (unless it’s
important that emacs events are only created at specific times?)

Replace ns_select with pselect.

Thanks for helping with this, I don’t think I’d be able to work it out
on my own.
-- 
Alan Third