From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7868) id 6508F3858401; Sat, 26 Feb 2022 10:52:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6508F3858401 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Takashi Yano To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/cygwin-3_3-branch] Cygwin: console: Prevent the order of typeahead input from swapped. X-Act-Checkin: newlib-cygwin X-Git-Author: Takashi Yano X-Git-Refname: refs/heads/cygwin-3_3-branch X-Git-Oldrev: d5e5babda58c43de89ac06adccdd72cd24485068 X-Git-Newrev: e2cf0e645ecfa02dc216b8eb0ec00c86a0e4c685 Message-Id: <20220226105233.6508F3858401@sourceware.org> Date: Sat, 26 Feb 2022 10:52:33 +0000 (GMT) X-BeenThere: cygwin-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 26 Feb 2022 10:52:33 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3De2cf0e645ec= fa02dc216b8eb0ec00c86a0e4c685 commit e2cf0e645ecfa02dc216b8eb0ec00c86a0e4c685 Author: Takashi Yano Date: Fri Feb 25 17:10:03 2022 +0900 Cygwin: console: Prevent the order of typeahead input from swapped. =20 - 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. Diff: --- 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_con= sole.cc index c6c42b6a7..5552db685 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 =3D=3D INREC_SIZE /* Working space full */ + && cygwait (p->input_handle, (DWORD) 0) =3D=3D WAIT_OBJECT_0) + { + const int incr =3D 1; + size_t bytes =3D sizeof (INPUT_RECORD) * (total_read - incr); + /* Discard oldest incr events. */ + memmove (input_rec, input_rec + incr, bytes); + total_read -=3D incr; + processed_up_to =3D + (processed_up_to + 1 >=3D incr) ? processed_up_to - incr : -1; + ReadConsoleInputW (p->input_handle, + input_rec + total_read, incr, &n); + total_read +=3D n; + } break; case WAIT_TIMEOUT: processed_up_to =3D -1; @@ -290,8 +304,43 @@ remove_record: } processed_up_to =3D 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 =3D sizeof (INPUT_RECORD) * total_read; + do + { + const int additional_size =3D 128; /* Possible max number of + incoming events during + above process. */ + const int new_size =3D 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) =3D=3D 0) + break; /* OK */ + /* Try to fix */ + DWORD incr =3D n - total_read; + DWORD ofst; + for (ofst =3D 1; ofst <=3D incr; ofst++) + if (memcmp (input_rec, tmp + ofst, bytes) =3D=3D 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);