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

From: Alan Third <[email-masked]>
Date: Wed, 28 Dec 2016 19:36:33 +0000

On Tue, Dec 27, 2016 at 01:13:11PM +0200, Eli Zaretskii wrote:
> > Date: Tue, 27 Dec 2016 10:44:24 +0000
> > From: Alan Third <[email-masked]>
> > Cc: [email-masked], [email-masked]
> 
> > > > >     [NSApp run];
> > > > > 
> > > > > Can this part and its surrounding code be made thread-safe?
> > > > 
> > > > I think this particular method call has to be done *only* from the
> > > > main thread. I imagine that could be a problem.
> > > 
> > > It could be a problem, yes.  But what does this do, exactly, and why
> > > does it need to be called as part of ns_select?
> > 
> > It runs an event loop that picks up all GUI events and then dispatches
> > them. It’s part of NextStep. It’s unclear to me why it’s run in
> > ns_select, but presumably it’s because it needs to be run somewhere
> > and whoever wrote it thought that was a good place.
> > 
> > If we need to, I expect we could move it to its own thread. That seems
> > to be a known pattern in the GNUStep/Cocoa world.
> 
> That's probably the only reasonable way.  But why does it use
> record_unwind_protect and unbind_to in the first place?  What happens
> if the user presses C-g while the event loop runs?

It was added in change 08f27aa39c498d34418c7420b33bf2db913827c3 which
relates to bug 18345. Previously it was simply apploopnr--, but
sometimes users would find themselves in a situation where that line
was never run (hitting C‐g while the event loop runs?) so the next
time ns_select (or ns_read_socket) ran it aborted. I take it unbind_to
fixes that particular problem.

Is there a safer way of ensuring that apploopnr is decremented?

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

The following is for my own future reference, if nothing else.

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

If either the pselect thread, or the timer run out before any input is
detected, they send a user defined event to the NSApp event loop so it
ends.

Similarly if the pselect thread detects input it sends an event to the
NSApp loop, which then ends.

If there’s NS input, it’s processed by the NSApp loop, which then
ends.

Whatever happens, the NSApp loop eventually returns control back to
ns_select, which works out what happened by examining the last NS
event and returns the relevant value.

I have my doubts this is thread safe. The communication between
ns_select and fd_handler is done by setting static variables and then
running:

    c = 'g';
    emacs_write_sig (selfds[1], &c, 1);

I don’t really know what that does. Sends something on an fd?

Then it writes back to the same global variables for ns_select to pick
up.

Now I’ve written it down it seems a lot less complicated...
-- 
Alan Third