* cygthread.h (cygthread::stack_ptr): New element.
(cygthread::detach): Accept a "wait_for_signal" argument. (cygthread::terminate_thread): New function. * cygthread.cc (cygthread::stub): Set stack pointer argument. (cygthread::terminate_thread): New function. Forcibly terminate thread. (cygthread::detach): Optionally wait for signals and kill thread when signal arrives. * exceptions.cc (signal_exit): Set signal_arrived prior to exiting to wake up anything blocking on signals. * fhandler.h (fhandler_base::set_r_no_interrupt): Change to accept bool argument. (fhandler_pipe::ready_for_read): Declare. * pipe.cc (pipeargs): New structure. (read_pipe): New thread stub wrapper for normal pipe read. (fhandler_pipe::read): Modify to call reader in a cygthread, terminating on signal, as appropriate. * select.cc (fhandler_pipe::ready_for_read): Define new function.
This commit is contained in:
		| @@ -1,3 +1,24 @@ | |||||||
|  | 2002-12-10  Christopher Faylor  <cgf@redhat.com> | ||||||
|  |  | ||||||
|  | 	* cygthread.h (cygthread::stack_ptr): New element. | ||||||
|  | 	(cygthread::detach): Accept a "wait_for_signal" argument. | ||||||
|  | 	(cygthread::terminate_thread): New function. | ||||||
|  | 	* cygthread.cc (cygthread::stub): Set stack pointer argument. | ||||||
|  | 	(cygthread::terminate_thread): New function.  Forcibly terminate | ||||||
|  | 	thread. | ||||||
|  | 	(cygthread::detach): Optionally wait for signals and kill thread when | ||||||
|  | 	signal arrives. | ||||||
|  | 	* exceptions.cc (signal_exit): Set signal_arrived prior to exiting to | ||||||
|  | 	wake up anything blocking on signals. | ||||||
|  | 	* fhandler.h (fhandler_base::set_r_no_interrupt): Change to accept bool | ||||||
|  | 	argument. | ||||||
|  | 	(fhandler_pipe::ready_for_read): Declare. | ||||||
|  | 	* pipe.cc (pipeargs): New structure. | ||||||
|  | 	(read_pipe): New thread stub wrapper for normal pipe read. | ||||||
|  | 	(fhandler_pipe::read): Modify to call reader in a cygthread, | ||||||
|  | 	terminating on signal, as appropriate. | ||||||
|  | 	* select.cc (fhandler_pipe::ready_for_read): Define new function. | ||||||
|  |  | ||||||
| 2002-12-10  Corinna Vinschen  <corinna@vinschen.de> | 2002-12-10  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* net.cc (free_protoent_ptr): Add missing free() for base structure. | 	* net.cc (free_protoent_ptr): Add missing free() for base structure. | ||||||
| @@ -6,16 +27,17 @@ | |||||||
|  |  | ||||||
| 2002-12-10 Craig McGeachie <slapdau@yahoo.com.au> | 2002-12-10 Craig McGeachie <slapdau@yahoo.com.au> | ||||||
|  |  | ||||||
| 	* netdb.cc (parse_alias_list, parse_services_line) | 	* netdb.cc (parse_alias_list): Change strtok calls to strtok_r. | ||||||
| 	(parse_protocol_line): Change strtok calls to strtok_r. | 	(parse_services_line): Ditto. | ||||||
|  | 	(parse_protocol_line): Ditto. | ||||||
|  |  | ||||||
| 2002-12-10  Pierre Humblet <pierre.humblet@ieee.org> | 2002-12-10  Pierre Humblet <pierre.humblet@ieee.org> | ||||||
|  |  | ||||||
| 	* pwdgrp.h (pwdgrp_check::pwdgrp_state): Replace by | 	* pwdgrp.h (pwdgrp_check::pwdgrp_state): Replace by | ||||||
| 	pwdgrp_check::isinitializing (). | 	pwdgrp_check::isinitializing (). | ||||||
| 	(pwdgrp_check::isinitializing): Create. | 	(pwdgrp_check::isinitializing): Create. | ||||||
| 	* passwd.cc (grab_int): Change type to unsigned, use strtoul and | 	* passwd.cc (grab_int): Change type to unsigned, use strtoul and set | ||||||
| 	set the pointer content to 0 if the field is invalid. | 	the pointer content to 0 if the field is invalid. | ||||||
| 	(parse_pwd): Move validity test after getting pw_gid. | 	(parse_pwd): Move validity test after getting pw_gid. | ||||||
| 	(read_etc_passwd): Replace "passwd_state <= " by | 	(read_etc_passwd): Replace "passwd_state <= " by | ||||||
| 	passwd_state::isinitializing (). | 	passwd_state::isinitializing (). | ||||||
|   | |||||||
| @@ -9,14 +9,17 @@ details. */ | |||||||
| #include "winsup.h" | #include "winsup.h" | ||||||
| #include <windows.h> | #include <windows.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  | #include <errno.h> | ||||||
| #include "exceptions.h" | #include "exceptions.h" | ||||||
| #include "security.h" | #include "security.h" | ||||||
| #include "cygthread.h" | #include "cygthread.h" | ||||||
| #include "sync.h" | #include "sync.h" | ||||||
|  | #include "cygerrno.h" | ||||||
|  | #include "sigproc.h" | ||||||
|  |  | ||||||
| #undef CloseHandle | #undef CloseHandle | ||||||
|  |  | ||||||
| static cygthread NO_COPY threads[9]; | static cygthread NO_COPY threads[18]; | ||||||
| #define NTHREADS (sizeof (threads) / sizeof (threads[0])) | #define NTHREADS (sizeof (threads) / sizeof (threads[0])) | ||||||
|  |  | ||||||
| DWORD NO_COPY cygthread::main_thread_id; | DWORD NO_COPY cygthread::main_thread_id; | ||||||
| @@ -37,11 +40,12 @@ cygthread::stub (VOID *arg) | |||||||
|  |  | ||||||
|   cygthread *info = (cygthread *) arg; |   cygthread *info = (cygthread *) arg; | ||||||
|   if (info->arg == cygself) |   if (info->arg == cygself) | ||||||
|     info->ev = info->thread_sync = NULL; |     info->ev = info->thread_sync = info->stack_ptr = NULL; | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       info->ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); |       info->ev = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); | ||||||
|       info->thread_sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); |       info->thread_sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); | ||||||
|  |       info->stack_ptr = &arg; | ||||||
|     } |     } | ||||||
|   while (1) |   while (1) | ||||||
|     { |     { | ||||||
| @@ -231,22 +235,72 @@ cygthread::exit_thread () | |||||||
|   ExitThread (0); |   ExitThread (0); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Forcibly terminate a thread. */ | ||||||
|  | void | ||||||
|  | cygthread::terminate_thread () | ||||||
|  | { | ||||||
|  |   if (!is_freerange) | ||||||
|  |     SetEvent (*this); | ||||||
|  |   (void) TerminateThread (h, 0); | ||||||
|  |   (void) WaitForSingleObject (h, INFINITE); | ||||||
|  |  | ||||||
|  |   MEMORY_BASIC_INFORMATION m; | ||||||
|  |   memset (&m, 0, sizeof (m)); | ||||||
|  |   (void) VirtualQuery (stack_ptr, &m, sizeof m); | ||||||
|  |  | ||||||
|  |   if (m.RegionSize) | ||||||
|  |     (void) VirtualFree (m.AllocationBase, m.RegionSize, MEM_DECOMMIT); | ||||||
|  |  | ||||||
|  |   if (is_freerange) | ||||||
|  |     is_freerange = false; | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       CloseHandle (ev); | ||||||
|  |       CloseHandle (thread_sync); | ||||||
|  |     } | ||||||
|  |   CloseHandle (h); | ||||||
|  |   thread_sync = ev = h = NULL; | ||||||
|  |   __name = NULL; | ||||||
|  |   id = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* Detach the cygthread from the current thread.  Note that the | /* Detach the cygthread from the current thread.  Note that the | ||||||
|    theory is that cygthreads are only associated with one thread. |    theory is that cygthreads are only associated with one thread. | ||||||
|    So, there should be no problems with multiple threads doing waits |    So, there should be no problems with multiple threads doing waits | ||||||
|    on the one cygthread. */ |    on the one cygthread. */ | ||||||
| void | void | ||||||
| cygthread::detach () | cygthread::detach (bool wait_for_sig) | ||||||
| { | { | ||||||
|   if (avail) |   if (avail) | ||||||
|     system_printf ("called detach on available thread %d?", avail); |     system_printf ("called detach on available thread %d?", avail); | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       DWORD avail = id; |       DWORD avail = id; | ||||||
|       DWORD res = WaitForSingleObject (*this, INFINITE); |       DWORD res; | ||||||
|       thread_printf ("WFSO returns %d, id %p", res, id); |  | ||||||
|  |  | ||||||
|       if (is_freerange) |       if (!wait_for_sig) | ||||||
|  | 	res = WaitForSingleObject (*this, INFINITE); | ||||||
|  |       else | ||||||
|  | 	{ | ||||||
|  | 	  HANDLE w4[2]; | ||||||
|  | 	  w4[0] = signal_arrived; | ||||||
|  | 	  w4[1] = *this; | ||||||
|  | 	  res = WaitForMultipleObjects (2, w4, FALSE, INFINITE); | ||||||
|  | 	  if (res == WAIT_OBJECT_0) | ||||||
|  | 	    { | ||||||
|  | 	      terminate_thread (); | ||||||
|  | 	      set_errno (EINTR);	/* caller should be dealing with return | ||||||
|  | 					   values. */ | ||||||
|  | 	      avail = 0; | ||||||
|  | 	    } | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |       thread_printf ("%s returns %d, id %p", wait_for_sig ? "WFMO" : "WFSO", | ||||||
|  | 		     res, id); | ||||||
|  |  | ||||||
|  |       if (!avail) | ||||||
|  | 	/* already handled */; | ||||||
|  |       else if (is_freerange) | ||||||
| 	{ | 	{ | ||||||
| 	  CloseHandle (h); | 	  CloseHandle (h); | ||||||
| 	  free (this); | 	  free (this); | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ class cygthread | |||||||
|   HANDLE h; |   HANDLE h; | ||||||
|   HANDLE ev; |   HANDLE ev; | ||||||
|   HANDLE thread_sync; |   HANDLE thread_sync; | ||||||
|  |   void *stack_ptr; | ||||||
|   const char *__name; |   const char *__name; | ||||||
|   LPTHREAD_START_ROUTINE func; |   LPTHREAD_START_ROUTINE func; | ||||||
|   VOID *arg; |   VOID *arg; | ||||||
| @@ -26,12 +27,13 @@ class cygthread | |||||||
|   cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *); |   cygthread (LPTHREAD_START_ROUTINE, LPVOID, const char *); | ||||||
|   cygthread () {}; |   cygthread () {}; | ||||||
|   static void init (); |   static void init (); | ||||||
|   void detach (); |   void detach (bool = false); | ||||||
|   operator HANDLE (); |   operator HANDLE (); | ||||||
|   static bool is (); |   static bool is (); | ||||||
|   void * operator new (size_t); |   void * operator new (size_t); | ||||||
|   static cygthread *freerange (); |   static cygthread *freerange (); | ||||||
|   void exit_thread (); |   void exit_thread (); | ||||||
|  |   void terminate_thread (); | ||||||
|   static void terminate (); |   static void terminate (); | ||||||
|   bool SetThreadPriority (int nPriority) {return ::SetThreadPriority (h, nPriority);} |   bool SetThreadPriority (int nPriority) {return ::SetThreadPriority (h, nPriority);} | ||||||
|   void zap_h () |   void zap_h () | ||||||
|   | |||||||
| @@ -1117,6 +1117,7 @@ signal_exit (int rc) | |||||||
|     TerminateProcess (hExeced, rc); |     TerminateProcess (hExeced, rc); | ||||||
|  |  | ||||||
|   sigproc_printf ("about to call do_exit (%x)", rc); |   sigproc_printf ("about to call do_exit (%x)", rc); | ||||||
|  |   (void) SetEvent (signal_arrived); | ||||||
|   do_exit (rc); |   do_exit (rc); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -219,7 +219,7 @@ class fhandler_base | |||||||
|   int get_default_fmode (int flags); |   int get_default_fmode (int flags); | ||||||
|  |  | ||||||
|   bool get_r_no_interrupt () { return FHISSETF (NOEINTR); } |   bool get_r_no_interrupt () { return FHISSETF (NOEINTR); } | ||||||
|   void set_r_no_interrupt (int b) { FHCONDSETF (b, NOEINTR); } |   void set_r_no_interrupt (bool b) { FHCONDSETF (b, NOEINTR); } | ||||||
|  |  | ||||||
|   bool get_close_on_exec () { return FHISSETF (CLOEXEC); } |   bool get_close_on_exec () { return FHISSETF (CLOEXEC); } | ||||||
|   int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); } |   int set_close_on_exec_flag (int b) { return FHCONDSETF (b, CLOEXEC); } | ||||||
| @@ -473,6 +473,7 @@ class fhandler_pipe: public fhandler_base | |||||||
|   void set_eof () {broken_pipe = true;} |   void set_eof () {broken_pipe = true;} | ||||||
|   friend int make_pipe (int fildes[2], unsigned int psize, int mode); |   friend int make_pipe (int fildes[2], unsigned int psize, int mode); | ||||||
|   HANDLE get_guard () const {return guard;} |   HANDLE get_guard () const {return guard;} | ||||||
|  |   int ready_for_read (int fd, DWORD howlong); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class fhandler_dev_raw: public fhandler_base | class fhandler_dev_raw: public fhandler_base | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ details. */ | |||||||
| #include "cygheap.h" | #include "cygheap.h" | ||||||
| #include "thread.h" | #include "thread.h" | ||||||
| #include "pinfo.h" | #include "pinfo.h" | ||||||
|  | #include "cygthread.h" | ||||||
|  |  | ||||||
| static unsigned pipecount; | static unsigned pipecount; | ||||||
| static const NO_COPY char pipeid_fmt[] = "stupid_pipe.%u.%u"; | static const NO_COPY char pipeid_fmt[] = "stupid_pipe.%u.%u"; | ||||||
| @@ -50,14 +51,36 @@ fhandler_pipe::set_close_on_exec (int val) | |||||||
|     set_inheritance (writepipe_exists, val); |     set_inheritance (writepipe_exists, val); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | struct pipeargs | ||||||
|  | { | ||||||
|  |   fhandler_base *fh; | ||||||
|  |   void *ptr; | ||||||
|  |   size_t len; | ||||||
|  |   int res; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | static DWORD WINAPI | ||||||
|  | read_pipe (void *arg) | ||||||
|  | { | ||||||
|  |   pipeargs *pi = (pipeargs *) arg; | ||||||
|  |   pi->res = pi->fh->fhandler_base::read (pi->ptr, pi->len); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| int __stdcall | int __stdcall | ||||||
| fhandler_pipe::read (void *in_ptr, size_t in_len) | fhandler_pipe::read (void *in_ptr, size_t in_len) | ||||||
| { | { | ||||||
|   if (broken_pipe) |   if (broken_pipe) | ||||||
|     return 0; |     return 0; | ||||||
|   int res = this->fhandler_base::read (in_ptr, in_len); |   pipeargs pi; | ||||||
|  |   pi.fh = this; | ||||||
|  |   pi.ptr = in_ptr; | ||||||
|  |   pi.len = in_len; | ||||||
|  |   pi.res = -1; | ||||||
|  |   cygthread *th = new cygthread (read_pipe, &pi, "read_pipe"); | ||||||
|  |   th->detach (1); | ||||||
|   (void) ReleaseMutex (guard); |   (void) ReleaseMutex (guard); | ||||||
|   return res; |   return pi.res; | ||||||
| } | } | ||||||
|  |  | ||||||
| int fhandler_pipe::close () | int fhandler_pipe::close () | ||||||
|   | |||||||
| @@ -431,7 +431,7 @@ peek_pipe (select_record *s, bool from_select) | |||||||
| 	{ | 	{ | ||||||
| 	case FH_PTYM: | 	case FH_PTYM: | ||||||
| 	case FH_TTYM: | 	case FH_TTYM: | ||||||
| 	  if (((fhandler_pty_master *)fh)->need_nl) | 	  if (((fhandler_pty_master *) fh)->need_nl) | ||||||
| 	    { | 	    { | ||||||
| 	      gotone = s->read_ready = true; | 	      gotone = s->read_ready = true; | ||||||
| 	      goto out; | 	      goto out; | ||||||
| @@ -521,7 +521,7 @@ struct pipeinf | |||||||
| static DWORD WINAPI | static DWORD WINAPI | ||||||
| thread_pipe (void *arg) | thread_pipe (void *arg) | ||||||
| { | { | ||||||
|   pipeinf *pi = (pipeinf *)arg; |   pipeinf *pi = (pipeinf *) arg; | ||||||
|   BOOL gotone = FALSE; |   BOOL gotone = FALSE; | ||||||
|  |  | ||||||
|   for (;;) |   for (;;) | ||||||
| @@ -563,18 +563,18 @@ start_thread_pipe (select_record *me, select_stuff *stuff) | |||||||
|   pipeinf *pi = new pipeinf; |   pipeinf *pi = new pipeinf; | ||||||
|   pi->start = &stuff->start; |   pi->start = &stuff->start; | ||||||
|   pi->stop_thread_pipe = FALSE; |   pi->stop_thread_pipe = FALSE; | ||||||
|   pi->thread = new cygthread (thread_pipe, (LPVOID)pi, "select_pipe"); |   pi->thread = new cygthread (thread_pipe, (LPVOID) pi, "select_pipe"); | ||||||
|   me->h = *pi->thread; |   me->h = *pi->thread; | ||||||
|   if (!me->h) |   if (!me->h) | ||||||
|     return 0; |     return 0; | ||||||
|   stuff->device_specific[FHDEVN (FH_PIPE)] = (void *)pi; |   stuff->device_specific[FHDEVN (FH_PIPE)] = (void *) pi; | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| pipe_cleanup (select_record *, select_stuff *stuff) | pipe_cleanup (select_record *, select_stuff *stuff) | ||||||
| { | { | ||||||
|   pipeinf *pi = (pipeinf *)stuff->device_specific[FHDEVN (FH_PIPE)]; |   pipeinf *pi = (pipeinf *) stuff->device_specific[FHDEVN (FH_PIPE)]; | ||||||
|   if (pi && pi->thread) |   if (pi && pi->thread) | ||||||
|     { |     { | ||||||
|       pi->stop_thread_pipe = true; |       pi->stop_thread_pipe = true; | ||||||
| @@ -584,6 +584,16 @@ pipe_cleanup (select_record *, select_stuff *stuff) | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | fhandler_pipe::ready_for_read (int fd, DWORD howlong) | ||||||
|  | { | ||||||
|  |   if (!howlong) | ||||||
|  |     return this->fhandler_base::ready_for_read (fd, howlong); | ||||||
|  |  | ||||||
|  |   get_guard (); | ||||||
|  |   return true; | ||||||
|  | } | ||||||
|  |  | ||||||
| select_record * | select_record * | ||||||
| fhandler_pipe::select_read (select_record *s) | fhandler_pipe::select_read (select_record *s) | ||||||
| { | { | ||||||
| @@ -631,7 +641,7 @@ static int | |||||||
| peek_console (select_record *me, bool) | peek_console (select_record *me, bool) | ||||||
| { | { | ||||||
|   extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *); |   extern const char * get_nonascii_key (INPUT_RECORD& input_rec, char *); | ||||||
|   fhandler_console *fh = (fhandler_console *)me->fh; |   fhandler_console *fh = (fhandler_console *) me->fh; | ||||||
|  |  | ||||||
|   if (!me->read_selected) |   if (!me->read_selected) | ||||||
|     return me->write_ready; |     return me->write_ready; | ||||||
| @@ -748,19 +758,19 @@ fhandler_console::select_except (select_record *s) | |||||||
| select_record * | select_record * | ||||||
| fhandler_tty_common::select_read (select_record *s) | fhandler_tty_common::select_read (select_record *s) | ||||||
| { | { | ||||||
|   return ((fhandler_pipe*)this)->fhandler_pipe::select_read (s); |   return ((fhandler_pipe *) this)->fhandler_pipe::select_read (s); | ||||||
| } | } | ||||||
|  |  | ||||||
| select_record * | select_record * | ||||||
| fhandler_tty_common::select_write (select_record *s) | fhandler_tty_common::select_write (select_record *s) | ||||||
| { | { | ||||||
|   return ((fhandler_pipe *)this)->fhandler_pipe::select_write (s); |   return ((fhandler_pipe *) this)->fhandler_pipe::select_write (s); | ||||||
| } | } | ||||||
|  |  | ||||||
| select_record * | select_record * | ||||||
| fhandler_tty_common::select_except (select_record *s) | fhandler_tty_common::select_except (select_record *s) | ||||||
| { | { | ||||||
|   return ((fhandler_pipe *)this)->fhandler_pipe::select_except (s); |   return ((fhandler_pipe *) this)->fhandler_pipe::select_except (s); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int | static int | ||||||
| @@ -846,7 +856,7 @@ peek_serial (select_record *s, bool) | |||||||
| { | { | ||||||
|   COMSTAT st; |   COMSTAT st; | ||||||
|  |  | ||||||
|   fhandler_serial *fh = (fhandler_serial *)s->fh; |   fhandler_serial *fh = (fhandler_serial *) s->fh; | ||||||
|  |  | ||||||
|   if (fh->get_readahead_valid () || fh->overlapped_armed < 0) |   if (fh->get_readahead_valid () || fh->overlapped_armed < 0) | ||||||
|     return s->read_ready = true; |     return s->read_ready = true; | ||||||
| @@ -944,7 +954,7 @@ err: | |||||||
| static DWORD WINAPI | static DWORD WINAPI | ||||||
| thread_serial (void *arg) | thread_serial (void *arg) | ||||||
| { | { | ||||||
|   serialinf *si = (serialinf *)arg; |   serialinf *si = (serialinf *) arg; | ||||||
|   BOOL gotone= FALSE; |   BOOL gotone= FALSE; | ||||||
|  |  | ||||||
|   for (;;) |   for (;;) | ||||||
| @@ -980,16 +990,16 @@ start_thread_serial (select_record *me, select_stuff *stuff) | |||||||
|   serialinf *si = new serialinf; |   serialinf *si = new serialinf; | ||||||
|   si->start = &stuff->start; |   si->start = &stuff->start; | ||||||
|   si->stop_thread_serial = FALSE; |   si->stop_thread_serial = FALSE; | ||||||
|   si->thread = new cygthread (thread_serial, (LPVOID)si, "select_serial"); |   si->thread = new cygthread (thread_serial, (LPVOID) si, "select_serial"); | ||||||
|   me->h = *si->thread; |   me->h = *si->thread; | ||||||
|   stuff->device_specific[FHDEVN (FH_SERIAL)] = (void *)si; |   stuff->device_specific[FHDEVN (FH_SERIAL)] = (void *) si; | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| serial_cleanup (select_record *, select_stuff *stuff) | serial_cleanup (select_record *, select_stuff *stuff) | ||||||
| { | { | ||||||
|   serialinf *si = (serialinf *)stuff->device_specific[FHDEVN (FH_SERIAL)]; |   serialinf *si = (serialinf *) stuff->device_specific[FHDEVN (FH_SERIAL)]; | ||||||
|   if (si && si->thread) |   if (si && si->thread) | ||||||
|     { |     { | ||||||
|       si->stop_thread_serial = true; |       si->stop_thread_serial = true; | ||||||
| @@ -1200,7 +1210,7 @@ static int start_thread_socket (select_record *, select_stuff *); | |||||||
| static DWORD WINAPI | static DWORD WINAPI | ||||||
| thread_socket (void *arg) | thread_socket (void *arg) | ||||||
| { | { | ||||||
|   socketinf *si = (socketinf *)arg; |   socketinf *si = (socketinf *) arg; | ||||||
|  |  | ||||||
|   select_printf ("stuff_start %p", &si->start); |   select_printf ("stuff_start %p", &si->start); | ||||||
|   int r = WINSOCK_SELECT (0, &si->readfds, &si->writefds, &si->exceptfds, NULL); |   int r = WINSOCK_SELECT (0, &si->readfds, &si->writefds, &si->exceptfds, NULL); | ||||||
| @@ -1243,7 +1253,7 @@ start_thread_socket (select_record *me, select_stuff *stuff) | |||||||
| { | { | ||||||
|   socketinf *si; |   socketinf *si; | ||||||
|  |  | ||||||
|   if ((si = (socketinf *)stuff->device_specific[FHDEVN (FH_SOCKET)])) |   if ((si = (socketinf *) stuff->device_specific[FHDEVN (FH_SOCKET)])) | ||||||
|     { |     { | ||||||
|       me->h = *si->thread; |       me->h = *si->thread; | ||||||
|       return 1; |       return 1; | ||||||
| @@ -1314,7 +1324,7 @@ start_thread_socket (select_record *me, select_stuff *stuff) | |||||||
|   stuff->device_specific[FHDEVN (FH_SOCKET)] = (void *) si; |   stuff->device_specific[FHDEVN (FH_SOCKET)] = (void *) si; | ||||||
|   si->start = &stuff->start; |   si->start = &stuff->start; | ||||||
|   select_printf ("stuff_start %p", &stuff->start); |   select_printf ("stuff_start %p", &stuff->start); | ||||||
|   si->thread = new cygthread (thread_socket, (LPVOID)si, "select_socket"); |   si->thread = new cygthread (thread_socket, (LPVOID) si, "select_socket"); | ||||||
|   me->h = *si->thread; |   me->h = *si->thread; | ||||||
|   return 1; |   return 1; | ||||||
|  |  | ||||||
| @@ -1327,7 +1337,7 @@ err: | |||||||
| void | void | ||||||
| socket_cleanup (select_record *, select_stuff *stuff) | socket_cleanup (select_record *, select_stuff *stuff) | ||||||
| { | { | ||||||
|   socketinf *si = (socketinf *)stuff->device_specific[FHDEVN (FH_SOCKET)]; |   socketinf *si = (socketinf *) stuff->device_specific[FHDEVN (FH_SOCKET)]; | ||||||
|   select_printf ("si %p si->thread %p", si, si ? si->thread : NULL); |   select_printf ("si %p si->thread %p", si, si ? si->thread : NULL); | ||||||
|   if (si && si->thread) |   if (si && si->thread) | ||||||
|     { |     { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user