Mercurial > emacs
comparison src/process.c @ 9686:cd788aa8cb2a
Handle multiple keyboard input descriptors.
(non_keyboard_wait_mask): New variable.
(Fset_process_filter): Update non_keyboard_wait_mask
(create_process, Fopen_network_stream, deactivate_process):
(init_process, sigchld_handler): Likewise.
(wait_reading_process_input): Maybe use non_keyboard_wait_mask.
(add_keyboard_wait_descriptor):
Renamed from change_keyboard_wait_descriptor.
Clear the old descriptor's bit only the first call.
(delete_keyboard_wait_descriptor): New function.
(keyboard_bit_set): New function.
(wait_reading_process_input): Use keyboard_bit_set.
Start the loop over process descs from 0, and explicitly
ignore non-process input descs.
(init_process): Don't init keyboard_descriptor.
(keyboard_descriptor): Variable deleted.
(add_keyboard_wait_descriptor): Don't set keyboard_descriptor.
(delete_keyboard_wait_descriptor): New function.
| author | Richard M. Stallman <rms@gnu.org> |
|---|---|
| date | Tue, 25 Oct 1994 09:48:44 +0000 |
| parents | d949b1150e25 |
| children | 328b8bc31f73 |
comparison
equal
deleted
inserted
replaced
| 9685:ee2c6124ae92 | 9686:cd788aa8cb2a |
|---|---|
| 220 to detect C-g. It isn't actually used when doing interrupt input. */ | 220 to detect C-g. It isn't actually used when doing interrupt input. */ |
| 221 #ifdef HAVE_X_WINDOWS | 221 #ifdef HAVE_X_WINDOWS |
| 222 #define POLL_FOR_INPUT | 222 #define POLL_FOR_INPUT |
| 223 #endif | 223 #endif |
| 224 | 224 |
| 225 /* Mask of bits indicating the descriptors that we wait for input on */ | 225 /* Mask of bits indicating the descriptors that we wait for input on. */ |
| 226 | 226 |
| 227 static SELECT_TYPE input_wait_mask; | 227 static SELECT_TYPE input_wait_mask; |
| 228 | |
| 229 /* Mask that excludes keyboard input descriptor (s). */ | |
| 230 | |
| 231 static SELECT_TYPE non_keyboard_wait_mask; | |
| 228 | 232 |
| 229 /* The largest descriptor currently in use for a process object. */ | 233 /* The largest descriptor currently in use for a process object. */ |
| 230 static int max_process_desc; | 234 static int max_process_desc; |
| 231 | 235 |
| 232 /* Descriptor to use for keyboard input. */ | 236 /* The largest descriptor currently in use for keyboard input. */ |
| 233 static int keyboard_descriptor; | 237 static int max_keyboard_desc; |
| 234 | 238 |
| 235 /* Nonzero means delete a process right away if it exits. */ | 239 /* Nonzero means delete a process right away if it exits. */ |
| 236 static int delete_exited_processes; | 240 static int delete_exited_processes; |
| 237 | 241 |
| 238 /* Indexed by descriptor, gives the process (if any) for that descriptor */ | 242 /* Indexed by descriptor, gives the process (if any) for that descriptor */ |
| 762 (proc, filter) | 766 (proc, filter) |
| 763 register Lisp_Object proc, filter; | 767 register Lisp_Object proc, filter; |
| 764 { | 768 { |
| 765 CHECK_PROCESS (proc, 0); | 769 CHECK_PROCESS (proc, 0); |
| 766 if (EQ (filter, Qt)) | 770 if (EQ (filter, Qt)) |
| 767 FD_CLR (XINT (XPROCESS (proc)->infd), &input_wait_mask); | 771 { |
| 772 FD_CLR (XINT (XPROCESS (proc)->infd), &input_wait_mask); | |
| 773 FD_CLR (XINT (XPROCESS (proc)->infd), &non_keyboard_wait_mask); | |
| 774 } | |
| 768 else if (EQ (XPROCESS (proc)->filter, Qt)) | 775 else if (EQ (XPROCESS (proc)->filter, Qt)) |
| 769 FD_SET (XINT (XPROCESS (proc)->infd), &input_wait_mask); | 776 { |
| 777 FD_SET (XINT (XPROCESS (proc)->infd), &input_wait_mask); | |
| 778 FD_SET (XINT (XPROCESS (proc)->infd), &non_keyboard_wait_mask); | |
| 779 } | |
| 770 XPROCESS (proc)->filter = filter; | 780 XPROCESS (proc)->filter = filter; |
| 771 return filter; | 781 return filter; |
| 772 } | 782 } |
| 773 | 783 |
| 774 DEFUN ("process-filter", Fprocess_filter, Sprocess_filter, | 784 DEFUN ("process-filter", Fprocess_filter, Sprocess_filter, |
| 1275 #endif /* ordinary USG */ | 1285 #endif /* ordinary USG */ |
| 1276 #endif /* not BSD4_1 */ | 1286 #endif /* not BSD4_1 */ |
| 1277 #endif /* SIGCHLD */ | 1287 #endif /* SIGCHLD */ |
| 1278 | 1288 |
| 1279 FD_SET (inchannel, &input_wait_mask); | 1289 FD_SET (inchannel, &input_wait_mask); |
| 1290 FD_SET (inchannel, &non_keyboard_wait_mask); | |
| 1280 if (inchannel > max_process_desc) | 1291 if (inchannel > max_process_desc) |
| 1281 max_process_desc = inchannel; | 1292 max_process_desc = inchannel; |
| 1282 | 1293 |
| 1283 /* Until we store the proper pid, enable sigchld_handler | 1294 /* Until we store the proper pid, enable sigchld_handler |
| 1284 to recognize an unknown pid as standing for this process. | 1295 to recognize an unknown pid as standing for this process. |
| 1661 XPROCESS (proc)->pid = Qnil; | 1672 XPROCESS (proc)->pid = Qnil; |
| 1662 XSETINT (XPROCESS (proc)->infd, s); | 1673 XSETINT (XPROCESS (proc)->infd, s); |
| 1663 XSETINT (XPROCESS (proc)->outfd, outch); | 1674 XSETINT (XPROCESS (proc)->outfd, outch); |
| 1664 XPROCESS (proc)->status = Qrun; | 1675 XPROCESS (proc)->status = Qrun; |
| 1665 FD_SET (inch, &input_wait_mask); | 1676 FD_SET (inch, &input_wait_mask); |
| 1677 FD_SET (inch, &non_keyboard_wait_mask); | |
| 1666 if (inch > max_process_desc) | 1678 if (inch > max_process_desc) |
| 1667 max_process_desc = inch; | 1679 max_process_desc = inch; |
| 1668 | 1680 |
| 1669 UNGCPRO; | 1681 UNGCPRO; |
| 1670 return proc; | 1682 return proc; |
| 1700 | 1712 |
| 1701 XSETINT (p->infd, -1); | 1713 XSETINT (p->infd, -1); |
| 1702 XSETINT (p->outfd, -1); | 1714 XSETINT (p->outfd, -1); |
| 1703 chan_process[inchannel] = Qnil; | 1715 chan_process[inchannel] = Qnil; |
| 1704 FD_CLR (inchannel, &input_wait_mask); | 1716 FD_CLR (inchannel, &input_wait_mask); |
| 1717 FD_CLR (inchannel, &non_keyboard_wait_mask); | |
| 1705 if (inchannel == max_process_desc) | 1718 if (inchannel == max_process_desc) |
| 1706 { | 1719 { |
| 1707 int i; | 1720 int i; |
| 1708 /* We just closed the highest-numbered process input descriptor, | 1721 /* We just closed the highest-numbered process input descriptor, |
| 1709 so recompute the highest-numbered one now. */ | 1722 so recompute the highest-numbered one now. */ |
| 1966 break; | 1979 break; |
| 1967 } | 1980 } |
| 1968 | 1981 |
| 1969 /* Wait till there is something to do */ | 1982 /* Wait till there is something to do */ |
| 1970 | 1983 |
| 1971 Available = input_wait_mask; | |
| 1972 if (! XINT (read_kbd) && wait_for_cell == 0) | 1984 if (! XINT (read_kbd) && wait_for_cell == 0) |
| 1973 FD_CLR (keyboard_descriptor, &Available); | 1985 Available = non_keyboard_wait_mask; |
| 1986 else | |
| 1987 Available = input_wait_mask; | |
| 1974 | 1988 |
| 1975 /* If frame size has changed or the window is newly mapped, | 1989 /* If frame size has changed or the window is newly mapped, |
| 1976 redisplay now, before we start to wait. There is a race | 1990 redisplay now, before we start to wait. There is a race |
| 1977 condition here; if a SIGIO arrives between now and the select | 1991 condition here; if a SIGIO arrives between now and the select |
| 1978 and indicates that a frame is trashed, the select may block | 1992 and indicates that a frame is trashed, the select may block |
| 2034 } | 2048 } |
| 2035 else | 2049 else |
| 2036 error("select error: %s", strerror (xerrno)); | 2050 error("select error: %s", strerror (xerrno)); |
| 2037 } | 2051 } |
| 2038 #if defined(sun) && !defined(USG5_4) | 2052 #if defined(sun) && !defined(USG5_4) |
| 2039 else if (nfds > 0 && FD_ISSET (keyboard_descriptor, &Available) | 2053 else if (nfds > 0 && keyboard_bit_set (&Available) |
| 2040 && interrupt_input) | 2054 && interrupt_input) |
| 2041 /* System sometimes fails to deliver SIGIO. | 2055 /* System sometimes fails to deliver SIGIO. |
| 2042 | 2056 |
| 2043 David J. Mackenzie says that Emacs doesn't compile under | 2057 David J. Mackenzie says that Emacs doesn't compile under |
| 2044 Solaris if this code is enabled, thus the USG5_4 in the CPP | 2058 Solaris if this code is enabled, thus the USG5_4 in the CPP |
| 2071 go read it. This can happen with X on BSD after logging out. | 2085 go read it. This can happen with X on BSD after logging out. |
| 2072 In that case, there really is no input and no SIGIO, | 2086 In that case, there really is no input and no SIGIO, |
| 2073 but select says there is input. */ | 2087 but select says there is input. */ |
| 2074 | 2088 |
| 2075 if (XINT (read_kbd) && interrupt_input | 2089 if (XINT (read_kbd) && interrupt_input |
| 2076 && (FD_ISSET (keyboard_descriptor, &Available))) | 2090 && (keyboard_bit_set (&Available))) |
| 2077 kill (0, SIGIO); | 2091 kill (0, SIGIO); |
| 2078 #endif | 2092 #endif |
| 2079 | 2093 |
| 2080 if (! wait_proc) | 2094 if (! wait_proc) |
| 2081 got_some_input |= nfds > 0; | 2095 got_some_input |= nfds > 0; |
| 2086 do_pending_window_change (); | 2100 do_pending_window_change (); |
| 2087 | 2101 |
| 2088 /* Check for data from a process. */ | 2102 /* Check for data from a process. */ |
| 2089 /* Really FIRST_PROC_DESC should be 0 on Unix, | 2103 /* Really FIRST_PROC_DESC should be 0 on Unix, |
| 2090 but this is safer in the short run. */ | 2104 but this is safer in the short run. */ |
| 2091 for (channel = keyboard_descriptor == 0 ? FIRST_PROC_DESC : 0; | 2105 for (channel = 0; channel <= max_process_desc; channel++) |
| 2092 channel <= max_process_desc; channel++) | |
| 2093 { | 2106 { |
| 2094 if (FD_ISSET (channel, &Available)) | 2107 if (FD_ISSET (channel, &Available) |
| 2108 && FD_ISSET (channel, &non_keyboard_wait_mask)) | |
| 2095 { | 2109 { |
| 2096 int nread; | 2110 int nread; |
| 2097 | 2111 |
| 2098 /* If waiting for this channel, arrange to return as | 2112 /* If waiting for this channel, arrange to return as |
| 2099 soon as no more input to be processed. No more | 2113 soon as no more input to be processed. No more |
| 3056 XSETFASTINT (p->raw_status_high, u.i >> 16); | 3070 XSETFASTINT (p->raw_status_high, u.i >> 16); |
| 3057 | 3071 |
| 3058 /* If process has terminated, stop waiting for its output. */ | 3072 /* If process has terminated, stop waiting for its output. */ |
| 3059 if (WIFSIGNALED (w) || WIFEXITED (w)) | 3073 if (WIFSIGNALED (w) || WIFEXITED (w)) |
| 3060 if (XINT (p->infd) >= 0) | 3074 if (XINT (p->infd) >= 0) |
| 3061 FD_CLR (XINT (p->infd), &input_wait_mask); | 3075 { |
| 3076 FD_CLR (XINT (p->infd), &input_wait_mask); | |
| 3077 FD_CLR (XINT (p->infd), &non_keyboard_wait_mask); | |
| 3078 } | |
| 3062 | 3079 |
| 3063 /* Tell wait_reading_process_input that it needs to wake up and | 3080 /* Tell wait_reading_process_input that it needs to wake up and |
| 3064 look around. */ | 3081 look around. */ |
| 3065 if (input_available_clear_time) | 3082 if (input_available_clear_time) |
| 3066 EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); | 3083 EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); |
| 3277 update_tick = process_tick; | 3294 update_tick = process_tick; |
| 3278 | 3295 |
| 3279 UNGCPRO; | 3296 UNGCPRO; |
| 3280 } | 3297 } |
| 3281 | 3298 |
| 3299 /* The first time this is called, assume keyboard input comes from DESC | |
| 3300 instead of from where we used to expect it. | |
| 3301 Subsequent calls mean assume input keyboard can come from DESC | |
| 3302 in addition to other places. */ | |
| 3303 | |
| 3304 static int add_keyboard_wait_descriptor_called_flag; | |
| 3305 | |
| 3306 void | |
| 3307 add_keyboard_wait_descriptor (desc) | |
| 3308 int desc; | |
| 3309 { | |
| 3310 if (! add_keyboard_wait_descriptor_called_flag) | |
| 3311 FD_CLR (0, &input_wait_mask); | |
| 3312 add_keyboard_wait_descriptor_called_flag = 1; | |
| 3313 FD_SET (desc, &input_wait_mask); | |
| 3314 if (desc > max_keyboard_desc) | |
| 3315 max_keyboard_desc = desc; | |
| 3316 } | |
| 3317 | |
| 3318 /* From now on, do not expect DESC to give keyboard input. */ | |
| 3319 | |
| 3320 void | |
| 3321 delete_keyboard_wait_descriptor (desc) | |
| 3322 int desc; | |
| 3323 { | |
| 3324 int fd; | |
| 3325 int lim = max_keyboard_desc; | |
| 3326 | |
| 3327 FD_CLR (desc, &input_wait_mask); | |
| 3328 | |
| 3329 if (desc == max_keyboard_desc) | |
| 3330 for (fd = 0; fd < lim; fd++) | |
| 3331 if (FD_ISSET (fd, &input_wait_mask) | |
| 3332 && !FD_ISSET (fd, &non_keyboard_wait_mask)) | |
| 3333 max_keyboard_desc = fd; | |
| 3334 } | |
| 3335 | |
| 3336 /* Return nonzero if *MASK has a bit set | |
| 3337 that corresponds to one of the keyboard input descriptors. */ | |
| 3338 | |
| 3339 int | |
| 3340 keyboard_bit_set (mask) | |
| 3341 SELECT_TYPE *mask; | |
| 3342 { | |
| 3343 int fd; | |
| 3344 | |
| 3345 for (fd = 0; fd < max_keyboard_desc; fd++) | |
| 3346 if (FD_ISSET (fd, mask) && FD_ISSET (fd, &input_wait_mask) | |
| 3347 && !FD_ISSET (fd, &non_keyboard_wait_mask)) | |
| 3348 return 1; | |
| 3349 | |
| 3350 return 0; | |
| 3351 } | |
| 3352 | |
| 3282 init_process () | 3353 init_process () |
| 3283 { | 3354 { |
| 3284 register int i; | 3355 register int i; |
| 3285 | 3356 |
| 3286 #ifdef SIGCHLD | 3357 #ifdef SIGCHLD |
| 3289 #endif | 3360 #endif |
| 3290 signal (SIGCHLD, sigchld_handler); | 3361 signal (SIGCHLD, sigchld_handler); |
| 3291 #endif | 3362 #endif |
| 3292 | 3363 |
| 3293 FD_ZERO (&input_wait_mask); | 3364 FD_ZERO (&input_wait_mask); |
| 3365 FD_ZERO (&non_keyboard_wait_mask); | |
| 3294 max_process_desc = 0; | 3366 max_process_desc = 0; |
| 3295 | 3367 |
| 3296 keyboard_descriptor = 0; | 3368 FD_SET (0, &input_wait_mask); |
| 3297 FD_SET (keyboard_descriptor, &input_wait_mask); | |
| 3298 | 3369 |
| 3299 Vprocess_alist = Qnil; | 3370 Vprocess_alist = Qnil; |
| 3300 for (i = 0; i < MAXDESC; i++) | 3371 for (i = 0; i < MAXDESC; i++) |
| 3301 { | 3372 { |
| 3302 chan_process[i] = Qnil; | 3373 chan_process[i] = Qnil; |
| 3303 proc_buffered_char[i] = -1; | 3374 proc_buffered_char[i] = -1; |
| 3304 } | 3375 } |
| 3305 } | |
| 3306 | |
| 3307 /* From now on, assume keyboard input comes from descriptor DESC. */ | |
| 3308 | |
| 3309 void | |
| 3310 change_keyboard_wait_descriptor (desc) | |
| 3311 int desc; | |
| 3312 { | |
| 3313 FD_CLR (keyboard_descriptor, &input_wait_mask); | |
| 3314 keyboard_descriptor = desc; | |
| 3315 FD_SET (keyboard_descriptor, &input_wait_mask); | |
| 3316 } | 3376 } |
| 3317 | 3377 |
| 3318 syms_of_process () | 3378 syms_of_process () |
| 3319 { | 3379 { |
| 3320 #ifdef HAVE_SOCKETS | 3380 #ifdef HAVE_SOCKETS |
