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:
parent
ff6d090ff7
commit
0ad5fd4b6c
4 changed files with 44 additions and 13 deletions
|
@ -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);
|
||||
|
||||
|
|
26
src/nsterm.m
26
src/nsterm.m
|
@ -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
|
||||
|
||||
|
||||
/* ==========================================================================
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue