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.
This commit is contained in:
Alan Third 2017-07-01 12:58:49 +01:00
parent ff6d090ff7
commit 0ad5fd4b6c
4 changed files with 44 additions and 13 deletions

View file

@ -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);

View file

@ -4068,7 +4068,7 @@ overwriting cursor (usually when cursor on a tab) */
app->nextappdefined = value;
[app performSelectorOnMainThread:@selector (sendFromMainThread:)
withObject:nil
waitUntilDone:YES];
waitUntilDone:NO];
return;
}
@ -4293,8 +4293,8 @@ in certain situations (rapid incoming events).
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 @@ in certain situations (rapid incoming events).
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 @@ in certain situations (rapid incoming events).
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
/* ==========================================================================

View file

@ -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);

View file

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