From c4ec64d76b9650b92d4c9f566fbac788c2d3fd46 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Wed, 9 Oct 2002 05:55:40 +0000 Subject: [PATCH] * cygthread.cc (cygthread::stub): Don't create an event for "cygself" threads. Assume that they exit via an ExitThread call. * cygthread.h (cygthread::SetThreadPriority): New function. (cygthread::zap_h): New function. * dcrt0.cc (do_exit): Move cygthread::terminate earlier and establish exit_state guard. * fhandler.h (fhandler_tty_master::output_thread): Delete. * fhandler_tty.cc (fhandler_tty_master::init): Set priority for threads via method. Zap handles when done. Don't treat process_output specially. (process_output): Call ExitThread directly. (fhandler_tty_master::fixup_after_fork): Don't worry about output_thread. (fhandler_tty_master::fixup_after_exec): Ditto. * sigproc.cc (proc_terminate): Don't detach from hwait_subproc. Just let it exit. (sigproc_init): Close thread handle after initialization. (wait_sig): Use GetCurrentThread() as SetThreadPriority call rather than *event* handle. Call ExitThread directly on termination. (wait_subproc): Call ExitThread directly on termination. * tty.cc (tty_list::terminate): Don't attempt t detach from output_thread. --- winsup/cygwin/ChangeLog | 25 +++++++++++++++++++++++++ winsup/cygwin/cygthread.cc | 5 ++++- winsup/cygwin/cygthread.h | 7 +++++++ winsup/cygwin/dcrt0.cc | 14 ++++++++++---- winsup/cygwin/fhandler.h | 2 -- winsup/cygwin/fhandler_tty.cc | 27 +++++++++++++-------------- winsup/cygwin/sigproc.cc | 8 ++++---- winsup/cygwin/tty.cc | 2 -- 8 files changed, 63 insertions(+), 27 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index b81f856e2..e006d7efa 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,28 @@ +2002-10-09 Christopher Faylor + + * cygthread.cc (cygthread::stub): Don't create an event for "cygself" + threads. Assume that they exit via an ExitThread call. + * cygthread.h (cygthread::SetThreadPriority): New function. + (cygthread::zap_h): New function. + * dcrt0.cc (do_exit): Move cygthread::terminate earlier and establish + exit_state guard. + * fhandler.h (fhandler_tty_master::output_thread): Delete. + * fhandler_tty.cc (fhandler_tty_master::init): Set priority for threads + via method. Zap handles when done. Don't treat process_output + specially. + (process_output): Call ExitThread directly. + (fhandler_tty_master::fixup_after_fork): Don't worry about + output_thread. + (fhandler_tty_master::fixup_after_exec): Ditto. + * sigproc.cc (proc_terminate): Don't detach from hwait_subproc. Just + let it exit. + (sigproc_init): Close thread handle after initialization. + (wait_sig): Use GetCurrentThread() as SetThreadPriority call rather + than *event* handle. Call ExitThread directly on termination. + (wait_subproc): Call ExitThread directly on termination. + * tty.cc (tty_list::terminate): Don't attempt t detach from + output_thread. + 2002-10-08 Christopher Faylor * cygheap.cc (dup_now): Make fatal error a little more informative. diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index c6e5d173b..74b35f454 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -53,7 +53,10 @@ cygthread::stub (VOID *arg) init_exceptions (&except_entry); cygthread *info = (cygthread *) arg; - info->ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); + if (info->arg == cygself) + info->ev = NULL; + else + info->ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); while (1) { if (!info->func) diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h index b55aec90c..5ea74b38f 100644 --- a/winsup/cygwin/cygthread.h +++ b/winsup/cygwin/cygthread.h @@ -34,6 +34,13 @@ class cygthread static void * freerange (); void exit_thread (); static void terminate (); + bool SetThreadPriority (int nPriority) {return ::SetThreadPriority (h, nPriority);} + void zap_h () + { + (void) CloseHandle (h); + h = NULL; + } + }; #define cygself NULL diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 4b752cf63..2959c6f08 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -947,9 +947,10 @@ __main (void) enum { - ES_SIGNAL = 1, - ES_CLOSEALL = 2, - ES_SIGPROCTERMINATE = 3 + ES_THREADTERM = 1, + ES_SIGNAL = 2, + ES_CLOSEALL = 3, + ES_SIGPROCTERMINATE = 4 }; extern "C" void __stdcall @@ -962,6 +963,12 @@ do_exit (int status) system_printf ("DisableThreadLibraryCalls (%p) failed, %E", cygwin_hmodule); + if (exit_state < ES_THREADTERM) + { + exit_state = ES_THREADTERM; + cygthread::terminate (); + } + syscall_printf ("do_exit (%d)", n); vfork_save *vf = vfork_storage.val (); @@ -1028,7 +1035,6 @@ do_exit (int status) window_terminate (); events_terminate (); shared_terminate (); - cygthread::terminate (); minimal_printf ("winpid %d, exit %d", GetCurrentProcessId (), n); myself->exit (n); diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 6611b487d..c0846ab9a 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -926,13 +926,11 @@ 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. - 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 9c2bb7f49..a8d6df2cc 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -36,7 +36,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), output_thread (NULL) + : fhandler_pty_master (FH_TTYM, unit), console (NULL) { } @@ -62,14 +62,17 @@ fhandler_tty_master::init (int ntty) inuse = get_ttyp ()->create_inuse (TTY_MASTER_ALIVE); cygthread *h; - h = new cygthread (process_input, NULL, "ttyin"); - SetThreadPriority (*h, THREAD_PRIORITY_HIGHEST); + h = new cygthread (process_input, cygself, "ttyin"); + h->SetThreadPriority (THREAD_PRIORITY_HIGHEST); + h->zap_h (); - h = new cygthread (process_ioctl, NULL, "ttyioctl"); - SetThreadPriority (*h, THREAD_PRIORITY_HIGHEST); + h = new cygthread (process_ioctl, cygself, "ttyioctl"); + h->SetThreadPriority (THREAD_PRIORITY_HIGHEST); + h->zap_h (); - output_thread = new cygthread (process_output, cygself, "ttyout"); - SetThreadPriority (*output_thread, THREAD_PRIORITY_HIGHEST); + h = new cygthread (process_output, cygself, "ttyout"); + h->SetThreadPriority (THREAD_PRIORITY_HIGHEST); + h->zap_h (); return 0; } @@ -368,9 +371,9 @@ out: } static DWORD WINAPI -process_output (void *self) +process_output (void *) { - char buf[OUT_BUFFER_SIZE*2]; + char buf[OUT_BUFFER_SIZE * 2]; for (;;) { @@ -379,9 +382,7 @@ process_output (void *self) { if (n < 0) termios_printf ("ReadFile %E"); - cygthread *t = (cygthread *) self; - tty_master->output_thread = NULL; - t->exit_thread (); + ExitThread (0); } n = tty_master->console->write ((void *) buf, (size_t) n); tty_master->get_ttyp ()->write_error = n == -1 ? get_errno () : 0; @@ -1167,7 +1168,6 @@ 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 @@ -1175,7 +1175,6 @@ fhandler_tty_master::fixup_after_exec (HANDLE) { console->close (); init_console (); - output_thread = NULL; // It's unreachable now } int diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 091065241..8cc459c1c 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -458,7 +458,6 @@ proc_terminate (void) { proc_loop_wait = 0; // Tell wait_subproc thread to exit wake_wait_subproc (); // Wake wait_subproc loop - hwait_subproc->detach (); hwait_subproc = NULL; sync_proc_subproc->acquire (WPSP); @@ -568,6 +567,7 @@ sigproc_init () ProtectHandle (signal_arrived); hwait_sig = new cygthread (wait_sig, cygself, "sig"); + hwait_sig->zap_h (); /* sync_proc_subproc is used by proc_subproc. It serialises * access to the children and zombie arrays. @@ -1030,7 +1030,7 @@ static DWORD WINAPI wait_sig (VOID *self) { /* Initialization */ - (void) SetThreadPriority (*((cygthread *) self), WAIT_SIG_PRIORITY); + (void) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY); /* sigcatch_nosync - semaphore incremented by sig_dispatch_pending and * by foreign processes to force an examination of @@ -1193,7 +1193,7 @@ wait_sig (VOID *self) } sigproc_printf ("done"); - return 0; + ExitThread (0); } /* Wait for subprocesses to terminate. Executes in a separate thread. */ @@ -1267,7 +1267,7 @@ wait_subproc (VOID *) ForceCloseHandle (events[0]); events[0] = NULL; sigproc_printf ("done"); - return 0; + ExitThread (0); } extern "C" { diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc index 18cfc9bdc..80465ea5d 100644 --- a/winsup/cygwin/tty.cc +++ b/winsup/cygwin/tty.cc @@ -144,8 +144,6 @@ tty_list::terminate (void) ForceCloseHandle1 (t->to_slave, to_pty); ForceCloseHandle1 (t->from_slave, from_pty); CloseHandle (tty_master->inuse); - if (tty_master->output_thread) - tty_master->output_thread->detach (); t->init (); char buf[20];