diff options
| author | Eli Zaretskii | 2016-12-04 19:59:17 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2016-12-04 19:59:17 +0200 |
| commit | de4624c99ea5bbe38ad5aff7b6461cc5c740d0be (patch) | |
| tree | 1b57de9e769cdb695cb2cecf157b50f7dea9cfe5 /src/process.c | |
| parent | a486fabb41cdbaa5813c2687fd4008945297d71d (diff) | |
| parent | e7bde34e939451d87fb42a36195086bdbe48b5e1 (diff) | |
| download | emacs-de4624c99ea5bbe38ad5aff7b6461cc5c740d0be.tar.gz emacs-de4624c99ea5bbe38ad5aff7b6461cc5c740d0be.zip | |
Merge branch 'concurrency'
Conflicts (resolved):
configure.ac
src/Makefile.in
src/alloc.c
src/bytecode.c
src/emacs.c
src/eval.c
src/lisp.h
src/process.c
src/regex.c
src/regex.h
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 542 |
1 files changed, 338 insertions, 204 deletions
diff --git a/src/process.c b/src/process.c index 49340b120ef..e538c86fcf5 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 |
| 140 | extern int sys_select (int, fd_set *, fd_set *, fd_set *, | 140 | extern int sys_select (int, fd_set *, fd_set *, fd_set *, |
| 141 | struct timespec *, void *); | 141 | struct timespec *, 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); | |||
| 260 | static void create_pty (Lisp_Object); | 260 | static void create_pty (Lisp_Object); |
| 261 | static void exec_sentinel (Lisp_Object, Lisp_Object); | 261 | static void exec_sentinel (Lisp_Object, Lisp_Object); |
| 262 | 262 | ||
| 263 | /* Mask of bits indicating the descriptors that we wait for input on. */ | ||
| 264 | |||
| 265 | static fd_set input_wait_mask; | ||
| 266 | |||
| 267 | /* Mask that excludes keyboard input descriptor(s). */ | ||
| 268 | |||
| 269 | static fd_set non_keyboard_wait_mask; | ||
| 270 | |||
| 271 | /* Mask that excludes process input descriptor(s). */ | ||
| 272 | |||
| 273 | static fd_set non_process_wait_mask; | ||
| 274 | |||
| 275 | /* Mask for selecting for write. */ | ||
| 276 | |||
| 277 | static 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 | |||
| 283 | static fd_set connect_wait_mask; | ||
| 284 | |||
| 285 | /* Number of bits set in connect_wait_mask. */ | 263 | /* Number of bits set in connect_wait_mask. */ |
| 286 | static int num_pending_connects; | 264 | static 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. */ |
| 289 | static int max_process_desc; | 267 | static int max_desc; |
| 290 | |||
| 291 | /* The largest descriptor currently in use for input; -1 if none. */ | ||
| 292 | static 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 | } |
| 386 | static void | 361 | static void |
| 362 | pset_thread (struct Lisp_Process *p, Lisp_Object val) | ||
| 363 | { | ||
| 364 | p->thread = val; | ||
| 365 | } | ||
| 366 | static void | ||
| 387 | pset_name (struct Lisp_Process *p, Lisp_Object val) | 367 | pset_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 | ||
| 409 | enum 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 | |||
| 429 | static struct fd_callback_data | 424 | static 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,23 @@ 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 | |||
| 452 | static void | ||
| 453 | add_non_keyboard_read_fd (int fd) | ||
| 454 | { | ||
| 455 | eassert (fd >= 0 && fd < FD_SETSIZE); | ||
| 456 | eassert (fd_callback_info[fd].func == NULL); | ||
| 457 | fd_callback_info[fd].flags |= FOR_READ; | ||
| 458 | if (fd > max_desc) | ||
| 459 | max_desc = fd; | ||
| 460 | } | ||
| 461 | |||
| 462 | static void | ||
| 463 | add_process_read_fd (int fd) | ||
| 464 | { | ||
| 465 | add_non_keyboard_read_fd (fd); | ||
| 466 | fd_callback_info[fd].flags |= PROCESS_FD; | ||
| 450 | } | 467 | } |
| 451 | 468 | ||
| 452 | /* Stop monitoring file descriptor FD for when read is possible. */ | 469 | /* Stop monitoring file descriptor FD for when read is possible. */ |
| @@ -456,8 +473,7 @@ delete_read_fd (int fd) | |||
| 456 | { | 473 | { |
| 457 | delete_keyboard_wait_descriptor (fd); | 474 | delete_keyboard_wait_descriptor (fd); |
| 458 | 475 | ||
| 459 | fd_callback_info[fd].condition &= ~FOR_READ; | 476 | if (fd_callback_info[fd].flags == 0) |
| 460 | if (fd_callback_info[fd].condition == 0) | ||
| 461 | { | 477 | { |
| 462 | fd_callback_info[fd].func = 0; | 478 | fd_callback_info[fd].func = 0; |
| 463 | fd_callback_info[fd].data = 0; | 479 | fd_callback_info[fd].data = 0; |
| @@ -470,28 +486,38 @@ delete_read_fd (int fd) | |||
| 470 | void | 486 | void |
| 471 | add_write_fd (int fd, fd_callback func, void *data) | 487 | add_write_fd (int fd, fd_callback func, void *data) |
| 472 | { | 488 | { |
| 473 | FD_SET (fd, &write_mask); | 489 | if (fd > max_desc) |
| 474 | if (fd > max_input_desc) | 490 | max_desc = fd; |
| 475 | max_input_desc = fd; | ||
| 476 | 491 | ||
| 477 | fd_callback_info[fd].func = func; | 492 | fd_callback_info[fd].func = func; |
| 478 | fd_callback_info[fd].data = data; | 493 | fd_callback_info[fd].data = data; |
| 479 | fd_callback_info[fd].condition |= FOR_WRITE; | 494 | fd_callback_info[fd].flags |= FOR_WRITE; |
| 480 | } | 495 | } |
| 481 | 496 | ||
| 482 | /* FD is no longer an input descriptor; update max_input_desc accordingly. */ | 497 | static void |
| 498 | add_non_blocking_write_fd (int fd) | ||
| 499 | { | ||
| 500 | eassert (fd >= 0 && fd < FD_SETSIZE); | ||
| 501 | eassert (fd_callback_info[fd].func == NULL); | ||
| 502 | |||
| 503 | fd_callback_info[fd].flags |= FOR_WRITE | NON_BLOCKING_CONNECT_FD; | ||
| 504 | if (fd > max_desc) | ||
| 505 | max_desc = fd; | ||
| 506 | ++num_pending_connects; | ||
| 507 | } | ||
| 483 | 508 | ||
| 484 | static void | 509 | static void |
| 485 | delete_input_desc (int fd) | 510 | recompute_max_desc (void) |
| 486 | { | 511 | { |
| 487 | if (fd == max_input_desc) | 512 | int fd; |
| 488 | { | ||
| 489 | do | ||
| 490 | fd--; | ||
| 491 | while (0 <= fd && ! (FD_ISSET (fd, &input_wait_mask) | ||
| 492 | || FD_ISSET (fd, &write_mask))); | ||
| 493 | 513 | ||
| 494 | max_input_desc = fd; | 514 | for (fd = max_desc; fd >= 0; --fd) |
| 515 | { | ||
| 516 | if (fd_callback_info[fd].flags != 0) | ||
| 517 | { | ||
| 518 | max_desc = fd; | ||
| 519 | break; | ||
| 520 | } | ||
| 495 | } | 521 | } |
| 496 | } | 522 | } |
| 497 | 523 | ||
| @@ -500,13 +526,123 @@ delete_input_desc (int fd) | |||
| 500 | void | 526 | void |
| 501 | delete_write_fd (int fd) | 527 | delete_write_fd (int fd) |
| 502 | { | 528 | { |
| 503 | FD_CLR (fd, &write_mask); | 529 | int lim = max_desc; |
| 504 | fd_callback_info[fd].condition &= ~FOR_WRITE; | 530 | |
| 505 | if (fd_callback_info[fd].condition == 0) | 531 | if ((fd_callback_info[fd].flags & NON_BLOCKING_CONNECT_FD) != 0) |
| 532 | { | ||
| 533 | if (--num_pending_connects < 0) | ||
| 534 | emacs_abort (); | ||
| 535 | } | ||
| 536 | fd_callback_info[fd].flags &= ~(FOR_WRITE | NON_BLOCKING_CONNECT_FD); | ||
| 537 | if (fd_callback_info[fd].flags == 0) | ||
| 506 | { | 538 | { |
| 507 | fd_callback_info[fd].func = 0; | 539 | fd_callback_info[fd].func = 0; |
| 508 | fd_callback_info[fd].data = 0; | 540 | fd_callback_info[fd].data = 0; |
| 509 | delete_input_desc (fd); | 541 | |
| 542 | if (fd == max_desc) | ||
| 543 | recompute_max_desc (); | ||
| 544 | } | ||
| 545 | } | ||
| 546 | |||
| 547 | static void | ||
| 548 | compute_input_wait_mask (fd_set *mask) | ||
| 549 | { | ||
| 550 | int fd; | ||
| 551 | |||
| 552 | FD_ZERO (mask); | ||
| 553 | for (fd = 0; fd <= max_desc; ++fd) | ||
| 554 | { | ||
| 555 | if (fd_callback_info[fd].thread != NULL | ||
| 556 | && fd_callback_info[fd].thread != current_thread) | ||
| 557 | continue; | ||
| 558 | if (fd_callback_info[fd].waiting_thread != NULL | ||
| 559 | && fd_callback_info[fd].waiting_thread != current_thread) | ||
| 560 | continue; | ||
| 561 | if ((fd_callback_info[fd].flags & FOR_READ) != 0) | ||
| 562 | { | ||
| 563 | FD_SET (fd, mask); | ||
| 564 | fd_callback_info[fd].waiting_thread = current_thread; | ||
| 565 | } | ||
| 566 | } | ||
| 567 | } | ||
| 568 | |||
| 569 | static void | ||
| 570 | compute_non_process_wait_mask (fd_set *mask) | ||
| 571 | { | ||
| 572 | int fd; | ||
| 573 | |||
| 574 | FD_ZERO (mask); | ||
| 575 | for (fd = 0; fd <= max_desc; ++fd) | ||
| 576 | { | ||
| 577 | if (fd_callback_info[fd].thread != NULL | ||
| 578 | && fd_callback_info[fd].thread != current_thread) | ||
| 579 | continue; | ||
| 580 | if (fd_callback_info[fd].waiting_thread != NULL | ||
| 581 | && fd_callback_info[fd].waiting_thread != current_thread) | ||
| 582 | continue; | ||
| 583 | if ((fd_callback_info[fd].flags & FOR_READ) != 0 | ||
| 584 | && (fd_callback_info[fd].flags & PROCESS_FD) == 0) | ||
| 585 | { | ||
| 586 | FD_SET (fd, mask); | ||
| 587 | fd_callback_info[fd].waiting_thread = current_thread; | ||
| 588 | } | ||
| 589 | } | ||
| 590 | } | ||
| 591 | |||
| 592 | static void | ||
| 593 | compute_non_keyboard_wait_mask (fd_set *mask) | ||
| 594 | { | ||
| 595 | int fd; | ||
| 596 | |||
| 597 | FD_ZERO (mask); | ||
| 598 | for (fd = 0; fd <= max_desc; ++fd) | ||
| 599 | { | ||
| 600 | if (fd_callback_info[fd].thread != NULL | ||
| 601 | && fd_callback_info[fd].thread != current_thread) | ||
| 602 | continue; | ||
| 603 | if (fd_callback_info[fd].waiting_thread != NULL | ||
| 604 | && fd_callback_info[fd].waiting_thread != current_thread) | ||
| 605 | continue; | ||
| 606 | if ((fd_callback_info[fd].flags & FOR_READ) != 0 | ||
| 607 | && (fd_callback_info[fd].flags & KEYBOARD_FD) == 0) | ||
| 608 | { | ||
| 609 | FD_SET (fd, mask); | ||
| 610 | fd_callback_info[fd].waiting_thread = current_thread; | ||
| 611 | } | ||
| 612 | } | ||
| 613 | } | ||
| 614 | |||
| 615 | static void | ||
| 616 | compute_write_mask (fd_set *mask) | ||
| 617 | { | ||
| 618 | int fd; | ||
| 619 | |||
| 620 | FD_ZERO (mask); | ||
| 621 | for (fd = 0; fd <= max_desc; ++fd) | ||
| 622 | { | ||
| 623 | if (fd_callback_info[fd].thread != NULL | ||
| 624 | && fd_callback_info[fd].thread != current_thread) | ||
| 625 | continue; | ||
| 626 | if (fd_callback_info[fd].waiting_thread != NULL | ||
| 627 | && fd_callback_info[fd].waiting_thread != current_thread) | ||
| 628 | continue; | ||
| 629 | if ((fd_callback_info[fd].flags & FOR_WRITE) != 0) | ||
| 630 | { | ||
| 631 | FD_SET (fd, mask); | ||
| 632 | fd_callback_info[fd].waiting_thread = current_thread; | ||
| 633 | } | ||
| 634 | } | ||
| 635 | } | ||
| 636 | |||
| 637 | static void | ||
| 638 | clear_waiting_thread_info (void) | ||
| 639 | { | ||
| 640 | int fd; | ||
| 641 | |||
| 642 | for (fd = 0; fd <= max_desc; ++fd) | ||
| 643 | { | ||
| 644 | if (fd_callback_info[fd].waiting_thread == current_thread) | ||
| 645 | fd_callback_info[fd].waiting_thread = NULL; | ||
| 510 | } | 646 | } |
| 511 | } | 647 | } |
| 512 | 648 | ||
| @@ -720,6 +856,7 @@ make_process (Lisp_Object name) | |||
| 720 | Lisp data to nil, so do it only for slots which should not be nil. */ | 856 | Lisp data to nil, so do it only for slots which should not be nil. */ |
| 721 | pset_status (p, Qrun); | 857 | pset_status (p, Qrun); |
| 722 | pset_mark (p, Fmake_marker ()); | 858 | pset_mark (p, Fmake_marker ()); |
| 859 | pset_thread (p, Fcurrent_thread ()); | ||
| 723 | 860 | ||
| 724 | /* Initialize non-Lisp data. Note that allocate_process zeroes out all | 861 | /* Initialize non-Lisp data. Note that allocate_process zeroes out all |
| 725 | non-Lisp data, so do it only for slots which should not be zero. */ | 862 | non-Lisp data, so do it only for slots which should not be zero. */ |
| @@ -768,6 +905,27 @@ remove_process (register Lisp_Object proc) | |||
| 768 | deactivate_process (proc); | 905 | deactivate_process (proc); |
| 769 | } | 906 | } |
| 770 | 907 | ||
| 908 | void | ||
| 909 | update_processes_for_thread_death (Lisp_Object dying_thread) | ||
| 910 | { | ||
| 911 | Lisp_Object pair; | ||
| 912 | |||
| 913 | for (pair = Vprocess_alist; !NILP (pair); pair = XCDR (pair)) | ||
| 914 | { | ||
| 915 | Lisp_Object process = XCDR (XCAR (pair)); | ||
| 916 | if (EQ (XPROCESS (process)->thread, dying_thread)) | ||
| 917 | { | ||
| 918 | struct Lisp_Process *proc = XPROCESS (process); | ||
| 919 | |||
| 920 | proc->thread = Qnil; | ||
| 921 | if (proc->infd >= 0) | ||
| 922 | fd_callback_info[proc->infd].thread = NULL; | ||
| 923 | if (proc->outfd >= 0) | ||
| 924 | fd_callback_info[proc->outfd].thread = NULL; | ||
| 925 | } | ||
| 926 | } | ||
| 927 | } | ||
| 928 | |||
| 771 | #ifdef HAVE_GETADDRINFO_A | 929 | #ifdef HAVE_GETADDRINFO_A |
| 772 | static void | 930 | static void |
| 773 | free_dns_request (Lisp_Object proc) | 931 | free_dns_request (Lisp_Object proc) |
| @@ -1070,17 +1228,11 @@ static void | |||
| 1070 | set_process_filter_masks (struct Lisp_Process *p) | 1228 | set_process_filter_masks (struct Lisp_Process *p) |
| 1071 | { | 1229 | { |
| 1072 | if (EQ (p->filter, Qt) && !EQ (p->status, Qlisten)) | 1230 | if (EQ (p->filter, Qt) && !EQ (p->status, Qlisten)) |
| 1073 | { | 1231 | delete_read_fd (p->infd); |
| 1074 | FD_CLR (p->infd, &input_wait_mask); | ||
| 1075 | FD_CLR (p->infd, &non_keyboard_wait_mask); | ||
| 1076 | } | ||
| 1077 | else if (EQ (p->filter, Qt) | 1232 | else if (EQ (p->filter, Qt) |
| 1078 | /* Network or serial process not stopped: */ | 1233 | /* Network or serial process not stopped: */ |
| 1079 | && !EQ (p->command, Qt)) | 1234 | && !EQ (p->command, Qt)) |
| 1080 | { | 1235 | add_read_fd (p->infd); |
| 1081 | FD_SET (p->infd, &input_wait_mask); | ||
| 1082 | FD_SET (p->infd, &non_keyboard_wait_mask); | ||
| 1083 | } | ||
| 1084 | } | 1236 | } |
| 1085 | 1237 | ||
| 1086 | DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter, | 1238 | DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter, |
| @@ -1167,6 +1319,42 @@ See `set-process-sentinel' for more info on sentinels. */) | |||
| 1167 | return XPROCESS (process)->sentinel; | 1319 | return XPROCESS (process)->sentinel; |
| 1168 | } | 1320 | } |
| 1169 | 1321 | ||
| 1322 | DEFUN ("set-process-thread", Fset_process_thread, Sset_process_thread, | ||
| 1323 | 2, 2, 0, | ||
| 1324 | doc: /* FIXME */) | ||
| 1325 | (Lisp_Object process, Lisp_Object thread) | ||
| 1326 | { | ||
| 1327 | struct Lisp_Process *proc; | ||
| 1328 | struct thread_state *tstate; | ||
| 1329 | |||
| 1330 | CHECK_PROCESS (process); | ||
| 1331 | if (NILP (thread)) | ||
| 1332 | tstate = NULL; | ||
| 1333 | else | ||
| 1334 | { | ||
| 1335 | CHECK_THREAD (thread); | ||
| 1336 | tstate = XTHREAD (thread); | ||
| 1337 | } | ||
| 1338 | |||
| 1339 | proc = XPROCESS (process); | ||
| 1340 | proc->thread = thread; | ||
| 1341 | if (proc->infd >= 0) | ||
| 1342 | fd_callback_info[proc->infd].thread = tstate; | ||
| 1343 | if (proc->outfd >= 0) | ||
| 1344 | fd_callback_info[proc->outfd].thread = tstate; | ||
| 1345 | |||
| 1346 | return thread; | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | DEFUN ("process-thread", Fprocess_thread, Sprocess_thread, | ||
| 1350 | 1, 1, 0, | ||
| 1351 | doc: /* FIXME */) | ||
| 1352 | (Lisp_Object process) | ||
| 1353 | { | ||
| 1354 | CHECK_PROCESS (process); | ||
| 1355 | return XPROCESS (process)->thread; | ||
| 1356 | } | ||
| 1357 | |||
| 1170 | DEFUN ("set-process-window-size", Fset_process_window_size, | 1358 | DEFUN ("set-process-window-size", Fset_process_window_size, |
| 1171 | Sset_process_window_size, 3, 3, 0, | 1359 | Sset_process_window_size, 3, 3, 0, |
| 1172 | doc: /* Tell PROCESS that it has logical window size WIDTH by HEIGHT. | 1360 | doc: /* Tell PROCESS that it has logical window size WIDTH by HEIGHT. |
| @@ -1843,14 +2031,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1843 | p->pty_flag = pty_flag; | 2031 | p->pty_flag = pty_flag; |
| 1844 | pset_status (p, Qrun); | 2032 | pset_status (p, Qrun); |
| 1845 | 2033 | ||
| 1846 | if (!EQ (p->command, Qt)) | 2034 | add_process_read_fd (inchannel); |
| 1847 | { | ||
| 1848 | FD_SET (inchannel, &input_wait_mask); | ||
| 1849 | FD_SET (inchannel, &non_keyboard_wait_mask); | ||
| 1850 | } | ||
| 1851 | |||
| 1852 | if (inchannel > max_process_desc) | ||
| 1853 | max_process_desc = inchannel; | ||
| 1854 | 2035 | ||
| 1855 | /* This may signal an error. */ | 2036 | /* This may signal an error. */ |
| 1856 | setup_process_coding_systems (process); | 2037 | setup_process_coding_systems (process); |
| @@ -2084,10 +2265,7 @@ create_pty (Lisp_Object process) | |||
| 2084 | pset_status (p, Qrun); | 2265 | pset_status (p, Qrun); |
| 2085 | setup_process_coding_systems (process); | 2266 | setup_process_coding_systems (process); |
| 2086 | 2267 | ||
| 2087 | FD_SET (pty_fd, &input_wait_mask); | 2268 | add_non_keyboard_read_fd (pty_fd); |
| 2088 | FD_SET (pty_fd, &non_keyboard_wait_mask); | ||
| 2089 | if (pty_fd > max_process_desc) | ||
| 2090 | max_process_desc = pty_fd; | ||
| 2091 | 2269 | ||
| 2092 | pset_tty_name (p, build_string (pty_name)); | 2270 | pset_tty_name (p, build_string (pty_name)); |
| 2093 | } | 2271 | } |
| @@ -2171,8 +2349,8 @@ usage: (make-pipe-process &rest ARGS) */) | |||
| 2171 | p->infd = inchannel; | 2349 | p->infd = inchannel; |
| 2172 | p->outfd = outchannel; | 2350 | p->outfd = outchannel; |
| 2173 | 2351 | ||
| 2174 | if (inchannel > max_process_desc) | 2352 | if (inchannel > max_desc) |
| 2175 | max_process_desc = inchannel; | 2353 | max_desc = inchannel; |
| 2176 | 2354 | ||
| 2177 | buffer = Fplist_get (contact, QCbuffer); | 2355 | buffer = Fplist_get (contact, QCbuffer); |
| 2178 | if (NILP (buffer)) | 2356 | if (NILP (buffer)) |
| @@ -2193,10 +2371,7 @@ usage: (make-pipe-process &rest ARGS) */) | |||
| 2193 | eassert (! p->pty_flag); | 2371 | eassert (! p->pty_flag); |
| 2194 | 2372 | ||
| 2195 | if (!EQ (p->command, Qt)) | 2373 | if (!EQ (p->command, Qt)) |
| 2196 | { | 2374 | add_non_keyboard_read_fd (inchannel); |
| 2197 | FD_SET (inchannel, &input_wait_mask); | ||
| 2198 | FD_SET (inchannel, &non_keyboard_wait_mask); | ||
| 2199 | } | ||
| 2200 | p->adaptive_read_buffering | 2375 | p->adaptive_read_buffering |
| 2201 | = (NILP (Vprocess_adaptive_read_buffering) ? 0 | 2376 | = (NILP (Vprocess_adaptive_read_buffering) ? 0 |
| 2202 | : EQ (Vprocess_adaptive_read_buffering, Qt) ? 1 : 2); | 2377 | : EQ (Vprocess_adaptive_read_buffering, Qt) ? 1 : 2); |
| @@ -2909,8 +3084,8 @@ usage: (make-serial-process &rest ARGS) */) | |||
| 2909 | p->open_fd[SUBPROCESS_STDIN] = fd; | 3084 | p->open_fd[SUBPROCESS_STDIN] = fd; |
| 2910 | p->infd = fd; | 3085 | p->infd = fd; |
| 2911 | p->outfd = fd; | 3086 | p->outfd = fd; |
| 2912 | if (fd > max_process_desc) | 3087 | if (fd > max_desc) |
| 2913 | max_process_desc = fd; | 3088 | max_desc = fd; |
| 2914 | chan_process[fd] = proc; | 3089 | chan_process[fd] = proc; |
| 2915 | 3090 | ||
| 2916 | buffer = Fplist_get (contact, QCbuffer); | 3091 | buffer = Fplist_get (contact, QCbuffer); |
| @@ -2932,10 +3107,7 @@ usage: (make-serial-process &rest ARGS) */) | |||
| 2932 | eassert (! p->pty_flag); | 3107 | eassert (! p->pty_flag); |
| 2933 | 3108 | ||
| 2934 | if (!EQ (p->command, Qt)) | 3109 | if (!EQ (p->command, Qt)) |
| 2935 | { | 3110 | add_non_keyboard_read_fd (fd); |
| 2936 | FD_SET (fd, &input_wait_mask); | ||
| 2937 | FD_SET (fd, &non_keyboard_wait_mask); | ||
| 2938 | } | ||
| 2939 | 3111 | ||
| 2940 | if (BUFFERP (buffer)) | 3112 | if (BUFFERP (buffer)) |
| 2941 | { | 3113 | { |
| @@ -3417,25 +3589,18 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos, | |||
| 3417 | if (! (connecting_status (p->status) | 3589 | if (! (connecting_status (p->status) |
| 3418 | && EQ (XCDR (p->status), addrinfos))) | 3590 | && EQ (XCDR (p->status), addrinfos))) |
| 3419 | pset_status (p, Fcons (Qconnect, addrinfos)); | 3591 | pset_status (p, Fcons (Qconnect, addrinfos)); |
| 3420 | if (!FD_ISSET (inch, &connect_wait_mask)) | 3592 | if ((fd_callback_info[inch].flags & NON_BLOCKING_CONNECT_FD) == 0) |
| 3421 | { | 3593 | add_non_blocking_write_fd (inch); |
| 3422 | FD_SET (inch, &connect_wait_mask); | ||
| 3423 | FD_SET (inch, &write_mask); | ||
| 3424 | num_pending_connects++; | ||
| 3425 | } | ||
| 3426 | } | 3594 | } |
| 3427 | else | 3595 | else |
| 3428 | /* A server may have a client filter setting of Qt, but it must | 3596 | /* A server may have a client filter setting of Qt, but it must |
| 3429 | still listen for incoming connects unless it is stopped. */ | 3597 | still listen for incoming connects unless it is stopped. */ |
| 3430 | if ((!EQ (p->filter, Qt) && !EQ (p->command, Qt)) | 3598 | if ((!EQ (p->filter, Qt) && !EQ (p->command, Qt)) |
| 3431 | || (EQ (p->status, Qlisten) && NILP (p->command))) | 3599 | || (EQ (p->status, Qlisten) && NILP (p->command))) |
| 3432 | { | 3600 | add_non_keyboard_read_fd (inch); |
| 3433 | FD_SET (inch, &input_wait_mask); | ||
| 3434 | FD_SET (inch, &non_keyboard_wait_mask); | ||
| 3435 | } | ||
| 3436 | 3601 | ||
| 3437 | if (inch > max_process_desc) | 3602 | if (inch > max_desc) |
| 3438 | max_process_desc = inch; | 3603 | max_desc = inch; |
| 3439 | 3604 | ||
| 3440 | /* Set up the masks based on the process filter. */ | 3605 | /* Set up the masks based on the process filter. */ |
| 3441 | set_process_filter_masks (p); | 3606 | set_process_filter_masks (p); |
| @@ -4366,26 +4531,11 @@ deactivate_process (Lisp_Object proc) | |||
| 4366 | } | 4531 | } |
| 4367 | #endif | 4532 | #endif |
| 4368 | chan_process[inchannel] = Qnil; | 4533 | chan_process[inchannel] = Qnil; |
| 4369 | FD_CLR (inchannel, &input_wait_mask); | 4534 | delete_read_fd (inchannel); |
| 4370 | FD_CLR (inchannel, &non_keyboard_wait_mask); | 4535 | if ((fd_callback_info[inchannel].flags & NON_BLOCKING_CONNECT_FD) != 0) |
| 4371 | if (FD_ISSET (inchannel, &connect_wait_mask)) | 4536 | delete_write_fd (inchannel); |
| 4372 | { | 4537 | if (inchannel == max_desc) |
| 4373 | FD_CLR (inchannel, &connect_wait_mask); | 4538 | recompute_max_desc (); |
| 4374 | FD_CLR (inchannel, &write_mask); | ||
| 4375 | if (--num_pending_connects < 0) | ||
| 4376 | emacs_abort (); | ||
| 4377 | } | ||
| 4378 | if (inchannel == max_process_desc) | ||
| 4379 | { | ||
| 4380 | /* We just closed the highest-numbered process input descriptor, | ||
| 4381 | so recompute the highest-numbered one now. */ | ||
| 4382 | int i = inchannel; | ||
| 4383 | do | ||
| 4384 | i--; | ||
| 4385 | while (0 <= i && NILP (chan_process[i])); | ||
| 4386 | |||
| 4387 | max_process_desc = i; | ||
| 4388 | } | ||
| 4389 | } | 4539 | } |
| 4390 | } | 4540 | } |
| 4391 | 4541 | ||
| @@ -4414,7 +4564,17 @@ is nil, from any process) before the timeout expired. */) | |||
| 4414 | int nsecs; | 4564 | int nsecs; |
| 4415 | 4565 | ||
| 4416 | if (! NILP (process)) | 4566 | if (! NILP (process)) |
| 4417 | CHECK_PROCESS (process); | 4567 | { |
| 4568 | struct Lisp_Process *procp; | ||
| 4569 | |||
| 4570 | CHECK_PROCESS (process); | ||
| 4571 | procp = XPROCESS (process); | ||
| 4572 | |||
| 4573 | /* Can't wait for a process that is dedicated to a different | ||
| 4574 | thread. */ | ||
| 4575 | if (!EQ (procp->thread, Qnil) && !EQ (procp->thread, Fcurrent_thread ())) | ||
| 4576 | error ("FIXME"); | ||
| 4577 | } | ||
| 4418 | else | 4578 | else |
| 4419 | just_this_one = Qnil; | 4579 | just_this_one = Qnil; |
| 4420 | 4580 | ||
| @@ -4632,13 +4792,7 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4632 | 4792 | ||
| 4633 | /* Client processes for accepted connections are not stopped initially. */ | 4793 | /* Client processes for accepted connections are not stopped initially. */ |
| 4634 | if (!EQ (p->filter, Qt)) | 4794 | if (!EQ (p->filter, Qt)) |
| 4635 | { | 4795 | add_non_keyboard_read_fd (s); |
| 4636 | FD_SET (s, &input_wait_mask); | ||
| 4637 | FD_SET (s, &non_keyboard_wait_mask); | ||
| 4638 | } | ||
| 4639 | |||
| 4640 | if (s > max_process_desc) | ||
| 4641 | max_process_desc = s; | ||
| 4642 | 4796 | ||
| 4643 | /* Setup coding system for new process based on server process. | 4797 | /* Setup coding system for new process based on server process. |
| 4644 | This seems to be the proper thing to do, as the coding system | 4798 | This seems to be the proper thing to do, as the coding system |
| @@ -4751,20 +4905,10 @@ wait_for_tls_negotiation (Lisp_Object process) | |||
| 4751 | #endif | 4905 | #endif |
| 4752 | } | 4906 | } |
| 4753 | 4907 | ||
| 4754 | /* This variable is different from waiting_for_input in keyboard.c. | ||
| 4755 | It is used to communicate to a lisp process-filter/sentinel (via the | ||
| 4756 | function Fwaiting_for_user_input_p below) whether Emacs was waiting | ||
| 4757 | for user-input when that process-filter was called. | ||
| 4758 | waiting_for_input cannot be used as that is by definition 0 when | ||
| 4759 | lisp code is being evalled. | ||
| 4760 | This is also used in record_asynch_buffer_change. | ||
| 4761 | For that purpose, this must be 0 | ||
| 4762 | when not inside wait_reading_process_output. */ | ||
| 4763 | static int waiting_for_user_input_p; | ||
| 4764 | |||
| 4765 | static void | 4908 | static void |
| 4766 | wait_reading_process_output_unwind (int data) | 4909 | wait_reading_process_output_unwind (int data) |
| 4767 | { | 4910 | { |
| 4911 | clear_waiting_thread_info (); | ||
| 4768 | waiting_for_user_input_p = data; | 4912 | waiting_for_user_input_p = data; |
| 4769 | } | 4913 | } |
| 4770 | 4914 | ||
| @@ -4837,6 +4981,10 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4837 | /* Close to the current time if known, an invalid timespec otherwise. */ | 4981 | /* Close to the current time if known, an invalid timespec otherwise. */ |
| 4838 | struct timespec now = invalid_timespec (); | 4982 | struct timespec now = invalid_timespec (); |
| 4839 | 4983 | ||
| 4984 | eassert (wait_proc == NULL | ||
| 4985 | || EQ (wait_proc->thread, Qnil) | ||
| 4986 | || XTHREAD (wait_proc->thread) == current_thread); | ||
| 4987 | |||
| 4840 | FD_ZERO (&Available); | 4988 | FD_ZERO (&Available); |
| 4841 | FD_ZERO (&Writeok); | 4989 | FD_ZERO (&Writeok); |
| 4842 | 4990 | ||
| @@ -5009,14 +5157,14 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5009 | if (kbd_on_hold_p ()) | 5157 | if (kbd_on_hold_p ()) |
| 5010 | FD_ZERO (&Atemp); | 5158 | FD_ZERO (&Atemp); |
| 5011 | else | 5159 | else |
| 5012 | Atemp = input_wait_mask; | 5160 | compute_input_wait_mask (&Atemp); |
| 5013 | Ctemp = write_mask; | 5161 | compute_write_mask (&Ctemp); |
| 5014 | 5162 | ||
| 5015 | timeout = make_timespec (0, 0); | 5163 | timeout = make_timespec (0, 0); |
| 5016 | if ((pselect (max (max_process_desc, max_input_desc) + 1, | 5164 | if ((thread_select (pselect, max_desc + 1, |
| 5017 | &Atemp, | 5165 | &Atemp, |
| 5018 | (num_pending_connects > 0 ? &Ctemp : NULL), | 5166 | (num_pending_connects > 0 ? &Ctemp : NULL), |
| 5019 | NULL, &timeout, NULL) | 5167 | NULL, &timeout, NULL) |
| 5020 | <= 0)) | 5168 | <= 0)) |
| 5021 | { | 5169 | { |
| 5022 | /* It's okay for us to do this and then continue with | 5170 | /* It's okay for us to do this and then continue with |
| @@ -5081,17 +5229,17 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5081 | } | 5229 | } |
| 5082 | else if (!NILP (wait_for_cell)) | 5230 | else if (!NILP (wait_for_cell)) |
| 5083 | { | 5231 | { |
| 5084 | Available = non_process_wait_mask; | 5232 | compute_non_process_wait_mask (&Available); |
| 5085 | check_delay = 0; | 5233 | check_delay = 0; |
| 5086 | check_write = 0; | 5234 | check_write = 0; |
| 5087 | } | 5235 | } |
| 5088 | else | 5236 | else |
| 5089 | { | 5237 | { |
| 5090 | if (! read_kbd) | 5238 | if (! read_kbd) |
| 5091 | Available = non_keyboard_wait_mask; | 5239 | compute_non_keyboard_wait_mask (&Available); |
| 5092 | else | 5240 | else |
| 5093 | Available = input_wait_mask; | 5241 | compute_input_wait_mask (&Available); |
| 5094 | Writeok = write_mask; | 5242 | compute_write_mask (&Writeok); |
| 5095 | check_delay = wait_proc ? 0 : process_output_delay_count; | 5243 | check_delay = wait_proc ? 0 : process_output_delay_count; |
| 5096 | check_write = true; | 5244 | check_write = true; |
| 5097 | } | 5245 | } |
| @@ -5133,7 +5281,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5133 | int adaptive_nsecs = timeout.tv_nsec; | 5281 | int adaptive_nsecs = timeout.tv_nsec; |
| 5134 | if (timeout.tv_sec > 0 || adaptive_nsecs > READ_OUTPUT_DELAY_MAX) | 5282 | if (timeout.tv_sec > 0 || adaptive_nsecs > READ_OUTPUT_DELAY_MAX) |
| 5135 | adaptive_nsecs = READ_OUTPUT_DELAY_MAX; | 5283 | adaptive_nsecs = READ_OUTPUT_DELAY_MAX; |
| 5136 | for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++) | 5284 | for (channel = 0; check_delay > 0 && channel <= max_desc; channel++) |
| 5137 | { | 5285 | { |
| 5138 | proc = chan_process[channel]; | 5286 | proc = chan_process[channel]; |
| 5139 | if (NILP (proc)) | 5287 | if (NILP (proc)) |
| @@ -5192,17 +5340,18 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5192 | } | 5340 | } |
| 5193 | #endif | 5341 | #endif |
| 5194 | 5342 | ||
| 5343 | nfds = thread_select ( | ||
| 5195 | #if defined (HAVE_NS) | 5344 | #if defined (HAVE_NS) |
| 5196 | nfds = ns_select | 5345 | ns_select |
| 5197 | #elif defined (HAVE_GLIB) | 5346 | #elif defined (HAVE_GLIB) |
| 5198 | nfds = xg_select | 5347 | xg_select |
| 5199 | #else | 5348 | #else |
| 5200 | nfds = pselect | 5349 | pselect |
| 5201 | #endif | 5350 | #endif |
| 5202 | (max (max_process_desc, max_input_desc) + 1, | 5351 | , max_desc + 1, |
| 5203 | &Available, | 5352 | &Available, |
| 5204 | (check_write ? &Writeok : 0), | 5353 | (check_write ? &Writeok : 0), |
| 5205 | NULL, &timeout, NULL); | 5354 | NULL, &timeout, NULL); |
| 5206 | 5355 | ||
| 5207 | #ifdef HAVE_GNUTLS | 5356 | #ifdef HAVE_GNUTLS |
| 5208 | /* GnuTLS buffers data internally. In lowat mode it leaves | 5357 | /* GnuTLS buffers data internally. In lowat mode it leaves |
| @@ -5386,22 +5535,22 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5386 | if (no_avail || nfds == 0) | 5535 | if (no_avail || nfds == 0) |
| 5387 | continue; | 5536 | continue; |
| 5388 | 5537 | ||
| 5389 | for (channel = 0; channel <= max_input_desc; ++channel) | 5538 | for (channel = 0; channel <= max_desc; ++channel) |
| 5390 | { | 5539 | { |
| 5391 | struct fd_callback_data *d = &fd_callback_info[channel]; | 5540 | struct fd_callback_data *d = &fd_callback_info[channel]; |
| 5392 | if (d->func | 5541 | if (d->func |
| 5393 | && ((d->condition & FOR_READ | 5542 | && ((d->flags & FOR_READ |
| 5394 | && FD_ISSET (channel, &Available)) | 5543 | && FD_ISSET (channel, &Available)) |
| 5395 | || (d->condition & FOR_WRITE | 5544 | || (d->flags & FOR_WRITE |
| 5396 | && FD_ISSET (channel, &write_mask)))) | 5545 | && FD_ISSET (channel, &Writeok)))) |
| 5397 | d->func (channel, d->data); | 5546 | d->func (channel, d->data); |
| 5398 | } | 5547 | } |
| 5399 | 5548 | ||
| 5400 | for (channel = 0; channel <= max_process_desc; channel++) | 5549 | for (channel = 0; channel <= max_desc; channel++) |
| 5401 | { | 5550 | { |
| 5402 | if (FD_ISSET (channel, &Available) | 5551 | if (FD_ISSET (channel, &Available) |
| 5403 | && FD_ISSET (channel, &non_keyboard_wait_mask) | 5552 | && ((fd_callback_info[channel].flags & (KEYBOARD_FD | PROCESS_FD)) |
| 5404 | && !FD_ISSET (channel, &non_process_wait_mask)) | 5553 | == PROCESS_FD)) |
| 5405 | { | 5554 | { |
| 5406 | int nread; | 5555 | int nread; |
| 5407 | 5556 | ||
| @@ -5466,8 +5615,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5466 | 5615 | ||
| 5467 | /* Clear the descriptor now, so we only raise the | 5616 | /* Clear the descriptor now, so we only raise the |
| 5468 | signal once. */ | 5617 | signal once. */ |
| 5469 | FD_CLR (channel, &input_wait_mask); | 5618 | delete_read_fd (channel); |
| 5470 | FD_CLR (channel, &non_keyboard_wait_mask); | ||
| 5471 | 5619 | ||
| 5472 | if (p->pid == -2) | 5620 | if (p->pid == -2) |
| 5473 | { | 5621 | { |
| @@ -5506,14 +5654,12 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5506 | } | 5654 | } |
| 5507 | } | 5655 | } |
| 5508 | if (FD_ISSET (channel, &Writeok) | 5656 | if (FD_ISSET (channel, &Writeok) |
| 5509 | && FD_ISSET (channel, &connect_wait_mask)) | 5657 | && (fd_callback_info[channel].flags |
| 5658 | & NON_BLOCKING_CONNECT_FD) != 0) | ||
| 5510 | { | 5659 | { |
| 5511 | struct Lisp_Process *p; | 5660 | struct Lisp_Process *p; |
| 5512 | 5661 | ||
| 5513 | FD_CLR (channel, &connect_wait_mask); | 5662 | delete_write_fd (channel); |
| 5514 | FD_CLR (channel, &write_mask); | ||
| 5515 | if (--num_pending_connects < 0) | ||
| 5516 | emacs_abort (); | ||
| 5517 | 5663 | ||
| 5518 | proc = chan_process[channel]; | 5664 | proc = chan_process[channel]; |
| 5519 | if (NILP (proc)) | 5665 | if (NILP (proc)) |
| @@ -5581,10 +5727,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 5581 | 5727 | ||
| 5582 | if (0 <= p->infd && !EQ (p->filter, Qt) | 5728 | if (0 <= p->infd && !EQ (p->filter, Qt) |
| 5583 | && !EQ (p->command, Qt)) | 5729 | && !EQ (p->command, Qt)) |
| 5584 | { | 5730 | delete_read_fd (p->infd); |
| 5585 | FD_SET (p->infd, &input_wait_mask); | ||
| 5586 | FD_SET (p->infd, &non_keyboard_wait_mask); | ||
| 5587 | } | ||
| 5588 | } | 5731 | } |
| 5589 | } | 5732 | } |
| 5590 | } /* End for each file descriptor. */ | 5733 | } /* End for each file descriptor. */ |
| @@ -6555,10 +6698,7 @@ of incoming traffic. */) | |||
| 6555 | p = XPROCESS (process); | 6698 | p = XPROCESS (process); |
| 6556 | if (NILP (p->command) | 6699 | if (NILP (p->command) |
| 6557 | && p->infd >= 0) | 6700 | && p->infd >= 0) |
| 6558 | { | 6701 | delete_read_fd (p->infd); |
| 6559 | FD_CLR (p->infd, &input_wait_mask); | ||
| 6560 | FD_CLR (p->infd, &non_keyboard_wait_mask); | ||
| 6561 | } | ||
| 6562 | pset_command (p, Qt); | 6702 | pset_command (p, Qt); |
| 6563 | return process; | 6703 | return process; |
| 6564 | } | 6704 | } |
| @@ -6587,8 +6727,7 @@ traffic. */) | |||
| 6587 | && p->infd >= 0 | 6727 | && p->infd >= 0 |
| 6588 | && (!EQ (p->filter, Qt) || EQ (p->status, Qlisten))) | 6728 | && (!EQ (p->filter, Qt) || EQ (p->status, Qlisten))) |
| 6589 | { | 6729 | { |
| 6590 | FD_SET (p->infd, &input_wait_mask); | 6730 | add_non_keyboard_read_fd (p->infd); |
| 6591 | FD_SET (p->infd, &non_keyboard_wait_mask); | ||
| 6592 | #ifdef WINDOWSNT | 6731 | #ifdef WINDOWSNT |
| 6593 | if (fd_info[ p->infd ].flags & FILE_SERIAL) | 6732 | if (fd_info[ p->infd ].flags & FILE_SERIAL) |
| 6594 | PurgeComm (fd_info[ p->infd ].hnd, PURGE_RXABORT | PURGE_RXCLEAR); | 6733 | PurgeComm (fd_info[ p->infd ].hnd, PURGE_RXABORT | PURGE_RXCLEAR); |
| @@ -6895,10 +7034,7 @@ handle_child_signal (int sig) | |||
| 6895 | 7034 | ||
| 6896 | /* clear_desc_flag avoids a compiler bug in Microsoft C. */ | 7035 | /* clear_desc_flag avoids a compiler bug in Microsoft C. */ |
| 6897 | if (clear_desc_flag) | 7036 | if (clear_desc_flag) |
| 6898 | { | 7037 | delete_read_fd (p->infd); |
| 6899 | FD_CLR (p->infd, &input_wait_mask); | ||
| 6900 | FD_CLR (p->infd, &non_keyboard_wait_mask); | ||
| 6901 | } | ||
| 6902 | } | 7038 | } |
| 6903 | } | 7039 | } |
| 6904 | } | 7040 | } |
| @@ -7258,9 +7394,9 @@ keyboard_bit_set (fd_set *mask) | |||
| 7258 | { | 7394 | { |
| 7259 | int fd; | 7395 | int fd; |
| 7260 | 7396 | ||
| 7261 | for (fd = 0; fd <= max_input_desc; fd++) | 7397 | for (fd = 0; fd <= max_desc; fd++) |
| 7262 | if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask) | 7398 | if (FD_ISSET (fd, mask) |
| 7263 | && !FD_ISSET (fd, &non_keyboard_wait_mask)) | 7399 | && ((fd_callback_info[fd].flags & KEYBOARD_FD) != 0)) |
| 7264 | return 1; | 7400 | return 1; |
| 7265 | 7401 | ||
| 7266 | return 0; | 7402 | return 0; |
| @@ -7497,14 +7633,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 7497 | void | 7633 | void |
| 7498 | add_timer_wait_descriptor (int fd) | 7634 | add_timer_wait_descriptor (int fd) |
| 7499 | { | 7635 | { |
| 7500 | FD_SET (fd, &input_wait_mask); | 7636 | add_read_fd (fd, timerfd_callback, NULL); |
| 7501 | FD_SET (fd, &non_keyboard_wait_mask); | 7637 | if (fd > max_desc) |
| 7502 | FD_SET (fd, &non_process_wait_mask); | 7638 | max_desc = fd; |
| 7503 | fd_callback_info[fd].func = timerfd_callback; | ||
| 7504 | fd_callback_info[fd].data = NULL; | ||
| 7505 | fd_callback_info[fd].condition |= FOR_READ; | ||
| 7506 | if (fd > max_input_desc) | ||
| 7507 | max_input_desc = fd; | ||
| 7508 | } | 7639 | } |
| 7509 | 7640 | ||
| 7510 | #endif /* HAVE_TIMERFD */ | 7641 | #endif /* HAVE_TIMERFD */ |
| @@ -7528,10 +7659,10 @@ void | |||
| 7528 | add_keyboard_wait_descriptor (int desc) | 7659 | add_keyboard_wait_descriptor (int desc) |
| 7529 | { | 7660 | { |
| 7530 | #ifdef subprocesses /* Actually means "not MSDOS". */ | 7661 | #ifdef subprocesses /* Actually means "not MSDOS". */ |
| 7531 | FD_SET (desc, &input_wait_mask); | 7662 | eassert (desc >= 0 && desc < FD_SETSIZE); |
| 7532 | FD_SET (desc, &non_process_wait_mask); | 7663 | fd_callback_info[desc].flags |= FOR_READ | KEYBOARD_FD; |
| 7533 | if (desc > max_input_desc) | 7664 | if (desc > max_desc) |
| 7534 | max_input_desc = desc; | 7665 | max_desc = desc; |
| 7535 | #endif | 7666 | #endif |
| 7536 | } | 7667 | } |
| 7537 | 7668 | ||
| @@ -7541,9 +7672,15 @@ void | |||
| 7541 | delete_keyboard_wait_descriptor (int desc) | 7672 | delete_keyboard_wait_descriptor (int desc) |
| 7542 | { | 7673 | { |
| 7543 | #ifdef subprocesses | 7674 | #ifdef subprocesses |
| 7544 | FD_CLR (desc, &input_wait_mask); | 7675 | int fd; |
| 7545 | FD_CLR (desc, &non_process_wait_mask); | 7676 | int lim = max_desc; |
| 7546 | delete_input_desc (desc); | 7677 | |
| 7678 | eassert (desc >= 0 && desc < FD_SETSIZE); | ||
| 7679 | |||
| 7680 | fd_callback_info[desc].flags &= ~(FOR_READ | KEYBOARD_FD | PROCESS_FD); | ||
| 7681 | |||
| 7682 | if (desc == max_desc) | ||
| 7683 | recompute_max_desc (); | ||
| 7547 | #endif | 7684 | #endif |
| 7548 | } | 7685 | } |
| 7549 | 7686 | ||
| @@ -7824,15 +7961,10 @@ init_process_emacs (int sockfd) | |||
| 7824 | } | 7961 | } |
| 7825 | #endif | 7962 | #endif |
| 7826 | 7963 | ||
| 7827 | FD_ZERO (&input_wait_mask); | ||
| 7828 | FD_ZERO (&non_keyboard_wait_mask); | ||
| 7829 | FD_ZERO (&non_process_wait_mask); | ||
| 7830 | FD_ZERO (&write_mask); | ||
| 7831 | max_process_desc = max_input_desc = -1; | ||
| 7832 | external_sock_fd = sockfd; | 7964 | external_sock_fd = sockfd; |
| 7965 | max_desc = -1; | ||
| 7833 | memset (fd_callback_info, 0, sizeof (fd_callback_info)); | 7966 | memset (fd_callback_info, 0, sizeof (fd_callback_info)); |
| 7834 | 7967 | ||
| 7835 | FD_ZERO (&connect_wait_mask); | ||
| 7836 | num_pending_connects = 0; | 7968 | num_pending_connects = 0; |
| 7837 | 7969 | ||
| 7838 | process_output_delay_count = 0; | 7970 | process_output_delay_count = 0; |
| @@ -8032,6 +8164,8 @@ The variable takes effect when `start-process' is called. */); | |||
| 8032 | defsubr (&Sprocess_filter); | 8164 | defsubr (&Sprocess_filter); |
| 8033 | defsubr (&Sset_process_sentinel); | 8165 | defsubr (&Sset_process_sentinel); |
| 8034 | defsubr (&Sprocess_sentinel); | 8166 | defsubr (&Sprocess_sentinel); |
| 8167 | defsubr (&Sset_process_thread); | ||
| 8168 | defsubr (&Sprocess_thread); | ||
| 8035 | defsubr (&Sset_process_window_size); | 8169 | defsubr (&Sset_process_window_size); |
| 8036 | defsubr (&Sset_process_inherit_coding_system_flag); | 8170 | defsubr (&Sset_process_inherit_coding_system_flag); |
| 8037 | defsubr (&Sset_process_query_on_exit_flag); | 8171 | defsubr (&Sset_process_query_on_exit_flag); |