diff options
| author | Alan Third | 2017-07-01 12:58:49 +0100 |
|---|---|---|
| committer | Alan Third | 2017-07-01 12:58:49 +0100 |
| commit | 0ad5fd4b6cac1824e50e5e8c1a43878825e7d3de (patch) | |
| tree | 0a8247163987e1c146583554fdbe508a435f6705 /src | |
| parent | ff6d090ff73af57d6d489bc221d8f9eb6c0da633 (diff) | |
| download | emacs-0ad5fd4b6cac1824e50e5e8c1a43878825e7d3de.tar.gz emacs-0ad5fd4b6cac1824e50e5e8c1a43878825e7d3de.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/nsterm.h | 7 | ||||
| -rw-r--r-- | src/nsterm.m | 26 | ||||
| -rw-r--r-- | src/process.c | 13 | ||||
| -rw-r--r-- | src/systhread.c | 11 |
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, | |||
| 1233 | extern void x_set_z_group (struct frame *f, Lisp_Object new_value, | 1233 | extern void x_set_z_group (struct frame *f, Lisp_Object new_value, |
| 1234 | Lisp_Object old_value); | 1234 | Lisp_Object old_value); |
| 1235 | extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds, | 1235 | extern int ns_select (int nfds, fd_set *readfds, fd_set *writefds, |
| 1236 | fd_set *exceptfds, struct timespec const *timeout, | 1236 | fd_set *exceptfds, struct timespec *timeout, |
| 1237 | sigset_t const *sigmask); | 1237 | sigset_t *sigmask); |
| 1238 | #ifdef HAVE_PTHREAD | ||
| 1239 | extern void ns_run_loop_break (void); | ||
| 1240 | #endif | ||
| 1238 | extern unsigned long ns_get_rgb_color (struct frame *f, | 1241 | extern unsigned long ns_get_rgb_color (struct frame *f, |
| 1239 | float r, float g, float b, float a); | 1242 | float r, float g, float b, float a); |
| 1240 | 1243 | ||
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) | |||
| 4068 | app->nextappdefined = value; | 4068 | app->nextappdefined = value; |
| 4069 | [app performSelectorOnMainThread:@selector (sendFromMainThread:) | 4069 | [app performSelectorOnMainThread:@selector (sendFromMainThread:) |
| 4070 | withObject:nil | 4070 | withObject:nil |
| 4071 | waitUntilDone:YES]; | 4071 | waitUntilDone:NO]; |
| 4072 | return; | 4072 | return; |
| 4073 | } | 4073 | } |
| 4074 | 4074 | ||
| @@ -4293,8 +4293,8 @@ ns_read_socket (struct terminal *terminal, struct input_event *hold_quit) | |||
| 4293 | 4293 | ||
| 4294 | int | 4294 | int |
| 4295 | ns_select (int nfds, fd_set *readfds, fd_set *writefds, | 4295 | ns_select (int nfds, fd_set *readfds, fd_set *writefds, |
| 4296 | fd_set *exceptfds, struct timespec const *timeout, | 4296 | fd_set *exceptfds, struct timespec *timeout, |
| 4297 | sigset_t const *sigmask) | 4297 | sigset_t *sigmask) |
| 4298 | /* -------------------------------------------------------------------------- | 4298 | /* -------------------------------------------------------------------------- |
| 4299 | Replacement for select, checking for events | 4299 | Replacement for select, checking for events |
| 4300 | -------------------------------------------------------------------------- */ | 4300 | -------------------------------------------------------------------------- */ |
| @@ -4327,7 +4327,13 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, | |||
| 4327 | if (NSApp == nil | 4327 | if (NSApp == nil |
| 4328 | || ![NSThread isMainThread] | 4328 | || ![NSThread isMainThread] |
| 4329 | || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0)) | 4329 | || (timeout && timeout->tv_sec == 0 && timeout->tv_nsec == 0)) |
| 4330 | return pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask); | 4330 | return thread_select(pselect, nfds, readfds, writefds, |
| 4331 | exceptfds, timeout, sigmask); | ||
| 4332 | else | ||
| 4333 | { | ||
| 4334 | struct timespec t = {0, 0}; | ||
| 4335 | thread_select(pselect, 0, NULL, NULL, NULL, &t, sigmask); | ||
| 4336 | } | ||
| 4331 | 4337 | ||
| 4332 | [outerpool release]; | 4338 | [outerpool release]; |
| 4333 | outerpool = [[NSAutoreleasePool alloc] init]; | 4339 | outerpool = [[NSAutoreleasePool alloc] init]; |
| @@ -4430,6 +4436,18 @@ ns_select (int nfds, fd_set *readfds, fd_set *writefds, | |||
| 4430 | return result; | 4436 | return result; |
| 4431 | } | 4437 | } |
| 4432 | 4438 | ||
| 4439 | #ifdef HAVE_PTHREAD | ||
| 4440 | void | ||
| 4441 | ns_run_loop_break () | ||
| 4442 | /* Break out of the NS run loop in ns_select or ns_read_socket. */ | ||
| 4443 | { | ||
| 4444 | NSTRACE_WHEN (NSTRACE_GROUP_EVENTS, "ns_run_loop_break"); | ||
| 4445 | |||
| 4446 | /* If we don't have a GUI, don't send the event. */ | ||
| 4447 | if (NSApp != NULL) | ||
| 4448 | ns_send_appdefined(-1); | ||
| 4449 | } | ||
| 4450 | #endif | ||
| 4433 | 4451 | ||
| 4434 | 4452 | ||
| 4435 | /* ========================================================================== | 4453 | /* ========================================================================== |
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, | |||
| 5371 | nfds = xg_select (max_desc + 1, | 5371 | nfds = xg_select (max_desc + 1, |
| 5372 | &Available, (check_write ? &Writeok : 0), | 5372 | &Available, (check_write ? &Writeok : 0), |
| 5373 | NULL, &timeout, NULL); | 5373 | NULL, &timeout, NULL); |
| 5374 | #elif defined HAVE_NS | ||
| 5375 | /* And NS builds call thread_select in ns_select. */ | ||
| 5376 | nfds = ns_select (max_desc + 1, | ||
| 5377 | &Available, (check_write ? &Writeok : 0), | ||
| 5378 | NULL, &timeout, NULL); | ||
| 5374 | #else /* !HAVE_GLIB */ | 5379 | #else /* !HAVE_GLIB */ |
| 5375 | nfds = thread_select ( | 5380 | nfds = thread_select (pselect, max_desc + 1, |
| 5376 | # ifdef HAVE_NS | ||
| 5377 | ns_select | ||
| 5378 | # else | ||
| 5379 | pselect | ||
| 5380 | # endif | ||
| 5381 | , max_desc + 1, | ||
| 5382 | &Available, | 5381 | &Available, |
| 5383 | (check_write ? &Writeok : 0), | 5382 | (check_write ? &Writeok : 0), |
| 5384 | NULL, &timeout, NULL); | 5383 | 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/>. */ | |||
| 20 | #include <setjmp.h> | 20 | #include <setjmp.h> |
| 21 | #include "lisp.h" | 21 | #include "lisp.h" |
| 22 | 22 | ||
| 23 | #ifdef HAVE_NS | ||
| 24 | #include "nsterm.h" | ||
| 25 | #endif | ||
| 26 | |||
| 23 | #ifndef THREADS_ENABLED | 27 | #ifndef THREADS_ENABLED |
| 24 | 28 | ||
| 25 | void | 29 | void |
| @@ -130,6 +134,13 @@ void | |||
| 130 | sys_cond_broadcast (sys_cond_t *cond) | 134 | sys_cond_broadcast (sys_cond_t *cond) |
| 131 | { | 135 | { |
| 132 | pthread_cond_broadcast (cond); | 136 | pthread_cond_broadcast (cond); |
| 137 | #ifdef HAVE_NS | ||
| 138 | /* Send an app defined event to break out of the NS run loop. | ||
| 139 | It seems that if ns_select is running the NS run loop, this | ||
| 140 | broadcast has no effect until the loop is done, breaking a couple | ||
| 141 | of tests in thread-tests.el. */ | ||
| 142 | ns_run_loop_break (); | ||
| 143 | #endif | ||
| 133 | } | 144 | } |
| 134 | 145 | ||
| 135 | void | 146 | void |