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

From: Alan Third <[email-masked]>
Date: Mon, 26 Dec 2016 13:09:17 +0000

On Sun, Dec 25, 2016 at 05:52:37PM +0200, Eli Zaretskii wrote:
> > Date: Sat, 24 Dec 2016 19:51:13 +0200
> > From: Eli Zaretskii <[email-masked]>
> > Cc: [email-masked]
> > 
> > I see that ns_select calls block/unblock_input, which makes it unsafe
> > when more than one thread is running.  It's quite possible that this
> > is the reason.
> > 
> > I hope some NS expert could take a look at this and fix this.
> 
> One idea is to write an implementation of block_input and
> unblock_input that uses atomic increment and decrement functions, then
> use those only in ns_select.
> 
> Could someone with access to NS please try that?

I’ve just tried the below patch and it doesn’t make any difference: it
still hangs immediately.

Back in October Ken Raeburn listed some things that need done in
ns_select which are probably relevant:

https://lists.gnu.org/archive/html/emacs-devel/2016-10/msg00525.html

2 files changed, 23 insertions(+)
src/blockinput.h |  8 ++++++++
src/keyboard.c   | 15 +++++++++++++++

modified   src/blockinput.h
@@ -49,10 +49,18 @@ extern volatile int interrupt_input_blocked;
 
 /* Begin critical section. */
 
+#ifdef NS_IMPL_COCOA
+#include <libkern/OSAtomic.h>
+#endif
+
 INLINE void
 block_input (void)
 {
+#ifdef NS_IMPL_COCOA
+  OSAtomicIncrement32(&interrupt_input_blocked);
+#else
   interrupt_input_blocked++;
+#endif
 }
 
 extern void unblock_input (void);
modified   src/keyboard.c
@@ -54,6 +54,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <sys/ioctl.h>
 #endif /* not MSDOS */
 
+#ifdef NS_IMPL_COCOA
+#include <libkern/OSAtomic.h>
+#endif
+
 #if defined USABLE_FIONREAD && defined USG5_4
 # include <sys/filio.h>
 #endif
@@ -7183,7 +7187,18 @@ unblock_input_to (int level)
 void
 unblock_input (void)
 {
+#ifdef NS_IMPL_COCOA
+  OSAtomicDecrement32(&interrupt_input_blocked);
+  if (interrupt_input_blocked == 0)
+    {
+      if (pending_signals && !fatal_error_in_progress)
+	process_pending_signals ();
+    }
+  else if (interrupt_input_blocked < 0)
+    emacs_abort ();
+#else  
   unblock_input_to (interrupt_input_blocked - 1);
+#endif
 }
 
 /* Undo any number of BLOCK_INPUT calls,

-- 
Alan Third