summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Third <alan@idiocy.org>2017-07-01 12:58:49 +0100
committerAlan Third <alan@idiocy.org>2017-07-01 12:58:49 +0100
commit0ad5fd4b6cac1824e50e5e8c1a43878825e7d3de (patch)
tree0a8247163987e1c146583554fdbe508a435f6705
parentff6d090ff73af57d6d489bc221d8f9eb6c0da633 (diff)
downloademacs-0ad5fd4b6cac1824e50e5e8c1a43878825e7d3de.tar.gz
Fix threads on NS (bug#25265)
src/nsterm.h (ns_select): Compiler doesn't like sigmask being const. (ns_run_loop_break) [HAVE_PTHREAD]: New function. src/nsterm.m (ns_select): Call thread_select from within ns_select. (ns_run_loop_break) [HAVE_PTHREAD]: New function. (ns_send_appdefined): Don't wait for main thread when sending app defined event. src/process.c (wait_reading_process_output): Call thread_select from within ns_select. src/systhread.c (sys_cond_broadcast) [HAVE_NS]: Break ns_select out of its event loop using ns_run_loop_break.
-rw-r--r--src/nsterm.h7
-rw-r--r--src/nsterm.m26
-rw-r--r--src/process.c13
-rw-r--r--src/systhread.c11
4 files changed, 44 insertions, 13 deletions
diff --git a/src/nsterm.h b/src/nsterm.h
index 84f7f0ab574..0f1b36db7b2 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -1233,8 +1233,11 @@ extern void x_set_no_accept_focus (struct frame *f, Lisp_Object new_value,
extern void x_set_z_group (struct frame *f, Lisp_Object new_value,
Lisp_Object old_value);
extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timespec const *timeout,
- sigset_t const *sigmask);
+ fd_set *exceptfds, struct timespec *timeout,
+ sigset_t *sigmask);
+#ifdef HAVE_PTHREAD
+extern void ns_run_loop_break (void);
+#endif
extern unsigned long ns_get_rgb_color (struct frame *f,
float r, float g, float b, float a);
diff --git a/src/nsterm.m b/src/nsterm.m
index e05dbf45fbc..bf83550b3d7 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -4068,7 +4068,7 @@ ns_send_appdefined (int value)
app->nextappdefined = value;
[app performSelectorOnMainThread:@selector (sendFromMainThread:)
withObject:nil
- waitUntilDone:YES];
+ waitUntilDone:NO];
return;
}
@@ -4293,8 +4293,8 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit)
int
ns_select (int nfds, fd_set *readfds, fd_set *writefds,
- fd_set *exceptfds, struct timespec const *timeout,
- sigset_t const *sigmask)
+ fd_set *exceptfds, struct timespec *timeout,
+ sigset_t *sigmask)
/* --------------------------------------------------------------------------
Replacement for select, checking for events
-------------------------------------------------------------------------- */
@@ -4327,7 +4327,13 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
if (NSApp == nil
|| ![NSThread isMainThread]
|| (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0))
- return pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask);
+ 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);
+ }
[outerpool release];
outerpool = [[NSAutoreleasePool alloc] init];
@@ -4430,6 +4436,18 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds,
return result;
}
+#ifdef HAVE_PTHREAD
+void
+ns_run_loop_break ()
+/* Break out of the NS run loop in ns_select or ns_read_socket. */
+{
+ NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_run_loop_break");
+
+ /* If we don't have a GUI, don't send the event. */
+ if (NSApp != NULL)
+ ns_send_appdefined(-1);
+}
+#endif
/* ==========================================================================
diff --git a/src/process.c b/src/process.c
index 2a1c2eecde3..abd017bb907 100644
--- a/src/process.c
+++ b/src/process.c
@@ -5371,14 +5371,13 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
nfds = xg_select (max_desc + 1,
&Available, (check_write ? &Writeok : 0),
NULL, &timeout, NULL);
+#elif defined HAVE_NS
+ /* And NS builds call thread_select in ns_select. */
+ nfds = ns_select (max_desc + 1,
+ &Available, (check_write ? &Writeok : 0),
+ NULL, &timeout, NULL);
#else /* !HAVE_GLIB */
- nfds = thread_select (
-# ifdef HAVE_NS
- ns_select
-# else
- pselect
-# endif
- , max_desc + 1,
+ nfds = thread_select (pselect, max_desc + 1,
&Available,
(check_write ? &Writeok : 0),
NULL, &timeout, NULL);
diff --git a/src/systhread.c b/src/systhread.c
index a84060c18f0..aee12a9b482 100644
--- a/src/systhread.c
+++ b/src/systhread.c
@@ -20,6 +20,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include <setjmp.h>
#include "lisp.h"
+#ifdef HAVE_NS
+#include "nsterm.h"
+#endif
+
#ifndef THREADS_ENABLED
void
@@ -130,6 +134,13 @@ void
sys_cond_broadcast (sys_cond_t *cond)
{
pthread_cond_broadcast (cond);
+#ifdef HAVE_NS
+ /* Send an app defined event to break out of the NS run loop.
+ It seems that if ns_select is running the NS run loop, this
+ broadcast has no effect until the loop is done, breaking a couple
+ of tests in thread-tests.el. */
+ ns_run_loop_break ();
+#endif
}
void