diff options
| author | Jan D | 2010-07-07 19:39:49 +0200 |
|---|---|---|
| committer | Jan D | 2010-07-07 19:39:49 +0200 |
| commit | cb768704a459ab54632daf5bb1a10127a6a5c9f7 (patch) | |
| tree | f4f9018ea6563a1eee13550f9a8bc89731f0ad25 /src | |
| parent | 3a8ce8225692c705bb0dde88acb62bda6e688158 (diff) | |
| download | emacs-cb768704a459ab54632daf5bb1a10127a6a5c9f7.tar.gz emacs-cb768704a459ab54632daf5bb1a10127a6a5c9f7.zip | |
If kbd_buffer is becoming full, stop reading until it drains (Bug#6571).
* keyboard.c (input_available_signal): Declare.
(kbd_buffer_nr_stored): New function.
(kbd_buffer_store_event_hold): If kbd_buffer_nr_stored returns
more than KBD_BUFFER_SIZE/2, stop reding input (Bug#6571).
(kbd_buffer_get_event): If input is suspended and kbd_buffer_nr_stored
returns less than KBD_BUFFER_SIZE/4, resume reding input (Bug#6571).
(tty_read_avail_input): If input is on hold, return.
Don't read more that free slots in kbd_buffer (Bug#6571).
* process.h (hold_keyboard_input, unhold_keyboard_input)
(kbd_on_hold_p): Declare.
* process.c (kbd_is_on_hold): New variable.
(hold_keyboard_input, unhold_keyboard_input, kbd_on_hold_p): New
functions.
(wait_reading_process_output): If kbd_on_hold_p returns non-zero,
select on empty input mask.
(init_process): Initialize kbd_is_on_hold to 0.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 21 | ||||
| -rw-r--r-- | src/keyboard.c | 48 | ||||
| -rw-r--r-- | src/process.c | 34 | ||||
| -rw-r--r-- | src/process.h | 4 |
4 files changed, 105 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 63b0dd0a53d..912a5a8d2f2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,24 @@ | |||
| 1 | 2010-07-07 Jan Djärv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * process.c (kbd_is_on_hold): New variable. | ||
| 4 | (hold_keyboard_input, unhold_keyboard_input, kbd_on_hold_p): New | ||
| 5 | functions. | ||
| 6 | (wait_reading_process_output): If kbd_on_hold_p returns non-zero, | ||
| 7 | select on empty input mask. | ||
| 8 | (init_process): Initialize kbd_is_on_hold to 0. | ||
| 9 | |||
| 10 | * process.h (hold_keyboard_input, unhold_keyboard_input) | ||
| 11 | (kbd_on_hold_p): Declare. | ||
| 12 | |||
| 13 | * keyboard.c (input_available_signal): Declare. | ||
| 14 | (kbd_buffer_nr_stored): New function. | ||
| 15 | (kbd_buffer_store_event_hold): If kbd_buffer_nr_stored returns | ||
| 16 | more than KBD_BUFFER_SIZE/2, stop reding input (Bug#6571). | ||
| 17 | (kbd_buffer_get_event): If input is suspended and kbd_buffer_nr_stored | ||
| 18 | returns less than KBD_BUFFER_SIZE/4, resume reding input (Bug#6571). | ||
| 19 | (tty_read_avail_input): If input is on hold, return. | ||
| 20 | Don't read more that free slots in kbd_buffer (Bug#6571). | ||
| 21 | |||
| 1 | 2010-07-07 Eli Zaretskii <eliz@gnu.org> | 22 | 2010-07-07 Eli Zaretskii <eliz@gnu.org> |
| 2 | 23 | ||
| 3 | * msdos.h: | 24 | * msdos.h: |
diff --git a/src/keyboard.c b/src/keyboard.c index 2cf7a7b24a6..c7d3ee413cd 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -635,6 +635,7 @@ static Lisp_Object apply_modifiers (int, Lisp_Object); | |||
| 635 | static void clear_event (struct input_event *); | 635 | static void clear_event (struct input_event *); |
| 636 | static Lisp_Object restore_kboard_configuration (Lisp_Object); | 636 | static Lisp_Object restore_kboard_configuration (Lisp_Object); |
| 637 | static SIGTYPE interrupt_signal (int signalnum); | 637 | static SIGTYPE interrupt_signal (int signalnum); |
| 638 | static SIGTYPE input_available_signal (int signo); | ||
| 638 | static void handle_interrupt (void); | 639 | static void handle_interrupt (void); |
| 639 | static void timer_start_idle (void); | 640 | static void timer_start_idle (void); |
| 640 | static void timer_stop_idle (void); | 641 | static void timer_stop_idle (void); |
| @@ -3590,6 +3591,18 @@ event_to_kboard (struct input_event *event) | |||
| 3590 | return FRAME_KBOARD (XFRAME (frame)); | 3591 | return FRAME_KBOARD (XFRAME (frame)); |
| 3591 | } | 3592 | } |
| 3592 | 3593 | ||
| 3594 | /* Return the number of slots occupied in kbd_buffer. */ | ||
| 3595 | |||
| 3596 | static int | ||
| 3597 | kbd_buffer_nr_stored () | ||
| 3598 | { | ||
| 3599 | return kbd_fetch_ptr == kbd_store_ptr | ||
| 3600 | ? 0 | ||
| 3601 | : (kbd_fetch_ptr < kbd_store_ptr | ||
| 3602 | ? kbd_store_ptr - kbd_fetch_ptr | ||
| 3603 | : ((kbd_buffer + KBD_BUFFER_SIZE) - kbd_fetch_ptr | ||
| 3604 | + (kbd_store_ptr - kbd_buffer))); | ||
| 3605 | } | ||
| 3593 | 3606 | ||
| 3594 | Lisp_Object Vthrow_on_input; | 3607 | Lisp_Object Vthrow_on_input; |
| 3595 | 3608 | ||
| @@ -3711,6 +3724,17 @@ kbd_buffer_store_event_hold (register struct input_event *event, | |||
| 3711 | { | 3724 | { |
| 3712 | *kbd_store_ptr = *event; | 3725 | *kbd_store_ptr = *event; |
| 3713 | ++kbd_store_ptr; | 3726 | ++kbd_store_ptr; |
| 3727 | if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE/2 && ! kbd_on_hold_p ()) | ||
| 3728 | { | ||
| 3729 | /* Don't read keyboard input until we have processed kbd_buffer. | ||
| 3730 | This happens when pasting text longer than KBD_BUFFER_SIZE/2. */ | ||
| 3731 | hold_keyboard_input (); | ||
| 3732 | #ifdef SIGIO | ||
| 3733 | if (!noninteractive) | ||
| 3734 | signal (SIGIO, SIG_IGN); | ||
| 3735 | #endif | ||
| 3736 | stop_polling (); | ||
| 3737 | } | ||
| 3714 | } | 3738 | } |
| 3715 | 3739 | ||
| 3716 | /* If we're inside while-no-input, and this event qualifies | 3740 | /* If we're inside while-no-input, and this event qualifies |
| @@ -3866,10 +3890,24 @@ clear_event (struct input_event *event) | |||
| 3866 | We always read and discard one event. */ | 3890 | We always read and discard one event. */ |
| 3867 | 3891 | ||
| 3868 | static Lisp_Object | 3892 | static Lisp_Object |
| 3869 | kbd_buffer_get_event (KBOARD **kbp, int *used_mouse_menu, struct timeval *end_time) | 3893 | kbd_buffer_get_event (KBOARD **kbp, |
| 3894 | int *used_mouse_menu, | ||
| 3895 | struct timeval *end_time) | ||
| 3870 | { | 3896 | { |
| 3871 | register int c; | 3897 | register int c; |
| 3872 | Lisp_Object obj; | 3898 | Lisp_Object obj; |
| 3899 | |||
| 3900 | if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE/4) | ||
| 3901 | { | ||
| 3902 | /* Start reading input again, we have processed enough so we can | ||
| 3903 | accept new events again. */ | ||
| 3904 | unhold_keyboard_input (); | ||
| 3905 | #ifdef SIGIO | ||
| 3906 | if (!noninteractive) | ||
| 3907 | signal (SIGIO, input_available_signal); | ||
| 3908 | #endif /* SIGIO */ | ||
| 3909 | start_polling (); | ||
| 3910 | } | ||
| 3873 | 3911 | ||
| 3874 | if (noninteractive | 3912 | if (noninteractive |
| 3875 | /* In case we are running as a daemon, only do this before | 3913 | /* In case we are running as a daemon, only do this before |
| @@ -7039,6 +7077,10 @@ tty_read_avail_input (struct terminal *terminal, | |||
| 7039 | int n_to_read, i; | 7077 | int n_to_read, i; |
| 7040 | struct tty_display_info *tty = terminal->display_info.tty; | 7078 | struct tty_display_info *tty = terminal->display_info.tty; |
| 7041 | int nread = 0; | 7079 | int nread = 0; |
| 7080 | int buffer_free = KBD_BUFFER_SIZE - kbd_buffer_nr_stored () - 1; | ||
| 7081 | |||
| 7082 | if (kbd_on_hold_p () || buffer_free <= 0) | ||
| 7083 | return 0; | ||
| 7042 | 7084 | ||
| 7043 | if (!terminal->name) /* Don't read from a dead terminal. */ | 7085 | if (!terminal->name) /* Don't read from a dead terminal. */ |
| 7044 | return 0; | 7086 | return 0; |
| @@ -7120,6 +7162,10 @@ tty_read_avail_input (struct terminal *terminal, | |||
| 7120 | #endif | 7162 | #endif |
| 7121 | #endif | 7163 | #endif |
| 7122 | 7164 | ||
| 7165 | /* Don't read more than we can store. */ | ||
| 7166 | if (n_to_read > buffer_free) | ||
| 7167 | n_to_read = buffer_free; | ||
| 7168 | |||
| 7123 | /* Now read; for one reason or another, this will not block. | 7169 | /* Now read; for one reason or another, this will not block. |
| 7124 | NREAD is set to the number of chars read. */ | 7170 | NREAD is set to the number of chars read. */ |
| 7125 | do | 7171 | do |
diff --git a/src/process.c b/src/process.c index 0807a0e17cb..c7460d81255 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -306,6 +306,10 @@ extern int timers_run; | |||
| 306 | 306 | ||
| 307 | static SELECT_TYPE input_wait_mask; | 307 | static SELECT_TYPE input_wait_mask; |
| 308 | 308 | ||
| 309 | /* Non-zero if keyboard input is on hold, zero otherwise. */ | ||
| 310 | |||
| 311 | static int kbd_is_on_hold; | ||
| 312 | |||
| 309 | /* Mask that excludes keyboard input descriptor(s). */ | 313 | /* Mask that excludes keyboard input descriptor(s). */ |
| 310 | 314 | ||
| 311 | static SELECT_TYPE non_keyboard_wait_mask; | 315 | static SELECT_TYPE non_keyboard_wait_mask; |
| @@ -4731,7 +4735,10 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display, | |||
| 4731 | SELECT_TYPE Ctemp; | 4735 | SELECT_TYPE Ctemp; |
| 4732 | #endif | 4736 | #endif |
| 4733 | 4737 | ||
| 4734 | Atemp = input_wait_mask; | 4738 | if (kbd_on_hold_p ()) |
| 4739 | FD_ZERO (&Atemp); | ||
| 4740 | else | ||
| 4741 | Atemp = input_wait_mask; | ||
| 4735 | IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask); | 4742 | IF_NON_BLOCKING_CONNECT (Ctemp = connect_wait_mask); |
| 4736 | 4743 | ||
| 4737 | EMACS_SET_SECS_USECS (timeout, 0, 0); | 4744 | EMACS_SET_SECS_USECS (timeout, 0, 0); |
| @@ -7010,6 +7017,30 @@ DEFUN ("process-filter-multibyte-p", Fprocess_filter_multibyte_p, | |||
| 7010 | 7017 | ||
| 7011 | 7018 | ||
| 7012 | 7019 | ||
| 7020 | /* Stop reading input from keyboard sources. */ | ||
| 7021 | |||
| 7022 | void | ||
| 7023 | hold_keyboard_input (void) | ||
| 7024 | { | ||
| 7025 | kbd_is_on_hold = 1; | ||
| 7026 | } | ||
| 7027 | |||
| 7028 | /* Resume reading input from keyboard sources. */ | ||
| 7029 | |||
| 7030 | void | ||
| 7031 | unhold_keyboard_input (void) | ||
| 7032 | { | ||
| 7033 | kbd_is_on_hold = 0; | ||
| 7034 | } | ||
| 7035 | |||
| 7036 | /* Return non-zero if keyboard input is on hold, zero otherwise. */ | ||
| 7037 | |||
| 7038 | int | ||
| 7039 | kbd_on_hold_p (void) | ||
| 7040 | { | ||
| 7041 | return kbd_is_on_hold; | ||
| 7042 | } | ||
| 7043 | |||
| 7013 | /* Add DESC to the set of keyboard input descriptors. */ | 7044 | /* Add DESC to the set of keyboard input descriptors. */ |
| 7014 | 7045 | ||
| 7015 | void | 7046 | void |
| @@ -7901,6 +7932,7 @@ integer or floating point values. | |||
| 7901 | void | 7932 | void |
| 7902 | init_process () | 7933 | init_process () |
| 7903 | { | 7934 | { |
| 7935 | kbd_is_on_hold = 0; | ||
| 7904 | } | 7936 | } |
| 7905 | 7937 | ||
| 7906 | void | 7938 | void |
diff --git a/src/process.h b/src/process.h index a8cd0a02da6..12b91d697b9 100644 --- a/src/process.h +++ b/src/process.h | |||
| @@ -170,5 +170,9 @@ extern Lisp_Object Qtime, Qctime; | |||
| 170 | extern Lisp_Object list_system_processes (void); | 170 | extern Lisp_Object list_system_processes (void); |
| 171 | extern Lisp_Object system_process_attributes (Lisp_Object); | 171 | extern Lisp_Object system_process_attributes (Lisp_Object); |
| 172 | 172 | ||
| 173 | extern void hold_keyboard_input (void); | ||
| 174 | extern void unhold_keyboard_input (void); | ||
| 175 | extern int kbd_on_hold_p (void); | ||
| 176 | |||
| 173 | /* arch-tag: dffedfc4-d7bc-4b58-a26f-c16155449c72 | 177 | /* arch-tag: dffedfc4-d7bc-4b58-a26f-c16155449c72 |
| 174 | (do not change this comment) */ | 178 | (do not change this comment) */ |