diff options
| author | Tom Tromey | 2013-03-17 19:49:39 -0600 |
|---|---|---|
| committer | Tom Tromey | 2013-03-17 19:49:39 -0600 |
| commit | dad8121b0e4438e68b23d388585f703e75951337 (patch) | |
| tree | b87288b9a4aaf821e0913a6507e9c253e0d36e63 /src/process.c | |
| parent | 6bd488cd8d05aa3983ca55f70ee384732d8c0085 (diff) | |
| download | emacs-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.c | 127 |
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); | |||
| 266 | static int num_pending_connects; | 266 | static 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. */ | ||
| 270 | static int max_process_desc; | ||
| 271 | |||
| 272 | /* The largest descriptor currently in use for input. */ | 269 | /* The largest descriptor currently in use for input. */ |
| 273 | static int max_input_desc; | 270 | static 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 */ |
| 276 | static Lisp_Object chan_process[MAXDESC]; | 273 | static 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 | ||
| 439 | void | 436 | static void |
| 440 | add_non_keyboard_read_fd (int fd) | 437 | add_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 | ||
| 449 | void | 446 | static void |
| 450 | add_process_read_fd (int fd) | 447 | add_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 | |||
| 459 | delete_read_fd (int fd) | 456 | delete_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 | |||
| 475 | add_write_fd (int fd, fd_callback func, void *data) | 473 | add_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 | ||
| 486 | void | 484 | static void |
| 487 | add_non_blocking_write_fd (int fd) | 485 | add_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 | ||
| 496 | static void | ||
| 497 | recompute_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 | ||
| 500 | void | 513 | void |
| 501 | delete_write_fd (int fd) | 514 | delete_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 |