* 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.
This commit is contained in:
		| @@ -1,3 +1,20 @@ | ||||
| 2002-08-01  Christopher Faylor  <cgf@redhat.com> | ||||
|  | ||||
| 	* 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  <cgf@redhat.com> | ||||
|  | ||||
| 	* syscalls.cc (_link): Revert previous change and just always | ||||
|   | ||||
| @@ -147,6 +147,13 @@ HANDLE () | ||||
|   return ev; | ||||
| } | ||||
|  | ||||
| void | ||||
| cygthread::exit_thread () | ||||
| { | ||||
|   SetEvent (ev); | ||||
|   ExitThread (0); | ||||
| } | ||||
|  | ||||
| void | ||||
| cygthread::detach () | ||||
| { | ||||
|   | ||||
| @@ -27,4 +27,5 @@ class cygthread | ||||
|   operator HANDLE (); | ||||
|   static bool is (); | ||||
|   void * operator new (size_t); | ||||
|   void exit_thread (); | ||||
| }; | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user