Skip to content

Commit 1e8cf1a

Browse files
committed
Merge branch 'backports-from-cygwin-3_5-branch'
This includes the pull request #72 from dscho/restore-pipes-blocking-mode, and adds two more backported patches. Signed-off-by: Johannes Schindelin <[email protected]>
2 parents faebbcd + 9d0d6e1 commit 1e8cf1a

File tree

5 files changed

+62
-10
lines changed

5 files changed

+62
-10
lines changed

winsup/cygwin/fhandler/console.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ fhandler_console::set_input_mode (tty::cons_mode m, const termios *t,
818818
GetConsoleMode (p->input_handle, &oflags);
819819
DWORD flags = oflags
820820
& (ENABLE_EXTENDED_FLAGS | ENABLE_INSERT_MODE | ENABLE_QUICK_EDIT_MODE);
821+
con.curr_input_mode = m;
821822
switch (m)
822823
{
823824
case tty::restore:
@@ -867,6 +868,7 @@ fhandler_console::set_output_mode (tty::cons_mode m, const termios *t,
867868
if (con.orig_virtual_terminal_processing_mode)
868869
flags |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
869870
WaitForSingleObject (p->output_mutex, mutex_timeout);
871+
con.curr_output_mode = m;
870872
switch (m)
871873
{
872874
case tty::restore:
@@ -1109,12 +1111,12 @@ fhandler_console::bg_check (int sig, bool dontsignal)
11091111
/* Setting-up console mode for cygwin app. This is necessary if the
11101112
cygwin app and other non-cygwin apps are started simultaneously
11111113
in the same process group. */
1112-
if (sig == SIGTTIN)
1114+
if (sig == SIGTTIN && con.curr_input_mode != tty::cygwin)
11131115
{
11141116
set_input_mode (tty::cygwin, &tc ()->ti, get_handle_set ());
11151117
set_disable_master_thread (false, this);
11161118
}
1117-
if (sig == SIGTTOU)
1119+
if (sig == SIGTTOU && con.curr_output_mode != tty::cygwin)
11181120
set_output_mode (tty::cygwin, &tc ()->ti, get_handle_set ());
11191121

11201122
return fhandler_termios::bg_check (sig, dontsignal);
@@ -2921,6 +2923,8 @@ fhandler_console::char_command (char c)
29212923
}
29222924
if (con.args[i] == 1) /* DECCKM */
29232925
con.cursor_key_app_mode = (c == 'h');
2926+
if (con.args[i] == 9001) /* win32-input-mode (https://github.com/microsoft/terminal/blob/main/doc/specs/%234999%20-%20Improved%20keyboard%20handling%20in%20Conpty.md) */
2927+
set_disable_master_thread (c == 'h', this);
29242928
}
29252929
/* Call fix_tab_position() if screen has been alternated. */
29262930
if (need_fix_tab_position)

winsup/cygwin/fhandler/pipe.cc

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ fhandler_pipe::set_pipe_non_blocking (bool nonblocking)
5454
NTSTATUS status;
5555
IO_STATUS_BLOCK io;
5656
FILE_PIPE_INFORMATION fpi;
57+
bool was_blocking_read_pipe_new = was_blocking_read_pipe;
58+
59+
if (get_device () == FH_PIPER && nonblocking && !was_blocking_read_pipe)
60+
{
61+
status = NtQueryInformationFile (get_handle (), &io, &fpi, sizeof fpi,
62+
FilePipeInformation);
63+
if (NT_SUCCESS (status))
64+
was_blocking_read_pipe_new =
65+
(fpi.CompletionMode == FILE_PIPE_QUEUE_OPERATION);
66+
}
5767

5868
fpi.ReadMode = FILE_PIPE_BYTE_STREAM_MODE;
5969
fpi.CompletionMode = nonblocking ? FILE_PIPE_COMPLETE_OPERATION
@@ -62,6 +72,11 @@ fhandler_pipe::set_pipe_non_blocking (bool nonblocking)
6272
FilePipeInformation);
6373
if (!NT_SUCCESS (status))
6474
debug_printf ("NtSetInformationFile(FilePipeInformation): %y", status);
75+
else
76+
{
77+
was_blocking_read_pipe = was_blocking_read_pipe_new;
78+
is_blocking_read_pipe = !nonblocking;
79+
}
6580
}
6681

6782
int
@@ -95,6 +110,8 @@ fhandler_pipe::init (HANDLE f, DWORD a, mode_t mode, int64_t uniq_id)
95110
even with FILE_SYNCHRONOUS_IO_NONALERT. */
96111
set_pipe_non_blocking (get_device () == FH_PIPER ?
97112
true : is_nonblocking ());
113+
was_blocking_read_pipe = false;
114+
98115
return 1;
99116
}
100117

@@ -289,6 +306,9 @@ fhandler_pipe::raw_read (void *ptr, size_t& len)
289306
if (!len)
290307
return;
291308

309+
if (is_blocking_read_pipe)
310+
set_pipe_non_blocking (true);
311+
292312
DWORD timeout = is_nonblocking () ? 0 : INFINITE;
293313
DWORD waitret = cygwait (read_mtx, timeout);
294314
switch (waitret)
@@ -721,6 +741,8 @@ fhandler_pipe::close ()
721741
CloseHandle (query_hdl);
722742
if (query_hdl_close_req_evt)
723743
CloseHandle (query_hdl_close_req_evt);
744+
if (was_blocking_read_pipe)
745+
set_pipe_non_blocking (false);
724746
int ret = fhandler_base::close ();
725747
ReleaseMutex (hdl_cnt_mtx);
726748
CloseHandle (hdl_cnt_mtx);
@@ -1377,6 +1399,7 @@ fhandler_pipe::spawn_worker (int fileno_stdin, int fileno_stdout,
13771399
{
13781400
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
13791401
pipe->set_pipe_non_blocking (false);
1402+
need_send_noncygchld_sig = true;
13801403
}
13811404

13821405
/* If multiple writers including non-cygwin app exist, the non-cygwin
@@ -1402,3 +1425,21 @@ fhandler_pipe::spawn_worker (int fileno_stdin, int fileno_stdout,
14021425
t->kill_pgrp (__SIGNONCYGCHLD);
14031426
}
14041427
}
1428+
1429+
void
1430+
fhandler_pipe::sigproc_worker (void)
1431+
{
1432+
cygheap_fdenum cfd (false);
1433+
while (cfd.next () >= 0)
1434+
if (cfd->get_dev () == FH_PIPEW)
1435+
{
1436+
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
1437+
if (pipe->need_close_query_hdl ())
1438+
pipe->close_query_handle ();
1439+
}
1440+
else if (cfd->get_dev () == FH_PIPER)
1441+
{
1442+
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
1443+
pipe->is_blocking_read_pipe = true;
1444+
}
1445+
}

winsup/cygwin/local_includes/fhandler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,6 +1197,8 @@ class fhandler_pipe: public fhandler_pipe_fifo
11971197
private:
11981198
HANDLE read_mtx;
11991199
pid_t popen_pid;
1200+
bool was_blocking_read_pipe;
1201+
bool is_blocking_read_pipe;
12001202
HANDLE query_hdl;
12011203
HANDLE hdl_cnt_mtx;
12021204
HANDLE query_hdl_proc;
@@ -1287,6 +1289,7 @@ class fhandler_pipe: public fhandler_pipe_fifo
12871289
}
12881290
static void spawn_worker (int fileno_stdin, int fileno_stdout,
12891291
int fileno_stderr);
1292+
static void sigproc_worker (void);
12901293
};
12911294

12921295
#define CYGWIN_FIFO_PIPE_NAME_LEN 47
@@ -2160,6 +2163,8 @@ class dev_console
21602163
char *cons_rapoi;
21612164
bool cursor_key_app_mode;
21622165
bool disable_master_thread;
2166+
tty::cons_mode curr_input_mode;
2167+
tty::cons_mode curr_output_mode;
21632168
bool master_thread_suspended;
21642169
int num_processed; /* Number of input events in the current input buffer
21652170
already processed by cons_master_thread(). */

winsup/cygwin/release/3.5.5

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Fixes:
2+
------
3+
4+
- Fix undesired behaviour of console master thread in win32-input-mode
5+
which is supported by Windows Termainal.
6+
Addresses: https://cygwin.com/pipermail/cygwin/2024-August/256380.html
7+
8+
- Fix a regression in 3.5.4 that writing to pipe extremely slows down.
9+
Addresses: https://cygwin.com/pipermail/cygwin/2024-August/256398.html

winsup/cygwin/sigproc.cc

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,14 +1475,7 @@ wait_sig (VOID *)
14751475
}
14761476
break;
14771477
case __SIGNONCYGCHLD:
1478-
cygheap_fdenum cfd (false);
1479-
while (cfd.next () >= 0)
1480-
if (cfd->get_dev () == FH_PIPEW)
1481-
{
1482-
fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
1483-
if (pipe->need_close_query_hdl ())
1484-
pipe->close_query_handle ();
1485-
}
1478+
fhandler_pipe::sigproc_worker ();
14861479
break;
14871480
}
14881481
if (clearwait && !have_execed)

0 commit comments

Comments
 (0)