aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorEli Zaretskii2016-12-10 18:54:43 +0200
committerEli Zaretskii2016-12-10 18:54:43 +0200
commit2412a1fc05fe9f89b171d0781c2d530923f48adc (patch)
treed42a5d2608e65a10b1cc23c6b4609d54bef25d49 /src/process.c
parentfc0fd24c105bde4c001ebebe4b8b7e1f96cd2871 (diff)
parent828b4560cd4a0d8cb9b7a7a3e20ff0c53ba86cfa (diff)
downloademacs-2412a1fc05fe9f89b171d0781c2d530923f48adc.tar.gz
emacs-2412a1fc05fe9f89b171d0781c2d530923f48adc.zip
Support concurrency in Emacs Lisp
Merge branch 'test-concurrency' * src/thread.c: * src/thread.h: * src/systhread.c: * src/systhread.h: New files. * src/xgselect.c (xg_select): Avoid using SAFE_NALLOCA and use xnmalloc unconditionally. * src/window.c (struct save_window_data): Rename current_buffer to f_current_buffer. * src/w32proc.c (sys_select): Change the function signature to closer fit 'pselect' on Posix hosts. * src/search.c: * src/regex.h: Convert some globals to macros that reference thread-specific values. * src/process.c (pset_thread, add_non_keyboard_read_fd) (add_process_read_fd, add_non_blocking_write_fd) (recompute_input_desc, compute_input_wait_mask) (compute_non_process_wait_mask, compute_non_keyboard_wait_mask) (compute_write_mask, clear_waiting_thread_info) (update_processes_for_thread_death, Fset_process_thread) (Fprocess_thread): New functions. (enum fd_bits): New enumeration. (fd_callback_data): Add 'thread' and 'waiting_thread', rename 'condition' to 'flags'. (set_process_filter_masks, create_process, create_pty) (Fmake_serial_process, finish_after_tls_connection) (connect_network_socket, deactivate_process) (server_accept_connection, wait_reading_process_output) (Fcontinue_process, Fstop_process, keyboard_bit_set) (add_timer_wait_descriptor, add_keyboard_wait_descriptor) (delete_keyboard_wait_descriptor): Use the new functions instead of manipulating fd flags and masks directly. (syms_of_process): Defsubr the new primitives. * src/print.c (print_object): Print threads, mutexes, and conditional variables. * src/lisp.h (enum pvec_type): New values PVEC_THREAD, PVEC_MUTEX, and PVEC_CONDVAR. (XTHREAD, XMUTEX, XCONDVAR, THREADP, MUTEXP, CONDVARP) (CHECK_THREAD, CHECK_MUTEX, CHECK_CONDVAR): New inline functions. (XSETTHREAD, XSETMUTEX, XSETCONDVAR): New macros. (struct handler): Add back byte_stack. Rename lisp_eval_depth to f_lisp_eval_depth. * src/eval.c (specpdl_kind, specpdl_arg, do_specbind) (rebind_for_thread_switch, do_one_unbind) (unbind_for_thread_switch): New functions. (init_eval): 'handlerlist' is not malloc'ed. (specbind): Call do_specbind. (unbind_to): Call do_one_unbind. (mark_specpdl): Accept 2 arguments. (mark_specpdl): Mark the saved value in a let-binding. * src/emacs.c (main): Call init_threads_once, init_threads, and syms_of_threads. * src/data.c (Ftype_of): Support thread, mutex, and condvar objects. (Fthreadp, Fmutexp, Fcondition_variable_p): New functions. (syms_of_data): DEFSYM and defsubr new symbols and primitives. * src/bytecode.c (struct byte_stack, FETCH, CHECK_RANGE) (BYTE_CODE_QUIT): Add back. (exec_byte_code): Add back byte stack manipulation. * src/alloc.c (cleanup_vector): Handle threads, mutexes, and conditional variables. (mark_stack): Now extern; accept additional argument 'bottom'. (flush_stack_call_func): New function. (garbage_collect_1): Call mark_threads and unmark_threads. Don't mark handlers. * src/.gdbinit (xbytecode): Add back. * test/src/thread-tests.el: New tests. * test/src/data-tests.el (binding-test-manual) (binding-test-setq-default, binding-test-makunbound) (binding-test-defvar-bool, binding-test-defvar-int) (binding-test-set-constant-t, binding-test-set-constant-nil) (binding-test-set-constant-keyword) (binding-test-set-constant-nil): New tests. * doc/lispref/processes.texi (Processes and Threads): New subsection. * doc/lispref/threads.texi: New file * doc/lispref/elisp.texi (Top): Include it. * doc/lispref/objects.texi (Thread Type, Mutex Type) (Condition Variable Type): New subsections. (Type Predicates): Add thread-related predicates. * doc/lispref/objects.texi (Editing Types): * doc/lispref/elisp.texi (Top): Update higher-level menus. * etc/NEWS: Mention concurrency features.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c547
1 files changed, 343 insertions, 204 deletions
diff --git a/src/process.c b/src/process.c
index 8ab73bd9ae6..31c9d74a3f2 100644
--- a/src/process.c
+++ b/src/process.c
@@ -138,7 +138,7 @@ static struct rlimit nofile_limit;
138 138
139#ifdef WINDOWSNT 139#ifdef WINDOWSNT
140extern int sys_select (int, fd_set *, fd_set *, fd_set *, 140extern int sys_select (int, fd_set *, fd_set *, fd_set *,
141 struct timespec *, void *); 141 const struct timespec *, const sigset_t *);
142#endif 142#endif
143 143
144/* Work around GCC 4.3.0 bug with strict overflow checking; see 144/* Work around GCC 4.3.0 bug with strict overflow checking; see
@@ -260,36 +260,11 @@ static int read_process_output (Lisp_Object, int);
260static void create_pty (Lisp_Object); 260static void create_pty (Lisp_Object);
261static void exec_sentinel (Lisp_Object, Lisp_Object); 261static void exec_sentinel (Lisp_Object, Lisp_Object);
262 262
263/* Mask of bits indicating the descriptors that we wait for input on. */
264
265static fd_set input_wait_mask;
266
267/* Mask that excludes keyboard input descriptor(s). */
268
269static fd_set non_keyboard_wait_mask;
270
271/* Mask that excludes process input descriptor(s). */
272
273static fd_set non_process_wait_mask;
274
275/* Mask for selecting for write. */
276
277static fd_set write_mask;
278
279/* Mask of bits indicating the descriptors that we wait for connect to
280 complete on. Once they complete, they are removed from this mask
281 and added to the input_wait_mask and non_keyboard_wait_mask. */
282
283static fd_set connect_wait_mask;
284
285/* Number of bits set in connect_wait_mask. */ 263/* Number of bits set in connect_wait_mask. */
286static int num_pending_connects; 264static int num_pending_connects;
287 265
288/* The largest descriptor currently in use for a process object; -1 if none. */ 266/* The largest descriptor currently in use; -1 if none. */
289static int max_process_desc; 267static int max_desc;
290
291/* The largest descriptor currently in use for input; -1 if none. */
292static int max_input_desc;
293 268
294/* Set the external socket descriptor for Emacs to use when 269/* Set the external socket descriptor for Emacs to use when
295 `make-network-process' is called with a non-nil 270 `make-network-process' is called with a non-nil
@@ -384,6 +359,11 @@ pset_mark (struct Lisp_Process *p, Lisp_Object val)
384 p->mark = val; 359 p->mark = val;
385} 360}
386static void 361static void
362pset_thread (struct Lisp_Process *p, Lisp_Object val)
363{
364 p->thread = val;
365}
366static void
387pset_name (struct Lisp_Process *p, Lisp_Object val) 367pset_name (struct Lisp_Process *p, Lisp_Object val)
388{ 368{
389 p->name = val; 369 p->name = val;
@@ -426,13 +406,34 @@ make_lisp_proc (struct Lisp_Process *p)
426 return make_lisp_ptr (p, Lisp_Vectorlike); 406 return make_lisp_ptr (p, Lisp_Vectorlike);
427} 407}
428 408
409enum fd_bits
410{
411 /* Read from file descriptor. */
412 FOR_READ = 1,
413 /* Write to file descriptor. */
414 FOR_WRITE = 2,
415 /* This descriptor refers to a keyboard. Only valid if FOR_READ is
416 set. */
417 KEYBOARD_FD = 4,
418 /* This descriptor refers to a process. */
419 PROCESS_FD = 8,
420 /* A non-blocking connect. Only valid if FOR_WRITE is set. */
421 NON_BLOCKING_CONNECT_FD = 16
422};
423
429static struct fd_callback_data 424static struct fd_callback_data
430{ 425{
431 fd_callback func; 426 fd_callback func;
432 void *data; 427 void *data;
433#define FOR_READ 1 428 /* Flags from enum fd_bits. */
434#define FOR_WRITE 2 429 int flags;
435 int condition; /* Mask of the defines above. */ 430 /* If this fd is locked to a certain thread, this points to it.
431 Otherwise, this is NULL. If an fd is locked to a thread, then
432 only that thread is permitted to wait on it. */
433 struct thread_state *thread;
434 /* If this fd is currently being selected on by a thread, this
435 points to the thread. Otherwise it is NULL. */
436 struct thread_state *waiting_thread;
436} fd_callback_info[FD_SETSIZE]; 437} fd_callback_info[FD_SETSIZE];
437 438
438 439
@@ -446,7 +447,25 @@ add_read_fd (int fd, fd_callback func, void *data)
446 447
447 fd_callback_info[fd].func = func; 448 fd_callback_info[fd].func = func;
448 fd_callback_info[fd].data = data; 449 fd_callback_info[fd].data = data;
449 fd_callback_info[fd].condition |= FOR_READ; 450}
451
452static void
453add_non_keyboard_read_fd (int fd)
454{
455 eassert (fd >= 0 && fd < FD_SETSIZE);
456 eassert (fd_callback_info[fd].func == NULL);
457
458 fd_callback_info[fd].flags &= ~KEYBOARD_FD;
459 fd_callback_info[fd].flags |= FOR_READ;
460 if (fd > max_desc)
461 max_desc = fd;
462}
463
464static void
465add_process_read_fd (int fd)
466{
467 add_non_keyboard_read_fd (fd);
468 fd_callback_info[fd].flags |= PROCESS_FD;
450} 469}
451 470
452/* Stop monitoring file descriptor FD for when read is possible. */ 471/* Stop monitoring file descriptor FD for when read is possible. */
@@ -456,8 +475,7 @@ delete_read_fd (int fd)
456{ 475{
457 delete_keyboard_wait_descriptor (fd); 476 delete_keyboard_wait_descriptor (fd);
458 477
459 fd_callback_info[fd].condition &= ~FOR_READ; 478 if (fd_callback_info[fd].flags == 0)
460 if (fd_callback_info[fd].condition == 0)
461 { 479 {
462 fd_callback_info[fd].func = 0; 480 fd_callback_info[fd].func = 0;
463 fd_callback_info[fd].data = 0; 481 fd_callback_info[fd].data = 0;
@@ -470,28 +488,39 @@ delete_read_fd (int fd)
470void 488void
471add_write_fd (int fd, fd_callback func, void *data) 489add_write_fd (int fd, fd_callback func, void *data)
472{ 490{
473 FD_SET (fd, &write_mask); 491 eassert (fd >= 0 && fd < FD_SETSIZE);
474 if (fd > max_input_desc)
475 max_input_desc = fd;
476 492
477 fd_callback_info[fd].func = func; 493 fd_callback_info[fd].func = func;
478 fd_callback_info[fd].data = data; 494 fd_callback_info[fd].data = data;
479 fd_callback_info[fd].condition |= FOR_WRITE; 495 fd_callback_info[fd].flags |= FOR_WRITE;
496 if (fd > max_desc)
497 max_desc = fd;
480} 498}
481 499
482/* FD is no longer an input descriptor; update max_input_desc accordingly. */ 500static void
501add_non_blocking_write_fd (int fd)
502{
503 eassert (fd >= 0 && fd < FD_SETSIZE);
504 eassert (fd_callback_info[fd].func == NULL);
505
506 fd_callback_info[fd].flags |= FOR_WRITE | NON_BLOCKING_CONNECT_FD;
507 if (fd > max_desc)
508 max_desc = fd;
509 ++num_pending_connects;
510}
483 511
484static void 512static void
485delete_input_desc (int fd) 513recompute_max_desc (void)
486{ 514{
487 if (fd == max_input_desc) 515 int fd;
488 {
489 do
490 fd--;
491 while (0 <= fd && ! (FD_ISSET (fd, &input_wait_mask)
492 || FD_ISSET (fd, &write_mask)));
493 516
494 max_input_desc = fd; 517 for (fd = max_desc; fd >= 0; --fd)
518 {
519 if (fd_callback_info[fd].flags != 0)
520 {
521 max_desc = fd;
522 break;
523 }
495 } 524 }
496} 525}
497 526
@@ -500,13 +529,121 @@ delete_input_desc (int fd)
500void 529void
501delete_write_fd (int fd) 530delete_write_fd (int fd)
502{ 531{
503 FD_CLR (fd, &write_mask); 532 if ((fd_callback_info[fd].flags & NON_BLOCKING_CONNECT_FD) != 0)
504 fd_callback_info[fd].condition &= ~FOR_WRITE; 533 {
505 if (fd_callback_info[fd].condition == 0) 534 if (--num_pending_connects < 0)
535 emacs_abort ();
536 }
537 fd_callback_info[fd].flags &= ~(FOR_WRITE | NON_BLOCKING_CONNECT_FD);
538 if (fd_callback_info[fd].flags == 0)
506 { 539 {
507 fd_callback_info[fd].func = 0; 540 fd_callback_info[fd].func = 0;
508 fd_callback_info[fd].data = 0; 541 fd_callback_info[fd].data = 0;
509 delete_input_desc (fd); 542
543 if (fd == max_desc)
544 recompute_max_desc ();
545 }
546}
547
548static void
549compute_input_wait_mask (fd_set *mask)
550{
551 int fd;
552
553 FD_ZERO (mask);
554 for (fd = 0; fd <= max_desc; ++fd)
555 {
556 if (fd_callback_info[fd].thread != NULL
557 && fd_callback_info[fd].thread != current_thread)
558 continue;
559 if (fd_callback_info[fd].waiting_thread != NULL
560 && fd_callback_info[fd].waiting_thread != current_thread)
561 continue;
562 if ((fd_callback_info[fd].flags & FOR_READ) != 0)
563 {
564 FD_SET (fd, mask);
565 fd_callback_info[fd].waiting_thread = current_thread;
566 }
567 }
568}
569
570static void
571compute_non_process_wait_mask (fd_set *mask)
572{
573 int fd;
574
575 FD_ZERO (mask);
576 for (fd = 0; fd <= max_desc; ++fd)
577 {
578 if (fd_callback_info[fd].thread != NULL
579 && fd_callback_info[fd].thread != current_thread)
580 continue;
581 if (fd_callback_info[fd].waiting_thread != NULL
582 && fd_callback_info[fd].waiting_thread != current_thread)
583 continue;
584 if ((fd_callback_info[fd].flags & FOR_READ) != 0
585 && (fd_callback_info[fd].flags & PROCESS_FD) == 0)
586 {
587 FD_SET (fd, mask);
588 fd_callback_info[fd].waiting_thread = current_thread;
589 }
590 }
591}
592
593static void
594compute_non_keyboard_wait_mask (fd_set *mask)
595{
596 int fd;
597
598 FD_ZERO (mask);
599 for (fd = 0; fd <= max_desc; ++fd)
600 {
601 if (fd_callback_info[fd].thread != NULL
602 && fd_callback_info[fd].thread != current_thread)
603 continue;
604 if (fd_callback_info[fd].waiting_thread != NULL
605 && fd_callback_info[fd].waiting_thread != current_thread)
606 continue;
607 if ((fd_callback_info[fd].flags & FOR_READ) != 0
608 && (fd_callback_info[fd].flags & KEYBOARD_FD) == 0)
609 {
610 FD_SET (fd, mask);
611 fd_callback_info[fd].waiting_thread = current_thread;
612 }
613 }
614}
615
616static void
617compute_write_mask (fd_set *mask)
618{
619 int fd;
620
621 FD_ZERO (mask);
622 for (fd = 0; fd <= max_desc; ++fd)
623 {
624 if (fd_callback_info[fd].thread != NULL
625 && fd_callback_info[fd].thread != current_thread)
626 continue;
627 if (fd_callback_info[fd].waiting_thread != NULL
628 && fd_callback_info[fd].waiting_thread != current_thread)
629 continue;
630 if ((fd_callback_info[fd].flags & FOR_WRITE) != 0)
631 {
632 FD_SET (fd, mask);
633 fd_callback_info[fd].waiting_thread = current_thread;
634 }
635 }
636}
637
638static void
639clear_waiting_thread_info (void)
640{
641 int fd;
642
643 for (fd = 0; fd <= max_desc; ++fd)
644 {
645 if (fd_callback_info[fd].waiting_thread == current_thread)
646 fd_callback_info[fd].waiting_thread = NULL;
510 } 647 }
511} 648}
512 649
@@ -716,6 +853,7 @@ make_process (Lisp_Object name)
716 Lisp data to nil, so do it only for slots which should not be nil. */ 853 Lisp data to nil, so do it only for slots which should not be nil. */
717 pset_status (p, Qrun); 854 pset_status (p, Qrun);
718 pset_mark (p, Fmake_marker ()); 855 pset_mark (p, Fmake_marker ());
856 pset_thread (p, Fcurrent_thread ());
719 857
720 /* Initialize non-Lisp data. Note that allocate_process zeroes out all 858 /* Initialize non-Lisp data. Note that allocate_process zeroes out all
721 non-Lisp data, so do it only for slots which should not be zero. */ 859 non-Lisp data, so do it only for slots which should not be zero. */
@@ -764,6 +902,27 @@ remove_process (register Lisp_Object proc)
764 deactivate_process (proc); 902 deactivate_process (proc);
765} 903}
766 904
905void
906update_processes_for_thread_death (Lisp_Object dying_thread)
907{
908 Lisp_Object pair;
909
910 for (pair = Vprocess_alist; !NILP (pair); pair = XCDR (pair))
911 {
912 Lisp_Object process = XCDR (XCAR (pair));
913 if (EQ (XPROCESS (process)->thread, dying_thread))
914 {
915 struct Lisp_Process *proc = XPROCESS (process);
916
917 pset_thread (proc, Qnil);
918 if (proc->infd >= 0)
919 fd_callback_info[proc->infd].thread = NULL;
920 if (proc->outfd >= 0)
921 fd_callback_info[proc->outfd].thread = NULL;
922 }
923 }
924}
925
767#ifdef HAVE_GETADDRINFO_A 926#ifdef HAVE_GETADDRINFO_A
768static void 927static void
769free_dns_request (Lisp_Object proc) 928free_dns_request (Lisp_Object proc)
@@ -1066,17 +1225,11 @@ static void
1066set_process_filter_masks (struct Lisp_Process *p) 1225set_process_filter_masks (struct Lisp_Process *p)
1067{ 1226{
1068 if (EQ (p->filter, Qt) && !EQ (p->status, Qlisten)) 1227 if (EQ (p->filter, Qt) && !EQ (p->status, Qlisten))
1069 { 1228 delete_read_fd (p->infd);
1070 FD_CLR (p->infd, &input_wait_mask);
1071 FD_CLR (p->infd, &non_keyboard_wait_mask);
1072 }
1073 else if (EQ (p->filter, Qt) 1229 else if (EQ (p->filter, Qt)
1074 /* Network or serial process not stopped: */ 1230 /* Network or serial process not stopped: */
1075 && !EQ (p->command, Qt)) 1231 && !EQ (p->command, Qt))
1076 { 1232 add_process_read_fd (p->infd);
1077 FD_SET (p->infd, &input_wait_mask);
1078 FD_SET (p->infd, &non_keyboard_wait_mask);
1079 }
1080} 1233}
1081 1234
1082DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter, 1235DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter,
@@ -1163,6 +1316,44 @@ See `set-process-sentinel' for more info on sentinels. */)
1163 return XPROCESS (process)->sentinel; 1316 return XPROCESS (process)->sentinel;
1164} 1317}
1165 1318
1319DEFUN ("set-process-thread", Fset_process_thread, Sset_process_thread,
1320 2, 2, 0,
1321 doc: /* Set the locking thread of PROCESS to be THREAD.
1322If THREAD is nil, the process is unlocked. */)
1323 (Lisp_Object process, Lisp_Object thread)
1324{
1325 struct Lisp_Process *proc;
1326 struct thread_state *tstate;
1327
1328 CHECK_PROCESS (process);
1329 if (NILP (thread))
1330 tstate = NULL;
1331 else
1332 {
1333 CHECK_THREAD (thread);
1334 tstate = XTHREAD (thread);
1335 }
1336
1337 proc = XPROCESS (process);
1338 pset_thread (proc, thread);
1339 if (proc->infd >= 0)
1340 fd_callback_info[proc->infd].thread = tstate;
1341 if (proc->outfd >= 0)
1342 fd_callback_info[proc->outfd].thread = tstate;
1343
1344 return thread;
1345}
1346
1347DEFUN ("process-thread", Fprocess_thread, Sprocess_thread,
1348 1, 1, 0,
1349 doc: /* Ret the locking thread of PROCESS.
1350If PROCESS is unlocked, this function returns nil. */)
1351 (Lisp_Object process)
1352{
1353 CHECK_PROCESS (process);
1354 return XPROCESS (process)->thread;
1355}
1356
1166DEFUN ("set-process-window-size", Fset_process_window_size, 1357DEFUN ("set-process-window-size", Fset_process_window_size,
1167 Sset_process_window_size, 3, 3, 0, 1358 Sset_process_window_size, 3, 3, 0,
1168 doc: /* Tell PROCESS that it has logical window size WIDTH by HEIGHT. 1359 doc: /* Tell PROCESS that it has logical window size WIDTH by HEIGHT.
@@ -1840,13 +2031,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1840 pset_status (p, Qrun); 2031 pset_status (p, Qrun);
1841 2032
1842 if (!EQ (p->command, Qt)) 2033 if (!EQ (p->command, Qt))
1843 { 2034 add_process_read_fd (inchannel);
1844 FD_SET (inchannel, &input_wait_mask);
1845 FD_SET (inchannel, &non_keyboard_wait_mask);
1846 }
1847
1848 if (inchannel > max_process_desc)
1849 max_process_desc = inchannel;
1850 2035
1851 /* This may signal an error. */ 2036 /* This may signal an error. */
1852 setup_process_coding_systems (process); 2037 setup_process_coding_systems (process);
@@ -2079,10 +2264,7 @@ create_pty (Lisp_Object process)
2079 pset_status (p, Qrun); 2264 pset_status (p, Qrun);
2080 setup_process_coding_systems (process); 2265 setup_process_coding_systems (process);
2081 2266
2082 FD_SET (pty_fd, &input_wait_mask); 2267 add_process_read_fd (pty_fd);
2083 FD_SET (pty_fd, &non_keyboard_wait_mask);
2084 if (pty_fd > max_process_desc)
2085 max_process_desc = pty_fd;
2086 2268
2087 pset_tty_name (p, build_string (pty_name)); 2269 pset_tty_name (p, build_string (pty_name));
2088 } 2270 }
@@ -2166,8 +2348,8 @@ usage: (make-pipe-process &rest ARGS) */)
2166 p->infd = inchannel; 2348 p->infd = inchannel;
2167 p->outfd = outchannel; 2349 p->outfd = outchannel;
2168 2350
2169 if (inchannel > max_process_desc) 2351 if (inchannel > max_desc)
2170 max_process_desc = inchannel; 2352 max_desc = inchannel;
2171 2353
2172 buffer = Fplist_get (contact, QCbuffer); 2354 buffer = Fplist_get (contact, QCbuffer);
2173 if (NILP (buffer)) 2355 if (NILP (buffer))
@@ -2188,10 +2370,7 @@ usage: (make-pipe-process &rest ARGS) */)
2188 eassert (! p->pty_flag); 2370 eassert (! p->pty_flag);
2189 2371
2190 if (!EQ (p->command, Qt)) 2372 if (!EQ (p->command, Qt))
2191 { 2373 add_process_read_fd (inchannel);
2192 FD_SET (inchannel, &input_wait_mask);
2193 FD_SET (inchannel, &non_keyboard_wait_mask);
2194 }
2195 p->adaptive_read_buffering 2374 p->adaptive_read_buffering
2196 = (NILP (Vprocess_adaptive_read_buffering) ? 0 2375 = (NILP (Vprocess_adaptive_read_buffering) ? 0
2197 : EQ (Vprocess_adaptive_read_buffering, Qt) ? 1 : 2); 2376 : EQ (Vprocess_adaptive_read_buffering, Qt) ? 1 : 2);
@@ -2904,8 +3083,8 @@ usage: (make-serial-process &rest ARGS) */)
2904 p->open_fd[SUBPROCESS_STDIN] = fd; 3083 p->open_fd[SUBPROCESS_STDIN] = fd;
2905 p->infd = fd; 3084 p->infd = fd;
2906 p->outfd = fd; 3085 p->outfd = fd;
2907 if (fd > max_process_desc) 3086 if (fd > max_desc)
2908 max_process_desc = fd; 3087 max_desc = fd;
2909 chan_process[fd] = proc; 3088 chan_process[fd] = proc;
2910 3089
2911 buffer = Fplist_get (contact, QCbuffer); 3090 buffer = Fplist_get (contact, QCbuffer);
@@ -2927,10 +3106,7 @@ usage: (make-serial-process &rest ARGS) */)
2927 eassert (! p->pty_flag); 3106 eassert (! p->pty_flag);
2928 3107
2929 if (!EQ (p->command, Qt)) 3108 if (!EQ (p->command, Qt))
2930 { 3109 add_process_read_fd (fd);
2931 FD_SET (fd, &input_wait_mask);
2932 FD_SET (fd, &non_keyboard_wait_mask);
2933 }
2934 3110
2935 if (BUFFERP (buffer)) 3111 if (BUFFERP (buffer))
2936 { 3112 {
@@ -3102,7 +3278,7 @@ finish_after_tls_connection (Lisp_Object proc)
3102 pset_status (p, Qfailed); 3278 pset_status (p, Qfailed);
3103 deactivate_process (proc); 3279 deactivate_process (proc);
3104 } 3280 }
3105 else if (! FD_ISSET (p->outfd, &connect_wait_mask)) 3281 else if ((fd_callback_info[p->outfd].flags & NON_BLOCKING_CONNECT_FD) == 0)
3106 { 3282 {
3107 /* If we cleared the connection wait mask before we did the TLS 3283 /* If we cleared the connection wait mask before we did the TLS
3108 setup, then we have to say that the process is finally "open" 3284 setup, then we have to say that the process is finally "open"
@@ -3412,25 +3588,18 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3412 if (! (connecting_status (p->status) 3588 if (! (connecting_status (p->status)
3413 && EQ (XCDR (p->status), addrinfos))) 3589 && EQ (XCDR (p->status), addrinfos)))
3414 pset_status (p, Fcons (Qconnect, addrinfos)); 3590 pset_status (p, Fcons (Qconnect, addrinfos));
3415 if (!FD_ISSET (inch, &connect_wait_mask)) 3591 if ((fd_callback_info[inch].flags & NON_BLOCKING_CONNECT_FD) == 0)
3416 { 3592 add_non_blocking_write_fd (inch);
3417 FD_SET (inch, &connect_wait_mask);
3418 FD_SET (inch, &write_mask);
3419 num_pending_connects++;
3420 }
3421 } 3593 }
3422 else 3594 else
3423 /* A server may have a client filter setting of Qt, but it must 3595 /* A server may have a client filter setting of Qt, but it must
3424 still listen for incoming connects unless it is stopped. */ 3596 still listen for incoming connects unless it is stopped. */
3425 if ((!EQ (p->filter, Qt) && !EQ (p->command, Qt)) 3597 if ((!EQ (p->filter, Qt) && !EQ (p->command, Qt))
3426 || (EQ (p->status, Qlisten) && NILP (p->command))) 3598 || (EQ (p->status, Qlisten) && NILP (p->command)))
3427 { 3599 add_process_read_fd (inch);
3428 FD_SET (inch, &input_wait_mask);
3429 FD_SET (inch, &non_keyboard_wait_mask);
3430 }
3431 3600
3432 if (inch > max_process_desc) 3601 if (inch > max_desc)
3433 max_process_desc = inch; 3602 max_desc = inch;
3434 3603
3435 /* Set up the masks based on the process filter. */ 3604 /* Set up the masks based on the process filter. */
3436 set_process_filter_masks (p); 3605 set_process_filter_masks (p);
@@ -4361,26 +4530,11 @@ deactivate_process (Lisp_Object proc)
4361 } 4530 }
4362#endif 4531#endif
4363 chan_process[inchannel] = Qnil; 4532 chan_process[inchannel] = Qnil;
4364 FD_CLR (inchannel, &input_wait_mask); 4533 delete_read_fd (inchannel);
4365 FD_CLR (inchannel, &non_keyboard_wait_mask); 4534 if ((fd_callback_info[inchannel].flags & NON_BLOCKING_CONNECT_FD) != 0)
4366 if (FD_ISSET (inchannel, &connect_wait_mask)) 4535 delete_write_fd (inchannel);
4367 { 4536 if (inchannel == max_desc)
4368 FD_CLR (inchannel, &connect_wait_mask); 4537 recompute_max_desc ();
4369 FD_CLR (inchannel, &write_mask);
4370 if (--num_pending_connects < 0)
4371 emacs_abort ();
4372 }
4373 if (inchannel == max_process_desc)
4374 {
4375 /* We just closed the highest-numbered process input descriptor,
4376 so recompute the highest-numbered one now. */
4377 int i = inchannel;
4378 do
4379 i--;
4380 while (0 <= i && NILP (chan_process[i]));
4381
4382 max_process_desc = i;
4383 }
4384 } 4538 }
4385} 4539}
4386 4540
@@ -4409,7 +4563,18 @@ is nil, from any process) before the timeout expired. */)
4409 int nsecs; 4563 int nsecs;
4410 4564
4411 if (! NILP (process)) 4565 if (! NILP (process))
4412 CHECK_PROCESS (process); 4566 {
4567 struct Lisp_Process *procp;
4568
4569 CHECK_PROCESS (process);
4570 procp = XPROCESS (process);
4571
4572 /* Can't wait for a process that is dedicated to a different
4573 thread. */
4574 if (!EQ (procp->thread, Qnil) && !EQ (procp->thread, Fcurrent_thread ()))
4575 error ("Attempt to accept output from process %s locked to thread %s",
4576 SDATA (procp->name), SDATA (XTHREAD (procp->thread)->name));
4577 }
4413 else 4578 else
4414 just_this_one = Qnil; 4579 just_this_one = Qnil;
4415 4580
@@ -4627,13 +4792,9 @@ server_accept_connection (Lisp_Object server, int channel)
4627 4792
4628 /* Client processes for accepted connections are not stopped initially. */ 4793 /* Client processes for accepted connections are not stopped initially. */
4629 if (!EQ (p->filter, Qt)) 4794 if (!EQ (p->filter, Qt))
4630 { 4795 add_process_read_fd (s);
4631 FD_SET (s, &input_wait_mask); 4796 if (s > max_desc)
4632 FD_SET (s, &non_keyboard_wait_mask); 4797 max_desc = s;
4633 }
4634
4635 if (s > max_process_desc)
4636 max_process_desc = s;
4637 4798
4638 /* Setup coding system for new process based on server process. 4799 /* Setup coding system for new process based on server process.
4639 This seems to be the proper thing to do, as the coding system 4800 This seems to be the proper thing to do, as the coding system
@@ -4746,20 +4907,10 @@ wait_for_tls_negotiation (Lisp_Object process)
4746#endif 4907#endif
4747} 4908}
4748 4909
4749/* This variable is different from waiting_for_input in keyboard.c.
4750 It is used to communicate to a lisp process-filter/sentinel (via the
4751 function Fwaiting_for_user_input_p below) whether Emacs was waiting
4752 for user-input when that process-filter was called.
4753 waiting_for_input cannot be used as that is by definition 0 when
4754 lisp code is being evalled.
4755 This is also used in record_asynch_buffer_change.
4756 For that purpose, this must be 0
4757 when not inside wait_reading_process_output. */
4758static int waiting_for_user_input_p;
4759
4760static void 4910static void
4761wait_reading_process_output_unwind (int data) 4911wait_reading_process_output_unwind (int data)
4762{ 4912{
4913 clear_waiting_thread_info ();
4763 waiting_for_user_input_p = data; 4914 waiting_for_user_input_p = data;
4764} 4915}
4765 4916
@@ -4832,6 +4983,10 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4832 /* Close to the current time if known, an invalid timespec otherwise. */ 4983 /* Close to the current time if known, an invalid timespec otherwise. */
4833 struct timespec now = invalid_timespec (); 4984 struct timespec now = invalid_timespec ();
4834 4985
4986 eassert (wait_proc == NULL
4987 || EQ (wait_proc->thread, Qnil)
4988 || XTHREAD (wait_proc->thread) == current_thread);
4989
4835 FD_ZERO (&Available); 4990 FD_ZERO (&Available);
4836 FD_ZERO (&Writeok); 4991 FD_ZERO (&Writeok);
4837 4992
@@ -5004,14 +5159,14 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5004 if (kbd_on_hold_p ()) 5159 if (kbd_on_hold_p ())
5005 FD_ZERO (&Atemp); 5160 FD_ZERO (&Atemp);
5006 else 5161 else
5007 Atemp = input_wait_mask; 5162 compute_input_wait_mask (&Atemp);
5008 Ctemp = write_mask; 5163 compute_write_mask (&Ctemp);
5009 5164
5010 timeout = make_timespec (0, 0); 5165 timeout = make_timespec (0, 0);
5011 if ((pselect (max (max_process_desc, max_input_desc) + 1, 5166 if ((thread_select (pselect, max_desc + 1,
5012 &Atemp, 5167 &Atemp,
5013 (num_pending_connects > 0 ? &Ctemp : NULL), 5168 (num_pending_connects > 0 ? &Ctemp : NULL),
5014 NULL, &timeout, NULL) 5169 NULL, &timeout, NULL)
5015 <= 0)) 5170 <= 0))
5016 { 5171 {
5017 /* It's okay for us to do this and then continue with 5172 /* It's okay for us to do this and then continue with
@@ -5076,17 +5231,17 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5076 } 5231 }
5077 else if (!NILP (wait_for_cell)) 5232 else if (!NILP (wait_for_cell))
5078 { 5233 {
5079 Available = non_process_wait_mask; 5234 compute_non_process_wait_mask (&Available);
5080 check_delay = 0; 5235 check_delay = 0;
5081 check_write = 0; 5236 check_write = 0;
5082 } 5237 }
5083 else 5238 else
5084 { 5239 {
5085 if (! read_kbd) 5240 if (! read_kbd)
5086 Available = non_keyboard_wait_mask; 5241 compute_non_keyboard_wait_mask (&Available);
5087 else 5242 else
5088 Available = input_wait_mask; 5243 compute_input_wait_mask (&Available);
5089 Writeok = write_mask; 5244 compute_write_mask (&Writeok);
5090 check_delay = wait_proc ? 0 : process_output_delay_count; 5245 check_delay = wait_proc ? 0 : process_output_delay_count;
5091 check_write = true; 5246 check_write = true;
5092 } 5247 }
@@ -5128,7 +5283,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5128 int adaptive_nsecs = timeout.tv_nsec; 5283 int adaptive_nsecs = timeout.tv_nsec;
5129 if (timeout.tv_sec > 0 || adaptive_nsecs > READ_OUTPUT_DELAY_MAX) 5284 if (timeout.tv_sec > 0 || adaptive_nsecs > READ_OUTPUT_DELAY_MAX)
5130 adaptive_nsecs = READ_OUTPUT_DELAY_MAX; 5285 adaptive_nsecs = READ_OUTPUT_DELAY_MAX;
5131 for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++) 5286 for (channel = 0; check_delay > 0 && channel <= max_desc; channel++)
5132 { 5287 {
5133 proc = chan_process[channel]; 5288 proc = chan_process[channel];
5134 if (NILP (proc)) 5289 if (NILP (proc))
@@ -5187,17 +5342,18 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5187 } 5342 }
5188#endif 5343#endif
5189 5344
5345 nfds = thread_select (
5190#if defined (HAVE_NS) 5346#if defined (HAVE_NS)
5191 nfds = ns_select 5347 ns_select
5192#elif defined (HAVE_GLIB) 5348#elif defined (HAVE_GLIB)
5193 nfds = xg_select 5349 xg_select
5194#else 5350#else
5195 nfds = pselect 5351 pselect
5196#endif 5352#endif
5197 (max (max_process_desc, max_input_desc) + 1, 5353 , max_desc + 1,
5198 &Available, 5354 &Available,
5199 (check_write ? &Writeok : 0), 5355 (check_write ? &Writeok : 0),
5200 NULL, &timeout, NULL); 5356 NULL, &timeout, NULL);
5201 5357
5202#ifdef HAVE_GNUTLS 5358#ifdef HAVE_GNUTLS
5203 /* GnuTLS buffers data internally. In lowat mode it leaves 5359 /* GnuTLS buffers data internally. In lowat mode it leaves
@@ -5381,22 +5537,22 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5381 if (no_avail || nfds == 0) 5537 if (no_avail || nfds == 0)
5382 continue; 5538 continue;
5383 5539
5384 for (channel = 0; channel <= max_input_desc; ++channel) 5540 for (channel = 0; channel <= max_desc; ++channel)
5385 { 5541 {
5386 struct fd_callback_data *d = &fd_callback_info[channel]; 5542 struct fd_callback_data *d = &fd_callback_info[channel];
5387 if (d->func 5543 if (d->func
5388 && ((d->condition & FOR_READ 5544 && ((d->flags & FOR_READ
5389 && FD_ISSET (channel, &Available)) 5545 && FD_ISSET (channel, &Available))
5390 || (d->condition & FOR_WRITE 5546 || ((d->flags & FOR_WRITE)
5391 && FD_ISSET (channel, &write_mask)))) 5547 && FD_ISSET (channel, &Writeok))))
5392 d->func (channel, d->data); 5548 d->func (channel, d->data);
5393 } 5549 }
5394 5550
5395 for (channel = 0; channel <= max_process_desc; channel++) 5551 for (channel = 0; channel <= max_desc; channel++)
5396 { 5552 {
5397 if (FD_ISSET (channel, &Available) 5553 if (FD_ISSET (channel, &Available)
5398 && FD_ISSET (channel, &non_keyboard_wait_mask) 5554 && ((fd_callback_info[channel].flags & (KEYBOARD_FD | PROCESS_FD))
5399 && !FD_ISSET (channel, &non_process_wait_mask)) 5555 == PROCESS_FD))
5400 { 5556 {
5401 int nread; 5557 int nread;
5402 5558
@@ -5461,8 +5617,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5461 5617
5462 /* Clear the descriptor now, so we only raise the 5618 /* Clear the descriptor now, so we only raise the
5463 signal once. */ 5619 signal once. */
5464 FD_CLR (channel, &input_wait_mask); 5620 delete_read_fd (channel);
5465 FD_CLR (channel, &non_keyboard_wait_mask);
5466 5621
5467 if (p->pid == -2) 5622 if (p->pid == -2)
5468 { 5623 {
@@ -5501,14 +5656,12 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5501 } 5656 }
5502 } 5657 }
5503 if (FD_ISSET (channel, &Writeok) 5658 if (FD_ISSET (channel, &Writeok)
5504 && FD_ISSET (channel, &connect_wait_mask)) 5659 && (fd_callback_info[channel].flags
5660 & NON_BLOCKING_CONNECT_FD) != 0)
5505 { 5661 {
5506 struct Lisp_Process *p; 5662 struct Lisp_Process *p;
5507 5663
5508 FD_CLR (channel, &connect_wait_mask); 5664 delete_write_fd (channel);
5509 FD_CLR (channel, &write_mask);
5510 if (--num_pending_connects < 0)
5511 emacs_abort ();
5512 5665
5513 proc = chan_process[channel]; 5666 proc = chan_process[channel];
5514 if (NILP (proc)) 5667 if (NILP (proc))
@@ -5576,10 +5729,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5576 5729
5577 if (0 <= p->infd && !EQ (p->filter, Qt) 5730 if (0 <= p->infd && !EQ (p->filter, Qt)
5578 && !EQ (p->command, Qt)) 5731 && !EQ (p->command, Qt))
5579 { 5732 add_process_read_fd (p->infd);
5580 FD_SET (p->infd, &input_wait_mask);
5581 FD_SET (p->infd, &non_keyboard_wait_mask);
5582 }
5583 } 5733 }
5584 } 5734 }
5585 } /* End for each file descriptor. */ 5735 } /* End for each file descriptor. */
@@ -6550,10 +6700,7 @@ of incoming traffic. */)
6550 p = XPROCESS (process); 6700 p = XPROCESS (process);
6551 if (NILP (p->command) 6701 if (NILP (p->command)
6552 && p->infd >= 0) 6702 && p->infd >= 0)
6553 { 6703 delete_read_fd (p->infd);
6554 FD_CLR (p->infd, &input_wait_mask);
6555 FD_CLR (p->infd, &non_keyboard_wait_mask);
6556 }
6557 pset_command (p, Qt); 6704 pset_command (p, Qt);
6558 return process; 6705 return process;
6559 } 6706 }
@@ -6582,8 +6729,7 @@ traffic. */)
6582 && p->infd >= 0 6729 && p->infd >= 0
6583 && (!EQ (p->filter, Qt) || EQ (p->status, Qlisten))) 6730 && (!EQ (p->filter, Qt) || EQ (p->status, Qlisten)))
6584 { 6731 {
6585 FD_SET (p->infd, &input_wait_mask); 6732 add_process_read_fd (p->infd);
6586 FD_SET (p->infd, &non_keyboard_wait_mask);
6587#ifdef WINDOWSNT 6733#ifdef WINDOWSNT
6588 if (fd_info[ p->infd ].flags & FILE_SERIAL) 6734 if (fd_info[ p->infd ].flags & FILE_SERIAL)
6589 PurgeComm (fd_info[ p->infd ].hnd, PURGE_RXABORT | PURGE_RXCLEAR); 6735 PurgeComm (fd_info[ p->infd ].hnd, PURGE_RXABORT | PURGE_RXCLEAR);
@@ -6890,10 +7036,7 @@ handle_child_signal (int sig)
6890 7036
6891 /* clear_desc_flag avoids a compiler bug in Microsoft C. */ 7037 /* clear_desc_flag avoids a compiler bug in Microsoft C. */
6892 if (clear_desc_flag) 7038 if (clear_desc_flag)
6893 { 7039 delete_read_fd (p->infd);
6894 FD_CLR (p->infd, &input_wait_mask);
6895 FD_CLR (p->infd, &non_keyboard_wait_mask);
6896 }
6897 } 7040 }
6898 } 7041 }
6899 } 7042 }
@@ -7253,9 +7396,10 @@ keyboard_bit_set (fd_set *mask)
7253{ 7396{
7254 int fd; 7397 int fd;
7255 7398
7256 for (fd = 0; fd <= max_input_desc; fd++) 7399 for (fd = 0; fd <= max_desc; fd++)
7257 if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask) 7400 if (FD_ISSET (fd, mask)
7258 && !FD_ISSET (fd, &non_keyboard_wait_mask)) 7401 && ((fd_callback_info[fd].flags & (FOR_READ | KEYBOARD_FD))
7402 == (FOR_READ | KEYBOARD_FD)))
7259 return 1; 7403 return 1;
7260 7404
7261 return 0; 7405 return 0;
@@ -7492,14 +7636,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
7492void 7636void
7493add_timer_wait_descriptor (int fd) 7637add_timer_wait_descriptor (int fd)
7494{ 7638{
7495 FD_SET (fd, &input_wait_mask); 7639 add_read_fd (fd, timerfd_callback, NULL);
7496 FD_SET (fd, &non_keyboard_wait_mask); 7640 fd_callback_info[fd].flags &= ~KEYBOARD_FD;
7497 FD_SET (fd, &non_process_wait_mask);
7498 fd_callback_info[fd].func = timerfd_callback;
7499 fd_callback_info[fd].data = NULL;
7500 fd_callback_info[fd].condition |= FOR_READ;
7501 if (fd > max_input_desc)
7502 max_input_desc = fd;
7503} 7641}
7504 7642
7505#endif /* HAVE_TIMERFD */ 7643#endif /* HAVE_TIMERFD */
@@ -7523,10 +7661,11 @@ void
7523add_keyboard_wait_descriptor (int desc) 7661add_keyboard_wait_descriptor (int desc)
7524{ 7662{
7525#ifdef subprocesses /* Actually means "not MSDOS". */ 7663#ifdef subprocesses /* Actually means "not MSDOS". */
7526 FD_SET (desc, &input_wait_mask); 7664 eassert (desc >= 0 && desc < FD_SETSIZE);
7527 FD_SET (desc, &non_process_wait_mask); 7665 fd_callback_info[desc].flags &= ~PROCESS_FD;
7528 if (desc > max_input_desc) 7666 fd_callback_info[desc].flags |= (FOR_READ | KEYBOARD_FD);
7529 max_input_desc = desc; 7667 if (desc > max_desc)
7668 max_desc = desc;
7530#endif 7669#endif
7531} 7670}
7532 7671
@@ -7536,9 +7675,12 @@ void
7536delete_keyboard_wait_descriptor (int desc) 7675delete_keyboard_wait_descriptor (int desc)
7537{ 7676{
7538#ifdef subprocesses 7677#ifdef subprocesses
7539 FD_CLR (desc, &input_wait_mask); 7678 eassert (desc >= 0 && desc < FD_SETSIZE);
7540 FD_CLR (desc, &non_process_wait_mask); 7679
7541 delete_input_desc (desc); 7680 fd_callback_info[desc].flags &= ~(FOR_READ | KEYBOARD_FD | PROCESS_FD);
7681
7682 if (desc == max_desc)
7683 recompute_max_desc ();
7542#endif 7684#endif
7543} 7685}
7544 7686
@@ -7819,15 +7961,10 @@ init_process_emacs (int sockfd)
7819 } 7961 }
7820#endif 7962#endif
7821 7963
7822 FD_ZERO (&input_wait_mask);
7823 FD_ZERO (&non_keyboard_wait_mask);
7824 FD_ZERO (&non_process_wait_mask);
7825 FD_ZERO (&write_mask);
7826 max_process_desc = max_input_desc = -1;
7827 external_sock_fd = sockfd; 7964 external_sock_fd = sockfd;
7965 max_desc = -1;
7828 memset (fd_callback_info, 0, sizeof (fd_callback_info)); 7966 memset (fd_callback_info, 0, sizeof (fd_callback_info));
7829 7967
7830 FD_ZERO (&connect_wait_mask);
7831 num_pending_connects = 0; 7968 num_pending_connects = 0;
7832 7969
7833 process_output_delay_count = 0; 7970 process_output_delay_count = 0;
@@ -8027,6 +8164,8 @@ The variable takes effect when `start-process' is called. */);
8027 defsubr (&Sprocess_filter); 8164 defsubr (&Sprocess_filter);
8028 defsubr (&Sset_process_sentinel); 8165 defsubr (&Sset_process_sentinel);
8029 defsubr (&Sprocess_sentinel); 8166 defsubr (&Sprocess_sentinel);
8167 defsubr (&Sset_process_thread);
8168 defsubr (&Sprocess_thread);
8030 defsubr (&Sset_process_window_size); 8169 defsubr (&Sset_process_window_size);
8031 defsubr (&Sset_process_inherit_coding_system_flag); 8170 defsubr (&Sset_process_inherit_coding_system_flag);
8032 defsubr (&Sset_process_query_on_exit_flag); 8171 defsubr (&Sset_process_query_on_exit_flag);