[PATCH] Cygwin: select: Speed up select() call for pty, pipe and fifo.

Takashi Yano takashi.yano@nifty.ne.jp
Mon Jan 6 14:38:00 GMT 2020


- The slowing down issue of X11 forwarding using ssh -Y, reported
  in https://www.cygwin.com/ml/cygwin/2019-12/msg00295.html,
  is due to the change of select() code for pty in the commit
  915fcd0ae8d83546ce135131cd25bf6795d97966. cygthread::detach()
  takes at most about 10msec because Sleep() is used in the thread.
  For this issue, this patch uses cygwait() instead of Sleep() and
  introduces an event to abort the wait. For not only pty, but pipe
  and fifo also have the same problem potentially, so this patch
  applies same strategy to them as well.
---
 winsup/cygwin/select.cc | 15 ++++++++++++---
 winsup/cygwin/select.h  |  1 +
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index e7014422b..b3aedf20f 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -744,7 +744,7 @@ thread_pipe (void *arg)
 	  }
       if (!looping)
 	break;
-      Sleep (sleep_time >> 3);
+      cygwait (pi->bye, sleep_time >> 3);
       if (sleep_time < 80)
 	++sleep_time;
       if (pi->stop_thread)
@@ -763,6 +763,7 @@ start_thread_pipe (select_record *me, select_stuff *stuff)
     {
       pi->start = &stuff->start;
       pi->stop_thread = false;
+      pi->bye = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
       pi->thread = new cygthread (thread_pipe, pi, "pipesel");
       me->h = *pi->thread;
       if (!me->h)
@@ -780,8 +781,10 @@ pipe_cleanup (select_record *, select_stuff *stuff)
   if (pi->thread)
     {
       pi->stop_thread = true;
+      SetEvent (pi->bye);
       pi->thread->detach ();
     }
+  CloseHandle (pi->bye);
   delete pi;
   stuff->device_specific_pipe = NULL;
 }
@@ -924,7 +927,7 @@ thread_fifo (void *arg)
 	  }
       if (!looping)
 	break;
-      Sleep (sleep_time >> 3);
+      cygwait (pi->bye, sleep_time >> 3);
       if (sleep_time < 80)
 	++sleep_time;
       if (pi->stop_thread)
@@ -943,6 +946,7 @@ start_thread_fifo (select_record *me, select_stuff *stuff)
     {
       pi->start = &stuff->start;
       pi->stop_thread = false;
+      pi->bye = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
       pi->thread = new cygthread (thread_fifo, pi, "fifosel");
       me->h = *pi->thread;
       if (!me->h)
@@ -960,8 +964,10 @@ fifo_cleanup (select_record *, select_stuff *stuff)
   if (pi->thread)
     {
       pi->stop_thread = true;
+      SetEvent (pi->bye);
       pi->thread->detach ();
     }
+  CloseHandle (pi->bye);
   delete pi;
   stuff->device_specific_fifo = NULL;
 }
@@ -1279,7 +1285,7 @@ thread_pty_slave (void *arg)
 	  }
       if (!looping)
 	break;
-      Sleep (sleep_time >> 3);
+      cygwait (pi->bye, sleep_time >> 3);
       if (sleep_time < 80)
 	++sleep_time;
       if (pi->stop_thread)
@@ -1303,6 +1309,7 @@ pty_slave_startup (select_record *me, select_stuff *stuff)
     {
       pi->start = &stuff->start;
       pi->stop_thread = false;
+      pi->bye = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
       pi->thread = new cygthread (thread_pty_slave, pi, "ptyssel");
       me->h = *pi->thread;
       if (!me->h)
@@ -1325,8 +1332,10 @@ pty_slave_cleanup (select_record *me, select_stuff *stuff)
   if (pi->thread)
     {
       pi->stop_thread = true;
+      SetEvent (pi->bye);
       pi->thread->detach ();
     }
+  CloseHandle (pi->bye);
   delete pi;
   stuff->device_specific_ptys = NULL;
 }
diff --git a/winsup/cygwin/select.h b/winsup/cygwin/select.h
index ae98c658d..98fde3a89 100644
--- a/winsup/cygwin/select.h
+++ b/winsup/cygwin/select.h
@@ -44,6 +44,7 @@ struct select_info
 {
   cygthread *thread;
   bool stop_thread;
+  HANDLE bye;
   select_record *start;
   select_info (): thread (NULL), stop_thread (0), start (NULL) {}
 };
-- 
2.21.0



More information about the Cygwin-patches mailing list