From 6b2a9a2fdf2a62475c7bb7ff3ef49eee5b82fa6e Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Fri, 2 Aug 2002 02:10:24 +0000 Subject: [PATCH] * cygthread.cc (cygthread::exit_thread): Define new method. * cygthread.h (cygthread::exit_thread): Declare new method. * fhandler.h (fhandler_tty_master::hThread): Delete. (fhandler_tty_master::output_thread): Define. * fhandler_tty.cc (fhandler_tty_master::fhandler_tty_master): Adjust constructor. (fhandler_tty_master::init): Use cygthread rather than handle. (process_output): Use cygthread method to exit. (fhandler_tty_master::fixup_after_fork): Set output_thread to NULL after fork. (fhandler_tty_master::fixup_after_exec): Set output_thread to NULL after spawn/exec. * tty.cc (tty_list::terminate): Detach from output_thread using cygthread method. --- winsup/cygwin/ChangeLog | 17 +++++++++++++++++ winsup/cygwin/cygthread.cc | 7 +++++++ winsup/cygwin/cygthread.h | 1 + winsup/cygwin/fhandler.h | 3 ++- winsup/cygwin/fhandler_tty.cc | 24 +++++++++++------------- winsup/cygwin/syscalls.cc | 9 +++++---- winsup/cygwin/tty.cc | 5 +++-- 7 files changed, 46 insertions(+), 20 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index a9daddbce..53ecc8cec 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,20 @@ +2002-08-01 Christopher Faylor + + * cygthread.cc (cygthread::exit_thread): Define new method. + * cygthread.h (cygthread::exit_thread): Declare new method. + * fhandler.h (fhandler_tty_master::hThread): Delete. + (fhandler_tty_master::output_thread): Define. + * fhandler_tty.cc (fhandler_tty_master::fhandler_tty_master): Adjust + constructor. + (fhandler_tty_master::init): Use cygthread rather than handle. + (process_output): Use cygthread method to exit. + (fhandler_tty_master::fixup_after_fork): Set output_thread to NULL + after fork. + (fhandler_tty_master::fixup_after_exec): Set output_thread to NULL + after spawn/exec. + * tty.cc (tty_list::terminate): Detach from output_thread using + cygthread method. + 2002-08-01 Christopher Faylor * syscalls.cc (_link): Revert previous change and just always diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index 66abb7408..a4f32472d 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -147,6 +147,13 @@ HANDLE () return ev; } +void +cygthread::exit_thread () +{ + SetEvent (ev); + ExitThread (0); +} + void cygthread::detach () { diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h index 67e9d591e..b4f6cbe2f 100644 --- a/winsup/cygwin/cygthread.h +++ b/winsup/cygwin/cygthread.h @@ -27,4 +27,5 @@ class cygthread operator HANDLE (); static bool is (); void * operator new (size_t); + void exit_thread (); }; diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 17390bdc3..a338987d4 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -921,12 +921,13 @@ class fhandler_pty_master: public fhandler_tty_common bool hit_eof (); }; +class cygthread; class fhandler_tty_master: public fhandler_pty_master { public: /* Constructor */ fhandler_console *console; // device handler to perform real i/o. - HANDLE hThread; // process_output thread handle. + cygthread *output_thread; // process_output thread fhandler_tty_master (int unit); int init (int); diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 2ead75122..a7b7d814d 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -37,7 +37,7 @@ static DWORD WINAPI process_output (void *); // Output queue thread static DWORD WINAPI process_ioctl (void *); // Ioctl requests thread fhandler_tty_master::fhandler_tty_master (int unit) - : fhandler_pty_master (FH_TTYM, unit), console (NULL), hThread (NULL) + : fhandler_pty_master (FH_TTYM, unit), console (NULL), output_thread (NULL) { } @@ -69,9 +69,8 @@ fhandler_tty_master::init (int ntty) h = new cygthread (process_ioctl, NULL, "ttyioctl"); SetThreadPriority (*h, THREAD_PRIORITY_HIGHEST); - h = new cygthread (process_output, NULL, "ttyout"); - hThread = *h; - SetThreadPriority (h, THREAD_PRIORITY_HIGHEST); + output_thread = new cygthread (process_output, NULL, "ttyout"); + SetThreadPriority (*output_thread, THREAD_PRIORITY_HIGHEST); return 0; } @@ -377,15 +376,13 @@ process_output (void *) for (;;) { int n = tty_master->process_slave_output (buf, OUT_BUFFER_SIZE, 0); - if (n < 0) + if (n <= 0) { - termios_printf ("ReadFile %E"); - ExitThread (0); - } - if (n == 0) - { - /* End of file. */ - ExitThread (0); + if (n < 0) + termios_printf ("ReadFile %E"); + cygthread *t = tty_master->output_thread; + tty_master->output_thread = NULL; + t->exit_thread (); } n = tty_master->console->write ((void *) buf, (size_t) n); tty_master->get_ttyp ()->write_error = n == -1 ? get_errno () : 0; @@ -1186,6 +1183,7 @@ fhandler_tty_master::fixup_after_fork (HANDLE child) { this->fhandler_pty_master::fixup_after_fork (child); console->fixup_after_fork (child); + output_thread = NULL; // It's unreachable now } void @@ -1193,7 +1191,7 @@ fhandler_tty_master::fixup_after_exec (HANDLE) { console->close (); init_console (); - return; + output_thread = NULL; // It's unreachable now } int diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index a9c9d53c5..4792744e0 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -305,10 +305,11 @@ _read (int fd, void *ptr, size_t len) DWORD wait = cfd->is_nonblocking () ? 0 : INFINITE; /* Could block, so let user know we at least got here. */ - syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers); + syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", + fd, ptr, len, wait ? "" : "non", sigcatchers); if (wait && (!cfd->is_slow () || cfd->get_r_no_interrupt ())) - debug_printf ("non-interruptible read\n"); + debug_printf ("no need to call ready_for_read\n"); else if (!cfd->ready_for_read (fd, wait)) { res = -1; @@ -318,7 +319,7 @@ _read (int fd, void *ptr, size_t len) /* FIXME: This is not thread safe. We need some method to ensure that an fd, closed in another thread, aborts I/O operations. */ - if (!cfd.isopen()) + if (!cfd.isopen ()) return -1; /* Check to see if this is a background read from a "tty", @@ -331,7 +332,7 @@ _read (int fd, void *ptr, size_t len) if (res > bg_eof) { myself->process_state |= PID_TTYIN; - if (!cfd.isopen()) + if (!cfd.isopen ()) return -1; res = cfd->read (ptr, len); myself->process_state &= ~PID_TTYIN; diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index 11c25b161..bb9f8409f 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -25,6 +25,7 @@ details. */ #include "cygwin/cygserver_transport.h" #include "cygwin/cygserver.h" #include "shared_info.h" +#include "cygthread.h" extern fhandler_tty_master *tty_master; @@ -144,8 +145,8 @@ tty_list::terminate (void) ForceCloseHandle1 (t->to_slave, to_pty); ForceCloseHandle1 (t->from_slave, from_pty); CloseHandle (tty_master->inuse); - // FIXME This should be using a cygthread object - WaitForSingleObject (tty_master->hThread, INFINITE); + if (tty_master->output_thread) + tty_master->output_thread->detach (); t->init (); char buf[20]; -- 2.43.5