From: Takashi Yano <takashi.yano@nifty.ne.jp>
To: cygwin-patches@cygwin.com
Subject: [PATCH] Cygwin: console: Prevent the order of typeahead input from swapped.
Date: Sat, 26 Feb 2022 19:36:16 +0900 [thread overview]
Message-ID: <20220226103616.1517-1-takashi.yano@nifty.ne.jp> (raw)
- If a lot of keys are typed very quickly in the app which does
not read console, the order of input keys in console input buffer
occasionally swapped. Although this extremely rarely happens,
is obviously a bug of cons_master_thread. This patch fixes the
issue.
---
winsup/cygwin/fhandler_console.cc | 53 +++++++++++++++++++++++++++++--
1 file changed, 51 insertions(+), 2 deletions(-)
diff --git a/winsup/cygwin/fhandler_console.cc b/winsup/cygwin/fhandler_console.cc
index aa0f26450..88c0f894b 100644
--- a/winsup/cygwin/fhandler_console.cc
+++ b/winsup/cygwin/fhandler_console.cc
@@ -208,6 +208,20 @@ fhandler_console::cons_master_thread (handle_set_t *p, tty *ttyp)
case WAIT_OBJECT_0:
ReadConsoleInputW (p->input_handle,
input_rec, INREC_SIZE, &total_read);
+ if (total_read == INREC_SIZE /* Working space full */
+ && cygwait (p->input_handle, (DWORD) 0) == WAIT_OBJECT_0)
+ {
+ const int incr = 1;
+ size_t bytes = sizeof (INPUT_RECORD) * (total_read - incr);
+ /* Discard oldest incr events. */
+ memmove (input_rec, input_rec + incr, bytes);
+ total_read -= incr;
+ processed_up_to =
+ (processed_up_to + 1 >= incr) ? processed_up_to - incr : -1;
+ ReadConsoleInputW (p->input_handle,
+ input_rec + total_read, incr, &n);
+ total_read += n;
+ }
break;
case WAIT_TIMEOUT:
processed_up_to = -1;
@@ -291,8 +305,43 @@ remove_record:
}
processed_up_to = total_read - 1;
if (total_read)
- /* Writeback input records other than interrupt. */
- WriteConsoleInputW (p->input_handle, input_rec, total_read, &n);
+ {
+ /* Writeback input records other than interrupt. */
+ WriteConsoleInputW (p->input_handle, input_rec, total_read, &n);
+ size_t bytes = sizeof (INPUT_RECORD) * total_read;
+ do
+ {
+ const int additional_size = 128; /* Possible max number of
+ incoming events during
+ above process. */
+ const int new_size = INREC_SIZE + additional_size;
+ INPUT_RECORD tmp[new_size];
+ /* Check if writeback was successfull. */
+ PeekConsoleInputW (p->input_handle, tmp, new_size, &n);
+ if (memcmp (input_rec, tmp, bytes) == 0)
+ break; /* OK */
+ /* Try to fix */
+ DWORD incr = n - total_read;
+ DWORD ofst;
+ for (ofst = 1; ofst <= incr; ofst++)
+ if (memcmp (input_rec, tmp + ofst, bytes) == 0)
+ {
+ ReadConsoleInputW (p->input_handle, tmp, new_size, &n);
+ DWORD m;
+ WriteConsoleInputW (p->input_handle, tmp + ofst,
+ total_read, &m);
+ WriteConsoleInputW (p->input_handle, tmp, ofst, &m);
+ if ( n > ofst + total_read)
+ WriteConsoleInputW (p->input_handle,
+ tmp + ofst + total_read,
+ n - (ofst + total_read), &m);
+ break;
+ }
+ if (ofst > incr) /* Hard to fix */
+ break; /* Giving up */
+ }
+ while (true);
+ }
skip_writeback:
ReleaseMutex (p->input_mutex);
cygwait (40);
--
2.35.1
reply other threads:[~2022-02-26 10:36 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220226103616.1517-1-takashi.yano@nifty.ne.jp \
--to=takashi.yano@nifty.ne.jp \
--cc=cygwin-patches@cygwin.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).