aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorTom Tromey2013-03-17 19:49:39 -0600
committerTom Tromey2013-03-17 19:49:39 -0600
commitdad8121b0e4438e68b23d388585f703e75951337 (patch)
treeb87288b9a4aaf821e0913a6507e9c253e0d36e63 /src/process.c
parent6bd488cd8d05aa3983ca55f70ee384732d8c0085 (diff)
downloademacs-dad8121b0e4438e68b23d388585f703e75951337.tar.gz
emacs-dad8121b0e4438e68b23d388585f703e75951337.zip
fix process bugs
Fix some process-related bugs, mostly thinkos from the conversion to recording fd state as flags. This now passes the test suite without hanging.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c127
1 files changed, 59 insertions, 68 deletions
diff --git a/src/process.c b/src/process.c
index 044e0c54772..e8e7a2be7be 100644
--- a/src/process.c
+++ b/src/process.c
@@ -266,11 +266,8 @@ static void exec_sentinel (Lisp_Object proc, Lisp_Object reason);
266static int num_pending_connects; 266static int num_pending_connects;
267#endif /* NON_BLOCKING_CONNECT */ 267#endif /* NON_BLOCKING_CONNECT */
268 268
269/* The largest descriptor currently in use for a process object. */
270static int max_process_desc;
271
272/* The largest descriptor currently in use for input. */ 269/* The largest descriptor currently in use for input. */
273static int max_input_desc; 270static int max_desc;
274 271
275/* Indexed by descriptor, gives the process (if any) for that descriptor */ 272/* Indexed by descriptor, gives the process (if any) for that descriptor */
276static Lisp_Object chan_process[MAXDESC]; 273static Lisp_Object chan_process[MAXDESC];
@@ -436,17 +433,17 @@ add_read_fd (int fd, fd_callback func, void *data)
436 fd_callback_info[fd].data = data; 433 fd_callback_info[fd].data = data;
437} 434}
438 435
439void 436static void
440add_non_keyboard_read_fd (int fd) 437add_non_keyboard_read_fd (int fd)
441{ 438{
442 eassert (fd >= 0 && fd < MAXDESC); 439 eassert (fd >= 0 && fd < MAXDESC);
443 eassert (fd_callback_info[fd].func == NULL); 440 eassert (fd_callback_info[fd].func == NULL);
444 fd_callback_info[fd].flags |= FOR_READ; 441 fd_callback_info[fd].flags |= FOR_READ;
445 if (fd > max_input_desc) 442 if (fd > max_desc)
446 max_input_desc = fd; 443 max_desc = fd;
447} 444}
448 445
449void 446static void
450add_process_read_fd (int fd) 447add_process_read_fd (int fd)
451{ 448{
452 add_non_keyboard_read_fd (fd); 449 add_non_keyboard_read_fd (fd);
@@ -459,6 +456,7 @@ void
459delete_read_fd (int fd) 456delete_read_fd (int fd)
460{ 457{
461 eassert (fd < MAXDESC); 458 eassert (fd < MAXDESC);
459 eassert (fd <= max_desc);
462 delete_keyboard_wait_descriptor (fd); 460 delete_keyboard_wait_descriptor (fd);
463 461
464 if (fd_callback_info[fd].flags == 0) 462 if (fd_callback_info[fd].flags == 0)
@@ -475,34 +473,51 @@ void
475add_write_fd (int fd, fd_callback func, void *data) 473add_write_fd (int fd, fd_callback func, void *data)
476{ 474{
477 eassert (fd < MAXDESC); 475 eassert (fd < MAXDESC);
478 if (fd > max_input_desc) 476 if (fd > max_desc)
479 max_input_desc = fd; 477 max_desc = fd;
480 478
481 fd_callback_info[fd].func = func; 479 fd_callback_info[fd].func = func;
482 fd_callback_info[fd].data = data; 480 fd_callback_info[fd].data = data;
483 fd_callback_info[fd].flags |= FOR_WRITE; 481 fd_callback_info[fd].flags |= FOR_WRITE;
484} 482}
485 483
486void 484static void
487add_non_blocking_write_fd (int fd) 485add_non_blocking_write_fd (int fd)
488{ 486{
489 eassert (fd >= 0 && fd < MAXDESC); 487 eassert (fd >= 0 && fd < MAXDESC);
490 eassert (fd_callback_info[fd].func == NULL); 488 eassert (fd_callback_info[fd].func == NULL);
491 489
492 fd_callback_info[fd].flags |= FOR_WRITE | NON_BLOCKING_CONNECT_FD; 490 fd_callback_info[fd].flags |= FOR_WRITE | NON_BLOCKING_CONNECT_FD;
493 if (fd > max_input_desc) 491 if (fd > max_desc)
494 max_input_desc = fd; 492 max_desc = fd;
495 ++num_pending_connects; 493 ++num_pending_connects;
496} 494}
497 495
496static void
497recompute_max_desc (void)
498{
499 int fd;
500
501 for (fd = max_desc; fd >= 0; --fd)
502 {
503 if (fd_callback_info[fd].flags != 0)
504 {
505 max_desc = fd;
506 break;
507 }
508 }
509}
510
498/* Stop monitoring file descriptor FD for when write is possible. */ 511/* Stop monitoring file descriptor FD for when write is possible. */
499 512
500void 513void
501delete_write_fd (int fd) 514delete_write_fd (int fd)
502{ 515{
503 int lim = max_input_desc; 516 int lim = max_desc;
504 517
505 eassert (fd < MAXDESC); 518 eassert (fd < MAXDESC);
519 eassert (fd <= max_desc);
520
506 if ((fd_callback_info[fd].flags & NON_BLOCKING_CONNECT_FD) != 0) 521 if ((fd_callback_info[fd].flags & NON_BLOCKING_CONNECT_FD) != 0)
507 { 522 {
508 if (--num_pending_connects < 0) 523 if (--num_pending_connects < 0)
@@ -514,17 +529,8 @@ delete_write_fd (int fd)
514 fd_callback_info[fd].func = 0; 529 fd_callback_info[fd].func = 0;
515 fd_callback_info[fd].data = 0; 530 fd_callback_info[fd].data = 0;
516 531
517 if (fd == max_input_desc) 532 if (fd == max_desc)
518 { 533 recompute_max_desc ();
519 for (fd = max_input_desc; fd >= 0; --fd)
520 {
521 if (fd_callback_info[fd].flags != 0)
522 {
523 max_input_desc = fd;
524 break;
525 }
526 }
527 }
528 } 534 }
529} 535}
530 536
@@ -534,7 +540,7 @@ compute_input_wait_mask (SELECT_TYPE *mask)
534 int fd; 540 int fd;
535 541
536 FD_ZERO (mask); 542 FD_ZERO (mask);
537 for (fd = 0; fd < max (max_process_desc, max_input_desc); ++fd) 543 for (fd = 0; fd <= max_desc; ++fd)
538 { 544 {
539 if (fd_callback_info[fd].thread != NULL 545 if (fd_callback_info[fd].thread != NULL
540 && fd_callback_info[fd].thread != current_thread) 546 && fd_callback_info[fd].thread != current_thread)
@@ -556,7 +562,7 @@ compute_non_process_wait_mask (SELECT_TYPE *mask)
556 int fd; 562 int fd;
557 563
558 FD_ZERO (mask); 564 FD_ZERO (mask);
559 for (fd = 0; fd < max (max_process_desc, max_input_desc); ++fd) 565 for (fd = 0; fd <= max_desc; ++fd)
560 { 566 {
561 if (fd_callback_info[fd].thread != NULL 567 if (fd_callback_info[fd].thread != NULL
562 && fd_callback_info[fd].thread != current_thread) 568 && fd_callback_info[fd].thread != current_thread)
@@ -579,7 +585,7 @@ compute_non_keyboard_wait_mask (SELECT_TYPE *mask)
579 int fd; 585 int fd;
580 586
581 FD_ZERO (mask); 587 FD_ZERO (mask);
582 for (fd = 0; fd < max (max_process_desc, max_input_desc); ++fd) 588 for (fd = 0; fd <= max_desc; ++fd)
583 { 589 {
584 if (fd_callback_info[fd].thread != NULL 590 if (fd_callback_info[fd].thread != NULL
585 && fd_callback_info[fd].thread != current_thread) 591 && fd_callback_info[fd].thread != current_thread)
@@ -602,7 +608,7 @@ compute_write_mask (SELECT_TYPE *mask)
602 int fd; 608 int fd;
603 609
604 FD_ZERO (mask); 610 FD_ZERO (mask);
605 for (fd = 0; fd < max (max_process_desc, max_input_desc); ++fd) 611 for (fd = 0; fd <= max_desc; ++fd)
606 { 612 {
607 if (fd_callback_info[fd].thread != NULL 613 if (fd_callback_info[fd].thread != NULL
608 && fd_callback_info[fd].thread != current_thread) 614 && fd_callback_info[fd].thread != current_thread)
@@ -623,7 +629,7 @@ clear_waiting_thread_info (void)
623{ 629{
624 int fd; 630 int fd;
625 631
626 for (fd = 0; fd < max (max_process_desc, max_input_desc); ++fd) 632 for (fd = 0; fd <= max_desc; ++fd)
627 { 633 {
628 if (fd_callback_info[fd].waiting_thread == current_thread) 634 if (fd_callback_info[fd].waiting_thread == current_thread)
629 fd_callback_info[fd].waiting_thread = NULL; 635 fd_callback_info[fd].waiting_thread = NULL;
@@ -1853,7 +1859,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1853 XPROCESS (process)->pty_flag = pty_flag; 1859 XPROCESS (process)->pty_flag = pty_flag;
1854 pset_status (XPROCESS (process), Qrun); 1860 pset_status (XPROCESS (process), Qrun);
1855 1861
1856 add_non_keyboard_read_fd (inchannel); 1862 add_process_read_fd (inchannel);
1857 1863
1858 /* This may signal an error. */ 1864 /* This may signal an error. */
1859 setup_process_coding_systems (process); 1865 setup_process_coding_systems (process);
@@ -2107,7 +2113,7 @@ create_pty (Lisp_Object process)
2107 pset_status (XPROCESS (process), Qrun); 2113 pset_status (XPROCESS (process), Qrun);
2108 setup_process_coding_systems (process); 2114 setup_process_coding_systems (process);
2109 2115
2110 add_non_keyboard_read_fd (inchannel); 2116 add_process_read_fd (inchannel);
2111 2117
2112 XPROCESS (process)->pid = -2; 2118 XPROCESS (process)->pid = -2;
2113#ifdef HAVE_PTYS 2119#ifdef HAVE_PTYS
@@ -2729,8 +2735,8 @@ usage: (make-serial-process &rest ARGS) */)
2729 fd = serial_open (SSDATA (port)); 2735 fd = serial_open (SSDATA (port));
2730 p->infd = fd; 2736 p->infd = fd;
2731 p->outfd = fd; 2737 p->outfd = fd;
2732 if (fd > max_process_desc) 2738 if (fd > max_desc)
2733 max_process_desc = fd; 2739 max_desc = fd;
2734 chan_process[fd] = proc; 2740 chan_process[fd] = proc;
2735 2741
2736 buffer = Fplist_get (contact, QCbuffer); 2742 buffer = Fplist_get (contact, QCbuffer);
@@ -3562,8 +3568,8 @@ usage: (make-network-process &rest ARGS) */)
3562 || (EQ (p->status, Qlisten) && NILP (p->command))) 3568 || (EQ (p->status, Qlisten) && NILP (p->command)))
3563 add_non_keyboard_read_fd (inch); 3569 add_non_keyboard_read_fd (inch);
3564 3570
3565 if (inch > max_process_desc) 3571 if (inch > max_desc)
3566 max_process_desc = inch; 3572 max_desc = inch;
3567 3573
3568 tem = Fplist_member (contact, QCcoding); 3574 tem = Fplist_member (contact, QCcoding);
3569 if (!NILP (tem) && (!CONSP (tem) || !CONSP (XCDR (tem)))) 3575 if (!NILP (tem) && (!CONSP (tem) || !CONSP (XCDR (tem))))
@@ -4009,16 +4015,8 @@ deactivate_process (Lisp_Object proc)
4009 if ((fd_callback_info[inchannel].flags & NON_BLOCKING_CONNECT_FD) != 0) 4015 if ((fd_callback_info[inchannel].flags & NON_BLOCKING_CONNECT_FD) != 0)
4010 delete_write_fd (inchannel); 4016 delete_write_fd (inchannel);
4011#endif 4017#endif
4012 if (inchannel == max_process_desc) 4018 if (inchannel == max_desc)
4013 { 4019 recompute_max_desc ();
4014 int i;
4015 /* We just closed the highest-numbered process input descriptor,
4016 so recompute the highest-numbered one now. */
4017 max_process_desc = 0;
4018 for (i = 0; i < MAXDESC; i++)
4019 if (!NILP (chan_process[i]))
4020 max_process_desc = i;
4021 }
4022 } 4020 }
4023} 4021}
4024 4022
@@ -4534,8 +4532,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4534 compute_write_mask (&Ctemp); 4532 compute_write_mask (&Ctemp);
4535 4533
4536 timeout = make_emacs_time (0, 0); 4534 timeout = make_emacs_time (0, 0);
4537 if ((thread_select (pselect, 4535 if ((thread_select (pselect, max_desc + 1,
4538 max (max_process_desc, max_input_desc) + 1,
4539 &Atemp, 4536 &Atemp,
4540#ifdef NON_BLOCKING_CONNECT 4537#ifdef NON_BLOCKING_CONNECT
4541 (num_pending_connects > 0 ? &Ctemp : NULL), 4538 (num_pending_connects > 0 ? &Ctemp : NULL),
@@ -4662,7 +4659,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4662 int nsecs = EMACS_NSECS (timeout); 4659 int nsecs = EMACS_NSECS (timeout);
4663 if (EMACS_SECS (timeout) > 0 || nsecs > READ_OUTPUT_DELAY_MAX) 4660 if (EMACS_SECS (timeout) > 0 || nsecs > READ_OUTPUT_DELAY_MAX)
4664 nsecs = READ_OUTPUT_DELAY_MAX; 4661 nsecs = READ_OUTPUT_DELAY_MAX;
4665 for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++) 4662 for (channel = 0; check_delay > 0 && channel <= max_desc; channel++)
4666 { 4663 {
4667 proc = chan_process[channel]; 4664 proc = chan_process[channel];
4668 if (NILP (proc)) 4665 if (NILP (proc))
@@ -4692,7 +4689,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4692#else 4689#else
4693 pselect 4690 pselect
4694#endif 4691#endif
4695 , max (max_process_desc, max_input_desc) + 1, 4692 , max_desc + 1,
4696 &Available, 4693 &Available,
4697 (check_write ? &Writeok : (SELECT_TYPE *)0), 4694 (check_write ? &Writeok : (SELECT_TYPE *)0),
4698 NULL, &timeout, NULL); 4695 NULL, &timeout, NULL);
@@ -4863,7 +4860,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4863 if (no_avail || nfds == 0) 4860 if (no_avail || nfds == 0)
4864 continue; 4861 continue;
4865 4862
4866 for (channel = 0; channel <= max_input_desc; ++channel) 4863 for (channel = 0; channel <= max_desc; ++channel)
4867 { 4864 {
4868 struct fd_callback_data *d = &fd_callback_info[channel]; 4865 struct fd_callback_data *d = &fd_callback_info[channel];
4869 if (d->func 4866 if (d->func
@@ -4874,7 +4871,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
4874 d->func (channel, d->data); 4871 d->func (channel, d->data);
4875 } 4872 }
4876 4873
4877 for (channel = 0; channel <= max_process_desc; channel++) 4874 for (channel = 0; channel <= max_desc; channel++)
4878 { 4875 {
4879 if (FD_ISSET (channel, &Available) 4876 if (FD_ISSET (channel, &Available)
4880 && ((fd_callback_info[channel].flags & (KEYBOARD_FD | PROCESS_FD)) 4877 && ((fd_callback_info[channel].flags & (KEYBOARD_FD | PROCESS_FD))
@@ -6669,7 +6666,7 @@ keyboard_bit_set (fd_set *mask)
6669{ 6666{
6670 int fd; 6667 int fd;
6671 6668
6672 for (fd = 0; fd <= max_input_desc; fd++) 6669 for (fd = 0; fd <= max_desc; fd++)
6673 if (FD_ISSET (fd, mask) 6670 if (FD_ISSET (fd, mask)
6674 && ((fd_callback_info[fd].flags & KEYBOARD_FD) != 0)) 6671 && ((fd_callback_info[fd].flags & KEYBOARD_FD) != 0))
6675 return 1; 6672 return 1;
@@ -6918,8 +6915,8 @@ add_keyboard_wait_descriptor (int desc)
6918#ifdef subprocesses /* actually means "not MSDOS" */ 6915#ifdef subprocesses /* actually means "not MSDOS" */
6919 eassert (desc >= 0 && desc < MAXDESC); 6916 eassert (desc >= 0 && desc < MAXDESC);
6920 fd_callback_info[desc].flags |= FOR_READ | KEYBOARD_FD; 6917 fd_callback_info[desc].flags |= FOR_READ | KEYBOARD_FD;
6921 if (desc > max_input_desc) 6918 if (desc > max_desc)
6922 max_input_desc = desc; 6919 max_desc = desc;
6923#endif 6920#endif
6924} 6921}
6925 6922
@@ -6930,21 +6927,15 @@ delete_keyboard_wait_descriptor (int desc)
6930{ 6927{
6931#ifdef subprocesses 6928#ifdef subprocesses
6932 int fd; 6929 int fd;
6933 int lim = max_input_desc; 6930 int lim = max_desc;
6931
6932 eassert (desc >= 0 && desc < MAXDESC);
6933 eassert (desc <= max_desc);
6934 6934
6935 fd_callback_info[desc].flags &= ~(FOR_READ | KEYBOARD_FD | PROCESS_FD); 6935 fd_callback_info[desc].flags &= ~(FOR_READ | KEYBOARD_FD | PROCESS_FD);
6936 6936
6937 if (desc == max_input_desc) 6937 if (desc == max_desc)
6938 { 6938 recompute_max_desc ();
6939 for (fd = max_input_desc; fd >= 0; --fd)
6940 {
6941 if (fd_callback_info[desc].flags != 0)
6942 {
6943 max_input_desc = fd;
6944 break;
6945 }
6946 }
6947 }
6948#endif 6939#endif
6949} 6940}
6950 6941
@@ -7202,7 +7193,7 @@ init_process_emacs (void)
7202 sigaction (SIGCHLD, &action, 0); 7193 sigaction (SIGCHLD, &action, 0);
7203 } 7194 }
7204 7195
7205 max_process_desc = 0; 7196 max_desc = 0;
7206 memset (fd_callback_info, 0, sizeof (fd_callback_info)); 7197 memset (fd_callback_info, 0, sizeof (fd_callback_info));
7207 7198
7208#ifdef NON_BLOCKING_CONNECT 7199#ifdef NON_BLOCKING_CONNECT