* 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:
parent
ea01c7f5d2
commit
1d380f593a
@ -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 ().
|
||||||
@ -23,7 +45,7 @@
|
|||||||
(internal_getpwnam): Ditto.
|
(internal_getpwnam): Ditto.
|
||||||
(getpwent): Ditto.
|
(getpwent): Ditto.
|
||||||
(getpass): Ditto.
|
(getpass): Ditto.
|
||||||
* grp.cc (parse_grp): Use strtoul for gr_gid and verify the validity.
|
* grp.cc (parse_grp): Use strtoul for gr_gid and verify the validity.
|
||||||
(read_etc_group): Replace "group_state <= " by
|
(read_etc_group): Replace "group_state <= " by
|
||||||
group_state::isinitializing ().
|
group_state::isinitializing ().
|
||||||
(internal_getgrgid): Ditto.
|
(internal_getgrgid): Ditto.
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user