diff options
| author | Tom Tromey | 2012-08-15 13:17:37 -0600 |
|---|---|---|
| committer | Tom Tromey | 2012-08-15 13:17:37 -0600 |
| commit | aa14ccd1e2edec2735f9200a4f2e5eee3b0abe09 (patch) | |
| tree | bec288e2f78e2965dfa533136ec7d369e3d97db7 /src/process.c | |
| parent | 0ccc5d8998a62c3e137f798e1e2b7f8362f12a85 (diff) | |
| download | emacs-aa14ccd1e2edec2735f9200a4f2e5eee3b0abe09.tar.gz emacs-aa14ccd1e2edec2735f9200a4f2e5eee3b0abe09.zip | |
Prepare process.c for threads by not having global select masks.
The next step is to make it so selects can choose fds by thread.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 295 |
1 files changed, 165 insertions, 130 deletions
diff --git a/src/process.c b/src/process.c index 2a61b6da777..0d3355512b8 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -267,29 +267,7 @@ static void create_pty (Lisp_Object); | |||
| 267 | static Lisp_Object get_process (register Lisp_Object name); | 267 | static Lisp_Object get_process (register Lisp_Object name); |
| 268 | static void exec_sentinel (Lisp_Object proc, Lisp_Object reason); | 268 | static void exec_sentinel (Lisp_Object proc, Lisp_Object reason); |
| 269 | 269 | ||
| 270 | /* Mask of bits indicating the descriptors that we wait for input on. */ | ||
| 271 | |||
| 272 | static SELECT_TYPE input_wait_mask; | ||
| 273 | |||
| 274 | /* Mask that excludes keyboard input descriptor(s). */ | ||
| 275 | |||
| 276 | static SELECT_TYPE non_keyboard_wait_mask; | ||
| 277 | |||
| 278 | /* Mask that excludes process input descriptor(s). */ | ||
| 279 | |||
| 280 | static SELECT_TYPE non_process_wait_mask; | ||
| 281 | |||
| 282 | /* Mask for selecting for write. */ | ||
| 283 | |||
| 284 | static SELECT_TYPE write_mask; | ||
| 285 | |||
| 286 | #ifdef NON_BLOCKING_CONNECT | 270 | #ifdef NON_BLOCKING_CONNECT |
| 287 | /* Mask of bits indicating the descriptors that we wait for connect to | ||
| 288 | complete on. Once they complete, they are removed from this mask | ||
| 289 | and added to the input_wait_mask and non_keyboard_wait_mask. */ | ||
| 290 | |||
| 291 | static SELECT_TYPE connect_wait_mask; | ||
| 292 | |||
| 293 | /* Number of bits set in connect_wait_mask. */ | 271 | /* Number of bits set in connect_wait_mask. */ |
| 294 | static int num_pending_connects; | 272 | static int num_pending_connects; |
| 295 | #endif /* NON_BLOCKING_CONNECT */ | 273 | #endif /* NON_BLOCKING_CONNECT */ |
| @@ -336,13 +314,27 @@ static int pty_max_bytes; | |||
| 336 | 314 | ||
| 337 | 315 | ||
| 338 | 316 | ||
| 317 | enum fd_bits | ||
| 318 | { | ||
| 319 | /* Read from file descriptor. */ | ||
| 320 | FOR_READ = 1, | ||
| 321 | /* Write to file descriptor. */ | ||
| 322 | FOR_WRITE = 2, | ||
| 323 | /* This descriptor refers to a keyboard. Only valid if FOR_READ is | ||
| 324 | set. */ | ||
| 325 | KEYBOARD_FD = 4, | ||
| 326 | /* This descriptor refers to a process. */ | ||
| 327 | PROCESS_FD = 8, | ||
| 328 | /* A non-blocking connect. Only valid if FOR_WRITE is set. */ | ||
| 329 | NON_BLOCKING_CONNECT_FD = 16 | ||
| 330 | }; | ||
| 331 | |||
| 339 | static struct fd_callback_data | 332 | static struct fd_callback_data |
| 340 | { | 333 | { |
| 341 | fd_callback func; | 334 | fd_callback func; |
| 342 | void *data; | 335 | void *data; |
| 343 | #define FOR_READ 1 | 336 | /* Flags from enum fd_bits. */ |
| 344 | #define FOR_WRITE 2 | 337 | int flags; |
| 345 | int condition; /* mask of the defines above. */ | ||
| 346 | } fd_callback_info[MAXDESC]; | 338 | } fd_callback_info[MAXDESC]; |
| 347 | 339 | ||
| 348 | 340 | ||
| @@ -357,7 +349,23 @@ add_read_fd (int fd, fd_callback func, void *data) | |||
| 357 | 349 | ||
| 358 | fd_callback_info[fd].func = func; | 350 | fd_callback_info[fd].func = func; |
| 359 | fd_callback_info[fd].data = data; | 351 | fd_callback_info[fd].data = data; |
| 360 | fd_callback_info[fd].condition |= FOR_READ; | 352 | } |
| 353 | |||
| 354 | void | ||
| 355 | add_non_keyboard_read_fd (int fd) | ||
| 356 | { | ||
| 357 | eassert (fd >= 0 && fd < MAXDESC); | ||
| 358 | eassert (fd_callback_info[fd].func == NULL); | ||
| 359 | fd_callback_info[fd].flags |= FOR_READ; | ||
| 360 | if (fd > max_input_desc) | ||
| 361 | max_input_desc = fd; | ||
| 362 | } | ||
| 363 | |||
| 364 | void | ||
| 365 | add_process_read_fd (int fd) | ||
| 366 | { | ||
| 367 | add_non_keyboard_read_fd (fd); | ||
| 368 | fd_callback_info[fd].flags |= PROCESS_FD; | ||
| 361 | } | 369 | } |
| 362 | 370 | ||
| 363 | /* Stop monitoring file descriptor FD for when read is possible. */ | 371 | /* Stop monitoring file descriptor FD for when read is possible. */ |
| @@ -368,8 +376,7 @@ delete_read_fd (int fd) | |||
| 368 | eassert (fd < MAXDESC); | 376 | eassert (fd < MAXDESC); |
| 369 | delete_keyboard_wait_descriptor (fd); | 377 | delete_keyboard_wait_descriptor (fd); |
| 370 | 378 | ||
| 371 | fd_callback_info[fd].condition &= ~FOR_READ; | 379 | if (fd_callback_info[fd].flags == 0) |
| 372 | if (fd_callback_info[fd].condition == 0) | ||
| 373 | { | 380 | { |
| 374 | fd_callback_info[fd].func = 0; | 381 | fd_callback_info[fd].func = 0; |
| 375 | fd_callback_info[fd].data = 0; | 382 | fd_callback_info[fd].data = 0; |
| @@ -383,13 +390,24 @@ void | |||
| 383 | add_write_fd (int fd, fd_callback func, void *data) | 390 | add_write_fd (int fd, fd_callback func, void *data) |
| 384 | { | 391 | { |
| 385 | eassert (fd < MAXDESC); | 392 | eassert (fd < MAXDESC); |
| 386 | FD_SET (fd, &write_mask); | ||
| 387 | if (fd > max_input_desc) | 393 | if (fd > max_input_desc) |
| 388 | max_input_desc = fd; | 394 | max_input_desc = fd; |
| 389 | 395 | ||
| 390 | fd_callback_info[fd].func = func; | 396 | fd_callback_info[fd].func = func; |
| 391 | fd_callback_info[fd].data = data; | 397 | fd_callback_info[fd].data = data; |
| 392 | fd_callback_info[fd].condition |= FOR_WRITE; | 398 | fd_callback_info[fd].flags |= FOR_WRITE; |
| 399 | } | ||
| 400 | |||
| 401 | void | ||
| 402 | add_non_blocking_write_fd (int fd) | ||
| 403 | { | ||
| 404 | eassert (fd >= 0 && fd < MAXDESC); | ||
| 405 | eassert (fd_callback_info[fd].func == NULL); | ||
| 406 | |||
| 407 | fd_callback_info[fd].flags |= FOR_WRITE | NON_BLOCKING_CONNECT_FD; | ||
| 408 | if (fd > max_input_desc) | ||
| 409 | max_input_desc = fd; | ||
| 410 | ++num_pending_connects; | ||
| 393 | } | 411 | } |
| 394 | 412 | ||
| 395 | /* Stop monitoring file descriptor FD for when write is possible. */ | 413 | /* Stop monitoring file descriptor FD for when write is possible. */ |
| @@ -400,24 +418,87 @@ delete_write_fd (int fd) | |||
| 400 | int lim = max_input_desc; | 418 | int lim = max_input_desc; |
| 401 | 419 | ||
| 402 | eassert (fd < MAXDESC); | 420 | eassert (fd < MAXDESC); |
| 403 | FD_CLR (fd, &write_mask); | 421 | if ((fd_callback_info[fd].flags & NON_BLOCKING_CONNECT_FD) != 0) |
| 404 | fd_callback_info[fd].condition &= ~FOR_WRITE; | 422 | { |
| 405 | if (fd_callback_info[fd].condition == 0) | 423 | if (--num_pending_connects < 0) |
| 424 | abort (); | ||
| 425 | } | ||
| 426 | fd_callback_info[fd].flags &= ~(FOR_WRITE | NON_BLOCKING_CONNECT_FD); | ||
| 427 | if (fd_callback_info[fd].flags == 0) | ||
| 406 | { | 428 | { |
| 407 | fd_callback_info[fd].func = 0; | 429 | fd_callback_info[fd].func = 0; |
| 408 | fd_callback_info[fd].data = 0; | 430 | fd_callback_info[fd].data = 0; |
| 409 | 431 | ||
| 410 | if (fd == max_input_desc) | 432 | if (fd == max_input_desc) |
| 411 | for (fd = lim; fd >= 0; fd--) | 433 | { |
| 412 | if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask)) | 434 | for (fd = max_input_desc; fd >= 0; --fd) |
| 413 | { | 435 | { |
| 414 | max_input_desc = fd; | 436 | if (fd_callback_info[fd].flags != 0) |
| 415 | break; | 437 | { |
| 416 | } | 438 | max_input_desc = fd; |
| 439 | break; | ||
| 440 | } | ||
| 441 | } | ||
| 442 | } | ||
| 443 | } | ||
| 444 | } | ||
| 445 | |||
| 446 | static void | ||
| 447 | compute_input_wait_mask (SELECT_TYPE *mask) | ||
| 448 | { | ||
| 449 | int fd; | ||
| 417 | 450 | ||
| 451 | FD_ZERO (mask); | ||
| 452 | for (fd = 0; fd < max (max_process_desc, max_input_desc); ++fd) | ||
| 453 | { | ||
| 454 | if ((fd_callback_info[fd].flags & FOR_READ) != 0) | ||
| 455 | FD_SET (fd, mask); | ||
| 418 | } | 456 | } |
| 419 | } | 457 | } |
| 420 | 458 | ||
| 459 | static void | ||
| 460 | compute_non_process_wait_mask (SELECT_TYPE *mask) | ||
| 461 | { | ||
| 462 | int fd; | ||
| 463 | |||
| 464 | FD_ZERO (mask); | ||
| 465 | for (fd = 0; fd < max (max_process_desc, max_input_desc); ++fd) | ||
| 466 | { | ||
| 467 | if ((fd_callback_info[fd].flags & FOR_READ) != 0 | ||
| 468 | && (fd_callback_info[fd].flags & PROCESS_FD) == 0) | ||
| 469 | FD_SET (fd, mask); | ||
| 470 | } | ||
| 471 | } | ||
| 472 | |||
| 473 | static void | ||
| 474 | compute_non_keyboard_wait_mask (SELECT_TYPE *mask) | ||
| 475 | { | ||
| 476 | int fd; | ||
| 477 | |||
| 478 | FD_ZERO (mask); | ||
| 479 | for (fd = 0; fd < max (max_process_desc, max_input_desc); ++fd) | ||
| 480 | { | ||
| 481 | if ((fd_callback_info[fd].flags & FOR_READ) != 0 | ||
| 482 | && (fd_callback_info[fd].flags & KEYBOARD_FD) == 0) | ||
| 483 | FD_SET (fd, mask); | ||
| 484 | } | ||
| 485 | } | ||
| 486 | |||
| 487 | static void | ||
| 488 | compute_write_mask (SELECT_TYPE *mask) | ||
| 489 | { | ||
| 490 | int fd; | ||
| 491 | |||
| 492 | FD_ZERO (mask); | ||
| 493 | for (fd = 0; fd < max (max_process_desc, max_input_desc); ++fd) | ||
| 494 | { | ||
| 495 | if ((fd_callback_info[fd].flags & FOR_WRITE) != 0) | ||
| 496 | FD_SET (fd, mask); | ||
| 497 | } | ||
| 498 | } | ||
| 499 | |||
| 500 | |||
| 501 | |||
| 421 | 502 | ||
| 422 | /* Compute the Lisp form of the process status, p->status, from | 503 | /* Compute the Lisp form of the process status, p->status, from |
| 423 | the numeric status that was returned by `wait'. */ | 504 | the numeric status that was returned by `wait'. */ |
| @@ -961,17 +1042,11 @@ The string argument is normally a multibyte string, except: | |||
| 961 | if (p->infd >= 0) | 1042 | if (p->infd >= 0) |
| 962 | { | 1043 | { |
| 963 | if (EQ (filter, Qt) && !EQ (p->status, Qlisten)) | 1044 | if (EQ (filter, Qt) && !EQ (p->status, Qlisten)) |
| 964 | { | 1045 | delete_read_fd (p->infd); |
| 965 | FD_CLR (p->infd, &input_wait_mask); | ||
| 966 | FD_CLR (p->infd, &non_keyboard_wait_mask); | ||
| 967 | } | ||
| 968 | else if (EQ (p->filter, Qt) | 1046 | else if (EQ (p->filter, Qt) |
| 969 | /* Network or serial process not stopped: */ | 1047 | /* Network or serial process not stopped: */ |
| 970 | && !EQ (p->command, Qt)) | 1048 | && !EQ (p->command, Qt)) |
| 971 | { | 1049 | delete_read_fd (p->infd); |
| 972 | FD_SET (p->infd, &input_wait_mask); | ||
| 973 | FD_SET (p->infd, &non_keyboard_wait_mask); | ||
| 974 | } | ||
| 975 | } | 1050 | } |
| 976 | 1051 | ||
| 977 | PSET (p, filter, filter); | 1052 | PSET (p, filter, filter); |
| @@ -1650,10 +1725,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir) | |||
| 1650 | #endif /* HAVE_WORKING_VFORK */ | 1725 | #endif /* HAVE_WORKING_VFORK */ |
| 1651 | pthread_sigmask (SIG_BLOCK, &blocked, &procmask); | 1726 | pthread_sigmask (SIG_BLOCK, &blocked, &procmask); |
| 1652 | 1727 | ||
| 1653 | FD_SET (inchannel, &input_wait_mask); | 1728 | add_non_keyboard_read_fd (inchannel); |
| 1654 | FD_SET (inchannel, &non_keyboard_wait_mask); | ||
| 1655 | if (inchannel > max_process_desc) | ||
| 1656 | max_process_desc = inchannel; | ||
| 1657 | 1729 | ||
| 1658 | /* Until we store the proper pid, enable sigchld_handler | 1730 | /* Until we store the proper pid, enable sigchld_handler |
| 1659 | to recognize an unknown pid as standing for this process. | 1731 | to recognize an unknown pid as standing for this process. |
| @@ -1968,10 +2040,7 @@ create_pty (Lisp_Object process) | |||
| 1968 | PSET (XPROCESS (process), status, Qrun); | 2040 | PSET (XPROCESS (process), status, Qrun); |
| 1969 | setup_process_coding_systems (process); | 2041 | setup_process_coding_systems (process); |
| 1970 | 2042 | ||
| 1971 | FD_SET (inchannel, &input_wait_mask); | 2043 | add_non_keyboard_read_fd (inchannel); |
| 1972 | FD_SET (inchannel, &non_keyboard_wait_mask); | ||
| 1973 | if (inchannel > max_process_desc) | ||
| 1974 | max_process_desc = inchannel; | ||
| 1975 | 2044 | ||
| 1976 | XPROCESS (process)->pid = -2; | 2045 | XPROCESS (process)->pid = -2; |
| 1977 | #ifdef HAVE_PTYS | 2046 | #ifdef HAVE_PTYS |
| @@ -2616,10 +2685,7 @@ usage: (make-serial-process &rest ARGS) */) | |||
| 2616 | p->pty_flag = 0; | 2685 | p->pty_flag = 0; |
| 2617 | 2686 | ||
| 2618 | if (!EQ (p->command, Qt)) | 2687 | if (!EQ (p->command, Qt)) |
| 2619 | { | 2688 | add_non_keyboard_read_fd (fd); |
| 2620 | FD_SET (fd, &input_wait_mask); | ||
| 2621 | FD_SET (fd, &non_keyboard_wait_mask); | ||
| 2622 | } | ||
| 2623 | 2689 | ||
| 2624 | if (BUFFERP (buffer)) | 2690 | if (BUFFERP (buffer)) |
| 2625 | { | 2691 | { |
| @@ -3431,12 +3497,8 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3431 | in that case, we still need to signal this like a non-blocking | 3497 | in that case, we still need to signal this like a non-blocking |
| 3432 | connection. */ | 3498 | connection. */ |
| 3433 | PSET (p, status, Qconnect); | 3499 | PSET (p, status, Qconnect); |
| 3434 | if (!FD_ISSET (inch, &connect_wait_mask)) | 3500 | if ((fd_callback_info[inch].flags & NON_BLOCKING_CONNECT_FD) == 0) |
| 3435 | { | 3501 | add_non_blocking_write_fd (inch); |
| 3436 | FD_SET (inch, &connect_wait_mask); | ||
| 3437 | FD_SET (inch, &write_mask); | ||
| 3438 | num_pending_connects++; | ||
| 3439 | } | ||
| 3440 | } | 3502 | } |
| 3441 | else | 3503 | else |
| 3442 | #endif | 3504 | #endif |
| @@ -3444,10 +3506,7 @@ usage: (make-network-process &rest ARGS) */) | |||
| 3444 | still listen for incoming connects unless it is stopped. */ | 3506 | still listen for incoming connects unless it is stopped. */ |
| 3445 | if ((!EQ (p->filter, Qt) && !EQ (p->command, Qt)) | 3507 | if ((!EQ (p->filter, Qt) && !EQ (p->command, Qt)) |
| 3446 | || (EQ (p->status, Qlisten) && NILP (p->command))) | 3508 | || (EQ (p->status, Qlisten) && NILP (p->command))) |
| 3447 | { | 3509 | add_non_keyboard_read_fd (inch); |
| 3448 | FD_SET (inch, &input_wait_mask); | ||
| 3449 | FD_SET (inch, &non_keyboard_wait_mask); | ||
| 3450 | } | ||
| 3451 | 3510 | ||
| 3452 | if (inch > max_process_desc) | 3511 | if (inch > max_process_desc) |
| 3453 | max_process_desc = inch; | 3512 | max_process_desc = inch; |
| @@ -3892,16 +3951,10 @@ deactivate_process (Lisp_Object proc) | |||
| 3892 | } | 3951 | } |
| 3893 | #endif | 3952 | #endif |
| 3894 | chan_process[inchannel] = Qnil; | 3953 | chan_process[inchannel] = Qnil; |
| 3895 | FD_CLR (inchannel, &input_wait_mask); | 3954 | delete_read_fd (inchannel); |
| 3896 | FD_CLR (inchannel, &non_keyboard_wait_mask); | ||
| 3897 | #ifdef NON_BLOCKING_CONNECT | 3955 | #ifdef NON_BLOCKING_CONNECT |
| 3898 | if (FD_ISSET (inchannel, &connect_wait_mask)) | 3956 | if ((fd_callback_info[inchannel].flags & NON_BLOCKING_CONNECT_FD) != 0) |
| 3899 | { | 3957 | delete_write_fd (inchannel); |
| 3900 | FD_CLR (inchannel, &connect_wait_mask); | ||
| 3901 | FD_CLR (inchannel, &write_mask); | ||
| 3902 | if (--num_pending_connects < 0) | ||
| 3903 | abort (); | ||
| 3904 | } | ||
| 3905 | #endif | 3958 | #endif |
| 3906 | if (inchannel == max_process_desc) | 3959 | if (inchannel == max_process_desc) |
| 3907 | { | 3960 | { |
| @@ -4165,13 +4218,7 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4165 | 4218 | ||
| 4166 | /* Client processes for accepted connections are not stopped initially. */ | 4219 | /* Client processes for accepted connections are not stopped initially. */ |
| 4167 | if (!EQ (p->filter, Qt)) | 4220 | if (!EQ (p->filter, Qt)) |
| 4168 | { | 4221 | add_non_keyboard_read_fd (s); |
| 4169 | FD_SET (s, &input_wait_mask); | ||
| 4170 | FD_SET (s, &non_keyboard_wait_mask); | ||
| 4171 | } | ||
| 4172 | |||
| 4173 | if (s > max_process_desc) | ||
| 4174 | max_process_desc = s; | ||
| 4175 | 4222 | ||
| 4176 | /* Setup coding system for new process based on server process. | 4223 | /* Setup coding system for new process based on server process. |
| 4177 | This seems to be the proper thing to do, as the coding system | 4224 | This seems to be the proper thing to do, as the coding system |
| @@ -4433,8 +4480,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4433 | if (kbd_on_hold_p ()) | 4480 | if (kbd_on_hold_p ()) |
| 4434 | FD_ZERO (&Atemp); | 4481 | FD_ZERO (&Atemp); |
| 4435 | else | 4482 | else |
| 4436 | Atemp = input_wait_mask; | 4483 | compute_input_wait_mask (&Atemp); |
| 4437 | Ctemp = write_mask; | 4484 | compute_write_mask (&Ctemp); |
| 4438 | 4485 | ||
| 4439 | timeout = make_emacs_time (0, 0); | 4486 | timeout = make_emacs_time (0, 0); |
| 4440 | if ((pselect (max (max_process_desc, max_input_desc) + 1, | 4487 | if ((pselect (max (max_process_desc, max_input_desc) + 1, |
| @@ -4512,17 +4559,17 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4512 | } | 4559 | } |
| 4513 | else if (!NILP (wait_for_cell)) | 4560 | else if (!NILP (wait_for_cell)) |
| 4514 | { | 4561 | { |
| 4515 | Available = non_process_wait_mask; | 4562 | compute_non_process_wait_mask (&Available); |
| 4516 | check_delay = 0; | 4563 | check_delay = 0; |
| 4517 | check_write = 0; | 4564 | check_write = 0; |
| 4518 | } | 4565 | } |
| 4519 | else | 4566 | else |
| 4520 | { | 4567 | { |
| 4521 | if (! read_kbd) | 4568 | if (! read_kbd) |
| 4522 | Available = non_keyboard_wait_mask; | 4569 | compute_non_keyboard_wait_mask (&Available); |
| 4523 | else | 4570 | else |
| 4524 | Available = input_wait_mask; | 4571 | compute_input_wait_mask (&Available); |
| 4525 | Writeok = write_mask; | 4572 | compute_write_mask (&Writeok); |
| 4526 | #ifdef SELECT_CANT_DO_WRITE_MASK | 4573 | #ifdef SELECT_CANT_DO_WRITE_MASK |
| 4527 | check_write = 0; | 4574 | check_write = 0; |
| 4528 | #else | 4575 | #else |
| @@ -4790,19 +4837,19 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4790 | struct fd_callback_data *d = &fd_callback_info[channel]; | 4837 | struct fd_callback_data *d = &fd_callback_info[channel]; |
| 4791 | if (FD_ISSET (channel, &Available) | 4838 | if (FD_ISSET (channel, &Available) |
| 4792 | && d->func != 0 | 4839 | && d->func != 0 |
| 4793 | && (d->condition & FOR_READ) != 0) | 4840 | && (d->flags & FOR_READ) != 0) |
| 4794 | d->func (channel, d->data, 1); | 4841 | d->func (channel, d->data, 1); |
| 4795 | if (FD_ISSET (channel, &Writeok) | 4842 | if (FD_ISSET (channel, &Writeok) |
| 4796 | && d->func != 0 | 4843 | && d->func != 0 |
| 4797 | && (d->condition & FOR_WRITE) != 0) | 4844 | && (d->flags & FOR_WRITE) != 0) |
| 4798 | d->func (channel, d->data, 0); | 4845 | d->func (channel, d->data, 0); |
| 4799 | } | 4846 | } |
| 4800 | 4847 | ||
| 4801 | for (channel = 0; channel <= max_process_desc; channel++) | 4848 | for (channel = 0; channel <= max_process_desc; channel++) |
| 4802 | { | 4849 | { |
| 4803 | if (FD_ISSET (channel, &Available) | 4850 | if (FD_ISSET (channel, &Available) |
| 4804 | && FD_ISSET (channel, &non_keyboard_wait_mask) | 4851 | && ((fd_callback_info[channel].flags & (KEYBOARD_FD | PROCESS_FD)) |
| 4805 | && !FD_ISSET (channel, &non_process_wait_mask)) | 4852 | == PROCESS_FD)) |
| 4806 | { | 4853 | { |
| 4807 | int nread; | 4854 | int nread; |
| 4808 | 4855 | ||
| @@ -4880,8 +4927,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4880 | 4927 | ||
| 4881 | /* Clear the descriptor now, so we only raise the | 4928 | /* Clear the descriptor now, so we only raise the |
| 4882 | signal once. */ | 4929 | signal once. */ |
| 4883 | FD_CLR (channel, &input_wait_mask); | 4930 | delete_read_fd (channel); |
| 4884 | FD_CLR (channel, &non_keyboard_wait_mask); | ||
| 4885 | 4931 | ||
| 4886 | if (p->pid == -2) | 4932 | if (p->pid == -2) |
| 4887 | { | 4933 | { |
| @@ -4915,14 +4961,12 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4915 | } | 4961 | } |
| 4916 | #ifdef NON_BLOCKING_CONNECT | 4962 | #ifdef NON_BLOCKING_CONNECT |
| 4917 | if (FD_ISSET (channel, &Writeok) | 4963 | if (FD_ISSET (channel, &Writeok) |
| 4918 | && FD_ISSET (channel, &connect_wait_mask)) | 4964 | && (fd_callback_info[channel].flags |
| 4965 | & NON_BLOCKING_CONNECT_FD) != 0) | ||
| 4919 | { | 4966 | { |
| 4920 | struct Lisp_Process *p; | 4967 | struct Lisp_Process *p; |
| 4921 | 4968 | ||
| 4922 | FD_CLR (channel, &connect_wait_mask); | 4969 | delete_write_fd (channel); |
| 4923 | FD_CLR (channel, &write_mask); | ||
| 4924 | if (--num_pending_connects < 0) | ||
| 4925 | abort (); | ||
| 4926 | 4970 | ||
| 4927 | proc = chan_process[channel]; | 4971 | proc = chan_process[channel]; |
| 4928 | if (NILP (proc)) | 4972 | if (NILP (proc)) |
| @@ -4970,10 +5014,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, | |||
| 4970 | from the process before calling the sentinel. */ | 5014 | from the process before calling the sentinel. */ |
| 4971 | exec_sentinel (proc, build_string ("open\n")); | 5015 | exec_sentinel (proc, build_string ("open\n")); |
| 4972 | if (!EQ (p->filter, Qt) && !EQ (p->command, Qt)) | 5016 | if (!EQ (p->filter, Qt) && !EQ (p->command, Qt)) |
| 4973 | { | 5017 | delete_read_fd (p->infd); |
| 4974 | FD_SET (p->infd, &input_wait_mask); | ||
| 4975 | FD_SET (p->infd, &non_keyboard_wait_mask); | ||
| 4976 | } | ||
| 4977 | } | 5018 | } |
| 4978 | } | 5019 | } |
| 4979 | #endif /* NON_BLOCKING_CONNECT */ | 5020 | #endif /* NON_BLOCKING_CONNECT */ |
| @@ -6014,10 +6055,7 @@ traffic. */) | |||
| 6014 | p = XPROCESS (process); | 6055 | p = XPROCESS (process); |
| 6015 | if (NILP (p->command) | 6056 | if (NILP (p->command) |
| 6016 | && p->infd >= 0) | 6057 | && p->infd >= 0) |
| 6017 | { | 6058 | delete_read_fd (p->infd); |
| 6018 | FD_CLR (p->infd, &input_wait_mask); | ||
| 6019 | FD_CLR (p->infd, &non_keyboard_wait_mask); | ||
| 6020 | } | ||
| 6021 | PSET (p, command, Qt); | 6059 | PSET (p, command, Qt); |
| 6022 | return process; | 6060 | return process; |
| 6023 | } | 6061 | } |
| @@ -6045,8 +6083,7 @@ traffic. */) | |||
| 6045 | && p->infd >= 0 | 6083 | && p->infd >= 0 |
| 6046 | && (!EQ (p->filter, Qt) || EQ (p->status, Qlisten))) | 6084 | && (!EQ (p->filter, Qt) || EQ (p->status, Qlisten))) |
| 6047 | { | 6085 | { |
| 6048 | FD_SET (p->infd, &input_wait_mask); | 6086 | add_non_keyboard_read_fd (p->infd); |
| 6049 | FD_SET (p->infd, &non_keyboard_wait_mask); | ||
| 6050 | #ifdef WINDOWSNT | 6087 | #ifdef WINDOWSNT |
| 6051 | if (fd_info[ p->infd ].flags & FILE_SERIAL) | 6088 | if (fd_info[ p->infd ].flags & FILE_SERIAL) |
| 6052 | PurgeComm (fd_info[ p->infd ].hnd, PURGE_RXABORT | PURGE_RXCLEAR); | 6089 | PurgeComm (fd_info[ p->infd ].hnd, PURGE_RXABORT | PURGE_RXCLEAR); |
| @@ -6419,10 +6456,7 @@ sigchld_handler (int signo) | |||
| 6419 | 6456 | ||
| 6420 | /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ | 6457 | /* We use clear_desc_flag to avoid a compiler bug in Microsoft C. */ |
| 6421 | if (clear_desc_flag) | 6458 | if (clear_desc_flag) |
| 6422 | { | 6459 | delete_read_fd (p->infd); |
| 6423 | FD_CLR (p->infd, &input_wait_mask); | ||
| 6424 | FD_CLR (p->infd, &non_keyboard_wait_mask); | ||
| 6425 | } | ||
| 6426 | 6460 | ||
| 6427 | /* Tell wait_reading_process_output that it needs to wake up and | 6461 | /* Tell wait_reading_process_output that it needs to wake up and |
| 6428 | look around. */ | 6462 | look around. */ |
| @@ -6796,8 +6830,8 @@ keyboard_bit_set (fd_set *mask) | |||
| 6796 | int fd; | 6830 | int fd; |
| 6797 | 6831 | ||
| 6798 | for (fd = 0; fd <= max_input_desc; fd++) | 6832 | for (fd = 0; fd <= max_input_desc; fd++) |
| 6799 | if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask) | 6833 | if (FD_ISSET (fd, mask) |
| 6800 | && !FD_ISSET (fd, &non_keyboard_wait_mask)) | 6834 | && ((fd_callback_info[fd].flags & KEYBOARD_FD) != 0)) |
| 6801 | return 1; | 6835 | return 1; |
| 6802 | 6836 | ||
| 6803 | return 0; | 6837 | return 0; |
| @@ -7042,8 +7076,8 @@ void | |||
| 7042 | add_keyboard_wait_descriptor (int desc) | 7076 | add_keyboard_wait_descriptor (int desc) |
| 7043 | { | 7077 | { |
| 7044 | #ifdef subprocesses /* actually means "not MSDOS" */ | 7078 | #ifdef subprocesses /* actually means "not MSDOS" */ |
| 7045 | FD_SET (desc, &input_wait_mask); | 7079 | eassert (desc >= 0 && desc < MAXDESC); |
| 7046 | FD_SET (desc, &non_process_wait_mask); | 7080 | fd_callback_info[desc].flags |= FOR_READ | KEYBOARD_FD; |
| 7047 | if (desc > max_input_desc) | 7081 | if (desc > max_input_desc) |
| 7048 | max_input_desc = desc; | 7082 | max_input_desc = desc; |
| 7049 | #endif | 7083 | #endif |
| @@ -7058,13 +7092,19 @@ delete_keyboard_wait_descriptor (int desc) | |||
| 7058 | int fd; | 7092 | int fd; |
| 7059 | int lim = max_input_desc; | 7093 | int lim = max_input_desc; |
| 7060 | 7094 | ||
| 7061 | FD_CLR (desc, &input_wait_mask); | 7095 | fd_callback_info[desc].flags &= ~(FOR_READ | KEYBOARD_FD | PROCESS_FD); |
| 7062 | FD_CLR (desc, &non_process_wait_mask); | ||
| 7063 | 7096 | ||
| 7064 | if (desc == max_input_desc) | 7097 | if (desc == max_input_desc) |
| 7065 | for (fd = 0; fd < lim; fd++) | 7098 | { |
| 7066 | if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask)) | 7099 | for (fd = max_input_desc; fd >= 0; --fd) |
| 7067 | max_input_desc = fd; | 7100 | { |
| 7101 | if (fd_callback_info[desc].flags != 0) | ||
| 7102 | { | ||
| 7103 | max_input_desc = fd; | ||
| 7104 | break; | ||
| 7105 | } | ||
| 7106 | } | ||
| 7107 | } | ||
| 7068 | #endif | 7108 | #endif |
| 7069 | } | 7109 | } |
| 7070 | 7110 | ||
| @@ -7320,15 +7360,10 @@ init_process_emacs (void) | |||
| 7320 | signal (SIGCHLD, sigchld_handler); | 7360 | signal (SIGCHLD, sigchld_handler); |
| 7321 | #endif | 7361 | #endif |
| 7322 | 7362 | ||
| 7323 | FD_ZERO (&input_wait_mask); | ||
| 7324 | FD_ZERO (&non_keyboard_wait_mask); | ||
| 7325 | FD_ZERO (&non_process_wait_mask); | ||
| 7326 | FD_ZERO (&write_mask); | ||
| 7327 | max_process_desc = 0; | 7363 | max_process_desc = 0; |
| 7328 | memset (fd_callback_info, 0, sizeof (fd_callback_info)); | 7364 | memset (fd_callback_info, 0, sizeof (fd_callback_info)); |
| 7329 | 7365 | ||
| 7330 | #ifdef NON_BLOCKING_CONNECT | 7366 | #ifdef NON_BLOCKING_CONNECT |
| 7331 | FD_ZERO (&connect_wait_mask); | ||
| 7332 | num_pending_connects = 0; | 7367 | num_pending_connects = 0; |
| 7333 | #endif | 7368 | #endif |
| 7334 | 7369 | ||