* select.h: New file split from fhandler.h.
(select_record::select_record): Define do-nothing constructor for "new" to avoid gratuitous zeroing. (select_info): New base class. (select_pipe_info): New class with methods for dealing with pipes. (select_socket_info): New class with methods for dealing with sockets. (select_serial_info): Dummy class for serial. (select_mailslot_info): Dummy class for mailslots. (select_stuff): Define device_specific_* as actual classes rather than void *. * dtable.h (dtable::select_read): Accommodate return value change to 'bool' and argument change to "select_stuff". (dtable::select_write): Ditto. (dtable::select_except): Ditto. * dtable.cc (dtable::select_read): Accommodate return value change to 'bool' and argument change to "select_stuff". (dtable::select_write): Ditto. (dtable::select_except): Ditto. * fhandler.h: Excise select-related classes. (fhandler_*::select_read): Change argument to select_stuff. (fhandler_*::select_write): Ditto. (fhandler_*::select_except): Ditto. * select.cc (UNIX_FD_ZERO): Use memset rather than bzero. (select_stuff::test_and_set): Change return type to bool. Allocate select_record on entry and let fhandler_*::select_* operate on the start.next field of select_stuff. (pipeinf): Delete. (select_pipe_info::select_pipe_info): New constructor. Allocates event for controlling pipe waits. (select_pipe_info::~select_pipe_info): New destructor. Destroy event. Stop thread. (select_pipe_info::add_watch_handle): New function. (thread_pipe): Wait for the hEvent part of any overlapped pipes before peeking. (start_thread_pipe): Don't allocate device_specific_pipe stuff here. Assume that it has been allocated earlier. (pipe_cleanup): Rely on select_pipe_info destructor to clean up pipe paraphenalia. (fhandler_*::select_*): Derive select_record from new select_stuff argument. (fhandler_pipe::select_*): Ditto. Allocate pipe-specific field if not already allocated. (serialinf): Delete. (thread_serial): serialinf -> select_serial_info. (fhandler_base::ready_for_read): Rewrite to accommodate change in argument to fhandler_*::select_*. (socketinf): Delete. (thread_socket): socketinf -> select_socket_info. (mailslotinf): Delete. (thread_mailslot): mailslotinf -> select_mailslot_info.
This commit is contained in:
parent
840bb39798
commit
b4fa816474
|
@ -1,3 +1,56 @@
|
|||
2009-06-30 Christopher Faylor <me+cygwin@cgf.cx>
|
||||
|
||||
* select.h: New file split from fhandler.h.
|
||||
(select_record::select_record): Define do-nothing constructor for "new"
|
||||
to avoid gratuitous zeroing.
|
||||
(select_info): New base class.
|
||||
(select_pipe_info): New class with methods for dealing with pipes.
|
||||
(select_socket_info): New class with methods for dealing with sockets.
|
||||
(select_serial_info): Dummy class for serial.
|
||||
(select_mailslot_info): Dummy class for mailslots.
|
||||
(select_stuff): Define device_specific_* as actual classes rather than
|
||||
void *.
|
||||
* dtable.h (dtable::select_read): Accommodate return value change to
|
||||
'bool' and argument change to "select_stuff".
|
||||
(dtable::select_write): Ditto.
|
||||
(dtable::select_except): Ditto.
|
||||
* dtable.cc (dtable::select_read): Accommodate return value change to
|
||||
'bool' and argument change to "select_stuff".
|
||||
(dtable::select_write): Ditto.
|
||||
(dtable::select_except): Ditto.
|
||||
* fhandler.h: Excise select-related classes.
|
||||
(fhandler_*::select_read): Change argument to select_stuff.
|
||||
(fhandler_*::select_write): Ditto.
|
||||
(fhandler_*::select_except): Ditto.
|
||||
* select.cc (UNIX_FD_ZERO): Use memset rather than bzero.
|
||||
(select_stuff::test_and_set): Change return type to bool. Allocate
|
||||
select_record on entry and let fhandler_*::select_* operate on the
|
||||
start.next field of select_stuff.
|
||||
(pipeinf): Delete.
|
||||
(select_pipe_info::select_pipe_info): New constructor. Allocates event
|
||||
for controlling pipe waits.
|
||||
(select_pipe_info::~select_pipe_info): New destructor. Destroy event.
|
||||
Stop thread.
|
||||
(select_pipe_info::add_watch_handle): New function.
|
||||
(thread_pipe): Wait for the hEvent part of any overlapped pipes before
|
||||
peeking.
|
||||
(start_thread_pipe): Don't allocate device_specific_pipe stuff here.
|
||||
Assume that it has been allocated earlier.
|
||||
(pipe_cleanup): Rely on select_pipe_info destructor to clean up pipe
|
||||
paraphenalia.
|
||||
(fhandler_*::select_*): Derive select_record from new select_stuff
|
||||
argument.
|
||||
(fhandler_pipe::select_*): Ditto. Allocate pipe-specific field if not
|
||||
already allocated.
|
||||
(serialinf): Delete.
|
||||
(thread_serial): serialinf -> select_serial_info.
|
||||
(fhandler_base::ready_for_read): Rewrite to accommodate change in
|
||||
argument to fhandler_*::select_*.
|
||||
(socketinf): Delete.
|
||||
(thread_socket): socketinf -> select_socket_info.
|
||||
(mailslotinf): Delete.
|
||||
(thread_mailslot): mailslotinf -> select_mailslot_info.
|
||||
|
||||
2009-06-30 Christopher Faylor <me+cygwin@cgf.cx>
|
||||
|
||||
* fhandler.cc (fhandler_base::has_ongoing_io): Accept an argument
|
||||
|
|
|
@ -109,7 +109,7 @@ class cygheap_user
|
|||
/* Extendend user information.
|
||||
The information is derived from the internal_getlogin call
|
||||
when on a NT system. */
|
||||
char *pname; /* user's name */
|
||||
char *pname; /* user's name */
|
||||
char *plogsrv; /* Logon server, may be FQDN */
|
||||
char *pdomain; /* Logon domain of the user */
|
||||
char *homedrive; /* User's home drive */
|
||||
|
|
|
@ -25,6 +25,7 @@ details. */
|
|||
#include "perprocess.h"
|
||||
#include "path.h"
|
||||
#include "fhandler.h"
|
||||
#include "select.h"
|
||||
#include "dtable.h"
|
||||
#include "cygheap.h"
|
||||
#include "tls_pbuf.h"
|
||||
|
@ -359,7 +360,7 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
|||
access |= GENERIC_WRITE; /* Should be rdwr for stderr but not sure that's
|
||||
possible for some versions of handles */
|
||||
/* FIXME: Workaround Windows 7 64 bit issue. If the parent process of
|
||||
the process tree closes the original handles to the console window,
|
||||
the process tree closes the original handles to the console window,
|
||||
strange problems occur when starting child processes later on if
|
||||
stdio redirection is used. How to reproduce:
|
||||
|
||||
|
@ -378,7 +379,7 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
|||
Remove the `exec 2>' or remove the cat call and the script will work.
|
||||
Start bash interactively, then start the script manually, and the
|
||||
script will work.
|
||||
|
||||
|
||||
This needs further investigation but the workaround not to close
|
||||
the handles will have a marginal hit of three extra handles per
|
||||
process at most. */
|
||||
|
@ -654,26 +655,26 @@ done:
|
|||
return res;
|
||||
}
|
||||
|
||||
select_record *
|
||||
dtable::select_read (int fd, select_record *s)
|
||||
bool
|
||||
dtable::select_read (int fd, select_stuff *ss)
|
||||
{
|
||||
if (not_open (fd))
|
||||
{
|
||||
set_errno (EBADF);
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
fhandler_base *fh = fds[fd];
|
||||
s = fh->select_read (s);
|
||||
select_record *s = fh->select_read (ss);
|
||||
s->fd = fd;
|
||||
if (!s->fh)
|
||||
s->fh = fh;
|
||||
s->thread_errno = 0;
|
||||
debug_printf ("%s fd %d", fh->get_name (), fd);
|
||||
return s;
|
||||
return true;
|
||||
}
|
||||
|
||||
select_record *
|
||||
dtable::select_write (int fd, select_record *s)
|
||||
bool
|
||||
dtable::select_write (int fd, select_stuff *ss)
|
||||
{
|
||||
if (not_open (fd))
|
||||
{
|
||||
|
@ -681,16 +682,16 @@ dtable::select_write (int fd, select_record *s)
|
|||
return NULL;
|
||||
}
|
||||
fhandler_base *fh = fds[fd];
|
||||
s = fh->select_write (s);
|
||||
select_record *s = fh->select_write (ss);
|
||||
s->fd = fd;
|
||||
s->fh = fh;
|
||||
s->thread_errno = 0;
|
||||
debug_printf ("%s fd %d", fh->get_name (), fd);
|
||||
return s;
|
||||
debug_printf ("%s fd %d", fh->get_name ());
|
||||
return true;
|
||||
}
|
||||
|
||||
select_record *
|
||||
dtable::select_except (int fd, select_record *s)
|
||||
bool
|
||||
dtable::select_except (int fd, select_stuff *ss)
|
||||
{
|
||||
if (not_open (fd))
|
||||
{
|
||||
|
@ -698,12 +699,12 @@ dtable::select_except (int fd, select_record *s)
|
|||
return NULL;
|
||||
}
|
||||
fhandler_base *fh = fds[fd];
|
||||
s = fh->select_except (s);
|
||||
select_record *s = fh->select_except (ss);
|
||||
s->fd = fd;
|
||||
s->fh = fh;
|
||||
s->thread_errno = 0;
|
||||
debug_printf ("%s fd %d", fh->get_name (), fd);
|
||||
return s;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -57,9 +57,9 @@ public:
|
|||
int dup2 (int oldfd, int newfd);
|
||||
void fixup_after_exec ();
|
||||
inline fhandler_base *&operator [](int fd) const { return fds[fd]; }
|
||||
select_record *select_read (int fd, select_record *s);
|
||||
select_record *select_write (int fd, select_record *s);
|
||||
select_record *select_except (int fd, select_record *s);
|
||||
bool select_read (int fd, select_stuff *);
|
||||
bool select_write (int fd, select_stuff *);
|
||||
bool select_except (int fd, select_stuff *);
|
||||
operator fhandler_base **() {return fds;}
|
||||
void stdio_init ();
|
||||
void get_debugger_info ();
|
||||
|
|
|
@ -37,6 +37,7 @@ extern const char proc[];
|
|||
extern const int proc_len;
|
||||
|
||||
class select_record;
|
||||
class select_stuff;
|
||||
class fhandler_disk_file;
|
||||
class inode_t;
|
||||
typedef struct __DIR DIR;
|
||||
|
@ -354,9 +355,9 @@ class fhandler_base
|
|||
virtual HANDLE& get_io_handle () { return io_handle; }
|
||||
virtual HANDLE& get_output_handle () { return io_handle; }
|
||||
virtual bool hit_eof () {return false;}
|
||||
virtual select_record *select_read (select_record *s);
|
||||
virtual select_record *select_write (select_record *s);
|
||||
virtual select_record *select_except (select_record *s);
|
||||
virtual select_record *select_read (select_stuff *);
|
||||
virtual select_record *select_write (select_stuff *);
|
||||
virtual select_record *select_except (select_stuff *);
|
||||
virtual int ready_for_read (int fd, DWORD howlong);
|
||||
virtual const char *get_native_name ()
|
||||
{
|
||||
|
@ -394,7 +395,7 @@ class fhandler_mailslot : public fhandler_base
|
|||
int open (int flags, mode_t mode = 0);
|
||||
int write (const void *ptr, size_t len);
|
||||
int ioctl (unsigned int cmd, void *);
|
||||
select_record *select_read (select_record *s);
|
||||
select_record *select_read (select_stuff *);
|
||||
};
|
||||
|
||||
struct wsa_event
|
||||
|
@ -507,9 +508,9 @@ class fhandler_socket: public fhandler_base
|
|||
void fixup_after_fork (HANDLE);
|
||||
char *get_proc_fd_name (char *buf);
|
||||
|
||||
select_record *select_read (select_record *s);
|
||||
select_record *select_write (select_record *s);
|
||||
select_record *select_except (select_record *s);
|
||||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
int ready_for_read (int, DWORD) { return true; }
|
||||
void set_addr_family (int af) {addr_family = af;}
|
||||
int get_addr_family () {return addr_family;}
|
||||
|
@ -543,9 +544,9 @@ public:
|
|||
void set_popen_pid (pid_t pid) {popen_pid = pid;}
|
||||
pid_t get_popen_pid () const {return popen_pid;}
|
||||
_off64_t lseek (_off64_t offset, int whence);
|
||||
select_record *select_read (select_record *s);
|
||||
select_record *select_write (select_record *s);
|
||||
select_record *select_except (select_record *s);
|
||||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
char *get_proc_fd_name (char *buf);
|
||||
void raw_read (void *ptr, size_t& len);
|
||||
int raw_write (const void *, size_t);
|
||||
|
@ -584,9 +585,9 @@ public:
|
|||
int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||
OVERLAPPED *get_overlapped () {return &io_status;}
|
||||
OVERLAPPED *get_overlapped_buffer () {return &io_status;}
|
||||
select_record *select_read (select_record *s);
|
||||
select_record *select_write (select_record *s);
|
||||
select_record *select_except (select_record *s);
|
||||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
};
|
||||
|
||||
class fhandler_dev_raw: public fhandler_base
|
||||
|
@ -784,9 +785,9 @@ class fhandler_serial: public fhandler_base
|
|||
permission checking on pgrps. */
|
||||
virtual int tcgetpgrp () { return pgrp_; }
|
||||
virtual int tcsetpgrp (const pid_t pid) { pgrp_ = pid; return 0; }
|
||||
select_record *select_read (select_record *s);
|
||||
select_record *select_write (select_record *s);
|
||||
select_record *select_except (select_record *s);
|
||||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
bool is_slow () {return true;}
|
||||
};
|
||||
|
||||
|
@ -964,9 +965,9 @@ class fhandler_console: public fhandler_termios
|
|||
void init (HANDLE, DWORD, mode_t);
|
||||
bool mouse_aware () {return dev_state->use_mouse;}
|
||||
|
||||
select_record *select_read (select_record *s);
|
||||
select_record *select_write (select_record *s);
|
||||
select_record *select_except (select_record *s);
|
||||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
void fixup_after_fork_exec (bool);
|
||||
void fixup_after_exec () {fixup_after_fork_exec (true);}
|
||||
void fixup_after_fork (HANDLE) {fixup_after_fork_exec (false);}
|
||||
|
@ -1006,9 +1007,9 @@ class fhandler_tty_common: public fhandler_termios
|
|||
int close ();
|
||||
_off64_t lseek (_off64_t, int);
|
||||
void set_close_on_exec (bool val);
|
||||
select_record *select_read (select_record *s);
|
||||
select_record *select_write (select_record *s);
|
||||
select_record *select_except (select_record *s);
|
||||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
bool is_slow () {return true;}
|
||||
};
|
||||
|
||||
|
@ -1033,7 +1034,7 @@ class fhandler_tty_slave: public fhandler_tty_common
|
|||
void fixup_after_fork (HANDLE parent);
|
||||
void fixup_after_exec ();
|
||||
|
||||
select_record *select_read (select_record *s);
|
||||
select_record *select_read (select_stuff *);
|
||||
int cygserver_attach_tty (HANDLE*, HANDLE*);
|
||||
int get_unit ();
|
||||
virtual char const *ttyname () { return pc.dev.name; }
|
||||
|
@ -1090,9 +1091,9 @@ class fhandler_dev_null: public fhandler_base
|
|||
public:
|
||||
fhandler_dev_null ();
|
||||
|
||||
select_record *select_read (select_record *s);
|
||||
select_record *select_write (select_record *s);
|
||||
select_record *select_except (select_record *s);
|
||||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
};
|
||||
|
||||
class fhandler_dev_zero: public fhandler_base
|
||||
|
@ -1194,9 +1195,9 @@ class fhandler_windows: public fhandler_base
|
|||
|
||||
void set_close_on_exec (bool val);
|
||||
void fixup_after_fork (HANDLE parent);
|
||||
select_record *select_read (select_record *s);
|
||||
select_record *select_write (select_record *s);
|
||||
select_record *select_except (select_record *s);
|
||||
select_record *select_read (select_stuff *);
|
||||
select_record *select_write (select_stuff *);
|
||||
select_record *select_except (select_stuff *);
|
||||
bool is_slow () {return true;}
|
||||
};
|
||||
|
||||
|
@ -1384,55 +1385,4 @@ typedef union
|
|||
char __virtual[sizeof (fhandler_virtual)];
|
||||
char __windows[sizeof (fhandler_windows)];
|
||||
} fhandler_union;
|
||||
|
||||
struct select_record
|
||||
{
|
||||
int fd;
|
||||
HANDLE h;
|
||||
fhandler_base *fh;
|
||||
int thread_errno;
|
||||
bool windows_handle;
|
||||
bool read_ready, write_ready, except_ready;
|
||||
bool read_selected, write_selected, except_selected;
|
||||
bool except_on_write;
|
||||
int (*startup) (select_record *me, class select_stuff *stuff);
|
||||
int (*peek) (select_record *, bool);
|
||||
int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds);
|
||||
void (*cleanup) (select_record *me, class select_stuff *stuff);
|
||||
struct select_record *next;
|
||||
void set_select_errno () {__seterrno (); thread_errno = errno;}
|
||||
int saw_error () {return thread_errno;}
|
||||
|
||||
select_record (fhandler_base *in_fh = NULL) : fd (0), h (NULL),
|
||||
fh (in_fh), thread_errno (0), windows_handle (false),
|
||||
read_ready (false), write_ready (false), except_ready (false),
|
||||
read_selected (false), write_selected (false),
|
||||
except_selected (false), except_on_write (false),
|
||||
startup (NULL), peek (NULL), verify (NULL), cleanup (NULL),
|
||||
next (NULL) {}
|
||||
};
|
||||
|
||||
class select_stuff
|
||||
{
|
||||
public:
|
||||
~select_stuff ();
|
||||
bool always_ready, windows_used;
|
||||
select_record start;
|
||||
void *device_specific_pipe;
|
||||
void *device_specific_socket;
|
||||
void *device_specific_serial;
|
||||
void *device_specific_mailslot;
|
||||
|
||||
int test_and_set (int i, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds);
|
||||
int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
|
||||
int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
|
||||
void cleanup ();
|
||||
select_stuff (): always_ready (0), windows_used (0), start (0),
|
||||
device_specific_pipe (0),
|
||||
device_specific_socket (0),
|
||||
device_specific_serial (0),
|
||||
device_specific_mailslot (0) {}
|
||||
};
|
||||
#endif /* _FHANDLER_H_ */
|
||||
|
|
|
@ -209,7 +209,7 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len)
|
|||
if (format == cygnativeformat)
|
||||
{
|
||||
unsigned char *buf;
|
||||
|
||||
|
||||
if (!(buf = (unsigned char *) GlobalLock (hglb)))
|
||||
{
|
||||
CloseClipboard ();
|
||||
|
|
|
@ -286,7 +286,7 @@ class inode_t
|
|||
|
||||
void wait () { ++i_wait; }
|
||||
void unwait () { if (i_wait > 0) --i_wait; }
|
||||
bool waiting () { return i_wait > 0; }
|
||||
bool waiting () { return i_wait > 0; }
|
||||
|
||||
lockf_t *get_all_locks_list ();
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@ class fs_info
|
|||
{
|
||||
struct status_flags
|
||||
{
|
||||
ULONG flags; /* Volume flags */
|
||||
ULONG samba_version; /* Samba version if available */
|
||||
ULONG flags; /* Volume flags */
|
||||
ULONG samba_version; /* Samba version if available */
|
||||
ULONG name_len; /* MaximumComponentNameLength */
|
||||
unsigned is_remote_drive : 1;
|
||||
unsigned has_buggy_open : 1;
|
||||
|
|
|
@ -27,6 +27,7 @@ details. */
|
|||
#include "security.h"
|
||||
#include "path.h"
|
||||
#include "fhandler.h"
|
||||
#include "select.h"
|
||||
#include "dtable.h"
|
||||
#include "cygheap.h"
|
||||
#include "pinfo.h"
|
||||
|
@ -68,7 +69,7 @@ typedef long fd_mask;
|
|||
#define UNIX_FD_ISSET(n, p) \
|
||||
((p)->fds_bits[(n)/UNIX_NFDBITS] & (1L << ((n) % UNIX_NFDBITS)))
|
||||
#define UNIX_FD_ZERO(p, n) \
|
||||
bzero ((caddr_t)(p), sizeof_fd_set ((n)))
|
||||
memset ((caddr_t) (p), 0, sizeof_fd_set ((n)))
|
||||
|
||||
#define allocfd_set(n) ((fd_set *) memset (alloca (sizeof_fd_set (n)), 0, sizeof_fd_set (n)))
|
||||
#define copyfd_set(to, from, n) memcpy (to, from, sizeof_fd_set (n));
|
||||
|
@ -205,19 +206,27 @@ select_stuff::~select_stuff ()
|
|||
}
|
||||
|
||||
/* Add a record to the select chain */
|
||||
int
|
||||
bool
|
||||
select_stuff::test_and_set (int i, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds)
|
||||
{
|
||||
select_record *s = NULL;
|
||||
if (UNIX_FD_ISSET (i, readfds) && (s = cygheap->fdtab.select_read (i, s)) == NULL)
|
||||
return 0; /* error */
|
||||
if (UNIX_FD_ISSET (i, writefds) && (s = cygheap->fdtab.select_write (i, s)) == NULL)
|
||||
return 0; /* error */
|
||||
if (UNIX_FD_ISSET (i, exceptfds) && (s = cygheap->fdtab.select_except (i, s)) == NULL)
|
||||
return 0; /* error */
|
||||
if (s == NULL)
|
||||
return 1; /* nothing to do */
|
||||
if (!UNIX_FD_ISSET (i, readfds) && !UNIX_FD_ISSET (i, writefds)
|
||||
&& ! UNIX_FD_ISSET (i, exceptfds))
|
||||
return true;
|
||||
|
||||
select_record *s = new select_record;
|
||||
if (!s)
|
||||
return false;
|
||||
|
||||
s->next = start.next;
|
||||
start.next = s;
|
||||
|
||||
if (UNIX_FD_ISSET (i, readfds) && !cygheap->fdtab.select_read (i, this))
|
||||
goto err;
|
||||
if (UNIX_FD_ISSET (i, writefds) && !cygheap->fdtab.select_write (i, this))
|
||||
goto err;
|
||||
if (UNIX_FD_ISSET (i, exceptfds) && !cygheap->fdtab.select_except (i, this))
|
||||
goto err; /* error */
|
||||
|
||||
if (s->read_ready || s->write_ready || s->except_ready)
|
||||
always_ready = true;
|
||||
|
@ -225,9 +234,12 @@ select_stuff::test_and_set (int i, fd_set *readfds, fd_set *writefds,
|
|||
if (s->windows_handle)
|
||||
windows_used = true;
|
||||
|
||||
s->next = start.next;
|
||||
start.next = s;
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
err:
|
||||
start.next = s->next;
|
||||
delete s;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* The heart of select. Waits for an fd to do something interesting. */
|
||||
|
@ -566,36 +578,61 @@ out:
|
|||
|
||||
static int start_thread_pipe (select_record *me, select_stuff *stuff);
|
||||
|
||||
struct pipeinf
|
||||
{
|
||||
cygthread *thread;
|
||||
bool stop_thread_pipe;
|
||||
select_record *start;
|
||||
};
|
||||
select_pipe_info::select_pipe_info ()
|
||||
{
|
||||
n = 1;
|
||||
w4[0] = CreateEvent (&sec_none_nih, true, false, NULL);
|
||||
}
|
||||
|
||||
select_pipe_info::~select_pipe_info ()
|
||||
{
|
||||
if (thread)
|
||||
{
|
||||
SetEvent (w4[0]);
|
||||
stop_thread = true;
|
||||
thread->detach ();
|
||||
}
|
||||
ForceCloseHandle (w4[0]);
|
||||
}
|
||||
|
||||
void
|
||||
select_pipe_info::add_watch_handle (fhandler_pipe *fh)
|
||||
{
|
||||
if (fh->get_overlapped () && fh->get_overlapped ()->hEvent)
|
||||
w4[n++] = fh->get_overlapped ()->hEvent;
|
||||
}
|
||||
|
||||
static DWORD WINAPI
|
||||
thread_pipe (void *arg)
|
||||
{
|
||||
pipeinf *pi = (pipeinf *) arg;
|
||||
select_pipe_info *pi = (select_pipe_info *) arg;
|
||||
bool gotone = false;
|
||||
DWORD sleep_time = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
select_record *s = pi->start;
|
||||
if (pi->n > 1)
|
||||
switch (WaitForMultipleObjects (pi->n, pi->w4, false, INFINITE))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
goto out;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
while ((s = s->next))
|
||||
if (s->startup == start_thread_pipe)
|
||||
{
|
||||
if (peek_pipe (s, true))
|
||||
gotone = true;
|
||||
if (pi->stop_thread_pipe)
|
||||
if (pi->stop_thread)
|
||||
{
|
||||
select_printf ("stopping");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* Paranoid check */
|
||||
if (pi->stop_thread_pipe)
|
||||
if (pi->stop_thread)
|
||||
{
|
||||
select_printf ("stopping from outer loop");
|
||||
break;
|
||||
|
@ -613,31 +650,27 @@ out:
|
|||
static int
|
||||
start_thread_pipe (select_record *me, select_stuff *stuff)
|
||||
{
|
||||
if (stuff->device_specific_pipe)
|
||||
select_pipe_info *pi = stuff->device_specific_pipe;
|
||||
if (pi->start)
|
||||
me->h = *((select_pipe_info *) stuff->device_specific_pipe)->thread;
|
||||
else
|
||||
{
|
||||
me->h = *((pipeinf *) stuff->device_specific_pipe)->thread;
|
||||
return 1;
|
||||
pi->start = &stuff->start;
|
||||
pi->stop_thread = false;
|
||||
pi->thread = new cygthread (thread_pipe, 0, pi, "select_pipe");
|
||||
me->h = *pi->thread;
|
||||
if (!me->h)
|
||||
return 0;
|
||||
}
|
||||
pipeinf *pi = new pipeinf;
|
||||
pi->start = &stuff->start;
|
||||
pi->stop_thread_pipe = false;
|
||||
pi->thread = new cygthread (thread_pipe, 0, pi, "select_pipe");
|
||||
me->h = *pi->thread;
|
||||
if (!me->h)
|
||||
return 0;
|
||||
stuff->device_specific_pipe = (void *) pi;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
pipe_cleanup (select_record *, select_stuff *stuff)
|
||||
{
|
||||
pipeinf *pi = (pipeinf *) stuff->device_specific_pipe;
|
||||
if (pi && pi->thread)
|
||||
if (stuff->device_specific_pipe)
|
||||
{
|
||||
pi->stop_thread_pipe = true;
|
||||
pi->thread->detach ();
|
||||
delete pi;
|
||||
delete stuff->device_specific_pipe;
|
||||
stuff->device_specific_pipe = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -654,10 +687,14 @@ fhandler_pipe::ready_for_read (int fd, DWORD howlong)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_pipe::select_read (select_record *s)
|
||||
fhandler_pipe::select_read (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
s = new select_record;
|
||||
if (!ss->device_specific_pipe
|
||||
&& (ss->device_specific_pipe = new select_pipe_info) == NULL)
|
||||
return NULL;
|
||||
ss->device_specific_pipe->add_watch_handle (this);
|
||||
|
||||
select_record *s = ss->start.next;
|
||||
s->startup = start_thread_pipe;
|
||||
s->peek = peek_pipe;
|
||||
s->verify = verify_ok;
|
||||
|
@ -668,10 +705,13 @@ fhandler_pipe::select_read (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_pipe::select_write (select_record *s)
|
||||
fhandler_pipe::select_write (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
s = new select_record;
|
||||
if (!ss->device_specific_pipe
|
||||
&& (ss->device_specific_pipe = new select_pipe_info) == NULL)
|
||||
return NULL;
|
||||
ss->device_specific_pipe->add_watch_handle (this);
|
||||
select_record *s = ss->start.next;
|
||||
s->startup = start_thread_pipe;
|
||||
s->peek = peek_pipe;
|
||||
s->verify = verify_ok;
|
||||
|
@ -682,10 +722,13 @@ fhandler_pipe::select_write (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_pipe::select_except (select_record *s)
|
||||
fhandler_pipe::select_except (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
s = new select_record;
|
||||
if (!ss->device_specific_pipe
|
||||
&& (ss->device_specific_pipe = new select_pipe_info) == NULL)
|
||||
return NULL;
|
||||
ss->device_specific_pipe->add_watch_handle (this);
|
||||
select_record *s = ss->start.next;
|
||||
s->startup = start_thread_pipe;
|
||||
s->peek = peek_pipe;
|
||||
s->verify = verify_ok;
|
||||
|
@ -696,10 +739,9 @@ fhandler_pipe::select_except (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_fifo::select_read (select_record *s)
|
||||
fhandler_fifo::select_read (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
s = new select_record;
|
||||
select_record *s = ss->start.next;
|
||||
s->startup = start_thread_pipe;
|
||||
s->peek = peek_pipe;
|
||||
s->verify = verify_ok;
|
||||
|
@ -710,10 +752,9 @@ fhandler_fifo::select_read (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_fifo::select_write (select_record *s)
|
||||
fhandler_fifo::select_write (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
s = new select_record;
|
||||
select_record *s = ss->start.next;
|
||||
s->startup = start_thread_pipe;
|
||||
s->peek = peek_pipe;
|
||||
s->verify = verify_ok;
|
||||
|
@ -724,10 +765,9 @@ fhandler_fifo::select_write (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_fifo::select_except (select_record *s)
|
||||
fhandler_fifo::select_except (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
s = new select_record;
|
||||
select_record *s = ss->start.next;
|
||||
s->startup = start_thread_pipe;
|
||||
s->peek = peek_pipe;
|
||||
s->verify = verify_ok;
|
||||
|
@ -804,11 +844,11 @@ verify_console (select_record *me, fd_set *rfds, fd_set *wfds,
|
|||
|
||||
|
||||
select_record *
|
||||
fhandler_console::select_read (select_record *s)
|
||||
fhandler_console::select_read (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = verify_console;
|
||||
set_cursor_maybe ();
|
||||
|
@ -822,11 +862,11 @@ fhandler_console::select_read (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_console::select_write (select_record *s)
|
||||
fhandler_console::select_write (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = no_verify;
|
||||
set_cursor_maybe ();
|
||||
|
@ -839,11 +879,11 @@ fhandler_console::select_write (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_console::select_except (select_record *s)
|
||||
fhandler_console::select_except (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = no_verify;
|
||||
set_cursor_maybe ();
|
||||
|
@ -856,21 +896,21 @@ fhandler_console::select_except (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_tty_common::select_read (select_record *s)
|
||||
fhandler_tty_common::select_read (select_stuff *ss)
|
||||
{
|
||||
return ((fhandler_pipe *) this)->fhandler_pipe::select_read (s);
|
||||
return ((fhandler_pipe *) this)->fhandler_pipe::select_read (ss);
|
||||
}
|
||||
|
||||
select_record *
|
||||
fhandler_tty_common::select_write (select_record *s)
|
||||
fhandler_tty_common::select_write (select_stuff *ss)
|
||||
{
|
||||
return ((fhandler_pipe *) this)->fhandler_pipe::select_write (s);
|
||||
return ((fhandler_pipe *) this)->fhandler_pipe::select_write (ss);
|
||||
}
|
||||
|
||||
select_record *
|
||||
fhandler_tty_common::select_except (select_record *s)
|
||||
fhandler_tty_common::select_except (select_stuff *ss)
|
||||
{
|
||||
return ((fhandler_pipe *) this)->fhandler_pipe::select_except (s);
|
||||
return ((fhandler_pipe *) this)->fhandler_pipe::select_except (ss);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -883,10 +923,9 @@ verify_tty_slave (select_record *me, fd_set *readfds, fd_set *writefds,
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_tty_slave::select_read (select_record *s)
|
||||
fhandler_tty_slave::select_read (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
s = new select_record;
|
||||
select_record *s = ss->start.next;
|
||||
s->h = input_available_event;
|
||||
s->startup = no_startup;
|
||||
s->peek = peek_pipe;
|
||||
|
@ -898,11 +937,11 @@ fhandler_tty_slave::select_read (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_dev_null::select_read (select_record *s)
|
||||
fhandler_dev_null::select_read (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = no_verify;
|
||||
}
|
||||
|
@ -913,11 +952,11 @@ fhandler_dev_null::select_read (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_dev_null::select_write (select_record *s)
|
||||
fhandler_dev_null::select_write (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = no_verify;
|
||||
}
|
||||
|
@ -928,11 +967,11 @@ fhandler_dev_null::select_write (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_dev_null::select_except (select_record *s)
|
||||
fhandler_dev_null::select_except (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = no_verify;
|
||||
}
|
||||
|
@ -944,13 +983,6 @@ fhandler_dev_null::select_except (select_record *s)
|
|||
|
||||
static int start_thread_serial (select_record *me, select_stuff *stuff);
|
||||
|
||||
struct serialinf
|
||||
{
|
||||
cygthread *thread;
|
||||
bool stop_thread_serial;
|
||||
select_record *start;
|
||||
};
|
||||
|
||||
static int
|
||||
peek_serial (select_record *s, bool)
|
||||
{
|
||||
|
@ -1057,7 +1089,7 @@ err:
|
|||
static DWORD WINAPI
|
||||
thread_serial (void *arg)
|
||||
{
|
||||
serialinf *si = (serialinf *) arg;
|
||||
select_serial_info *si = (select_serial_info *) arg;
|
||||
bool gotone = false;
|
||||
|
||||
for (;;)
|
||||
|
@ -1069,7 +1101,7 @@ thread_serial (void *arg)
|
|||
if (peek_serial (s, true))
|
||||
gotone = true;
|
||||
}
|
||||
if (si->stop_thread_serial)
|
||||
if (si->stop_thread)
|
||||
{
|
||||
select_printf ("stopping");
|
||||
break;
|
||||
|
@ -1086,26 +1118,26 @@ static int
|
|||
start_thread_serial (select_record *me, select_stuff *stuff)
|
||||
{
|
||||
if (stuff->device_specific_serial)
|
||||
me->h = *((select_serial_info *) stuff->device_specific_serial)->thread;
|
||||
else
|
||||
{
|
||||
me->h = *((serialinf *) stuff->device_specific_serial)->thread;
|
||||
return 1;
|
||||
select_serial_info *si = new select_serial_info;
|
||||
si->start = &stuff->start;
|
||||
si->stop_thread = false;
|
||||
si->thread = new cygthread (thread_serial, 0, si, "select_serial");
|
||||
me->h = *si->thread;
|
||||
stuff->device_specific_serial = si;
|
||||
}
|
||||
serialinf *si = new serialinf;
|
||||
si->start = &stuff->start;
|
||||
si->stop_thread_serial = false;
|
||||
si->thread = new cygthread (thread_serial, 0, si, "select_serial");
|
||||
me->h = *si->thread;
|
||||
stuff->device_specific_serial = (void *) si;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
serial_cleanup (select_record *, select_stuff *stuff)
|
||||
{
|
||||
serialinf *si = (serialinf *) stuff->device_specific_serial;
|
||||
select_serial_info *si = (select_serial_info *) stuff->device_specific_serial;
|
||||
if (si && si->thread)
|
||||
{
|
||||
si->stop_thread_serial = true;
|
||||
si->stop_thread = true;
|
||||
si->thread->detach ();
|
||||
delete si;
|
||||
stuff->device_specific_serial = NULL;
|
||||
|
@ -1113,11 +1145,11 @@ serial_cleanup (select_record *, select_stuff *stuff)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_serial::select_read (select_record *s)
|
||||
fhandler_serial::select_read (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = start_thread_serial;
|
||||
s->verify = verify_ok;
|
||||
s->cleanup = serial_cleanup;
|
||||
|
@ -1129,11 +1161,11 @@ fhandler_serial::select_read (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_serial::select_write (select_record *s)
|
||||
fhandler_serial::select_write (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = verify_ok;
|
||||
}
|
||||
|
@ -1145,11 +1177,11 @@ fhandler_serial::select_write (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_serial::select_except (select_record *s)
|
||||
fhandler_serial::select_except (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = verify_ok;
|
||||
}
|
||||
|
@ -1164,46 +1196,57 @@ int
|
|||
fhandler_base::ready_for_read (int fd, DWORD howlong)
|
||||
{
|
||||
bool avail = false;
|
||||
select_record me (this);
|
||||
me.fd = fd;
|
||||
while (!avail)
|
||||
|
||||
select_stuff sel;
|
||||
fd_set *thisfd = allocfd_set (fd + 1);
|
||||
fd_set *dummy_writefds = allocfd_set (fd + 1);
|
||||
fd_set *dummy_exceptfds = allocfd_set (fd + 1);
|
||||
UNIX_FD_SET(fd, thisfd);
|
||||
|
||||
if (!sel.test_and_set (fd, thisfd, dummy_writefds, dummy_exceptfds))
|
||||
select_printf ("aborting due to test_and_set error");
|
||||
else
|
||||
{
|
||||
select_read (&me);
|
||||
avail = me.read_ready ?: me.peek (&me, false);
|
||||
|
||||
if (fd >= 0 && cygheap->fdtab.not_open (fd))
|
||||
select_record *me = sel.start.next;
|
||||
while (!avail)
|
||||
{
|
||||
set_sig_errno (EBADF);
|
||||
avail = false;
|
||||
break;
|
||||
}
|
||||
avail = me->read_ready ?: me->peek (me, false);
|
||||
|
||||
if (howlong != INFINITE)
|
||||
{
|
||||
if (!avail)
|
||||
set_sig_errno (EAGAIN);
|
||||
break;
|
||||
}
|
||||
if (fd >= 0 && cygheap->fdtab.not_open (fd))
|
||||
{
|
||||
set_sig_errno (EBADF);
|
||||
avail = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (WaitForSingleObject (signal_arrived, avail ? 0 : 10) == WAIT_OBJECT_0)
|
||||
{
|
||||
debug_printf ("interrupted");
|
||||
set_sig_errno (EINTR);
|
||||
avail = false;
|
||||
break;
|
||||
if (howlong != INFINITE)
|
||||
{
|
||||
if (!avail)
|
||||
set_sig_errno (EAGAIN);
|
||||
break;
|
||||
}
|
||||
|
||||
if (WaitForSingleObject (signal_arrived, avail ? 0 : 10) == WAIT_OBJECT_0)
|
||||
{
|
||||
debug_printf ("interrupted");
|
||||
set_sig_errno (EINTR);
|
||||
avail = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
select_printf ("read_ready %d, avail %d", me.read_ready, avail);
|
||||
select_printf ("read_ready %d, avail %d", sel.start.next->read_ready, avail);
|
||||
sel.cleanup ();
|
||||
return avail;
|
||||
}
|
||||
|
||||
select_record *
|
||||
fhandler_base::select_read (select_record *s)
|
||||
fhandler_base::select_read (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = verify_ok;
|
||||
}
|
||||
|
@ -1214,11 +1257,11 @@ fhandler_base::select_read (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_base::select_write (select_record *s)
|
||||
fhandler_base::select_write (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = verify_ok;
|
||||
}
|
||||
|
@ -1229,11 +1272,11 @@ fhandler_base::select_write (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_base::select_except (select_record *s)
|
||||
fhandler_base::select_except (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = verify_ok;
|
||||
}
|
||||
|
@ -1268,20 +1311,10 @@ peek_socket (select_record *me, bool)
|
|||
|
||||
static int start_thread_socket (select_record *, select_stuff *);
|
||||
|
||||
struct socketinf
|
||||
{
|
||||
cygthread *thread;
|
||||
int max_w4;
|
||||
int num_w4;
|
||||
LONG *ser_num;
|
||||
HANDLE *w4;
|
||||
select_record *start;
|
||||
};
|
||||
|
||||
static DWORD WINAPI
|
||||
thread_socket (void *arg)
|
||||
{
|
||||
socketinf *si = (socketinf *) arg;
|
||||
select_socket_info *si = (select_socket_info *) arg;
|
||||
DWORD timeout = 64 / (si->max_w4 / MAXIMUM_WAIT_OBJECTS);
|
||||
bool event = false;
|
||||
|
||||
|
@ -1317,15 +1350,15 @@ out:
|
|||
static int
|
||||
start_thread_socket (select_record *me, select_stuff *stuff)
|
||||
{
|
||||
socketinf *si;
|
||||
select_socket_info *si;
|
||||
|
||||
if ((si = (socketinf *) stuff->device_specific_socket))
|
||||
if ((si = (select_socket_info *) stuff->device_specific_socket))
|
||||
{
|
||||
me->h = *si->thread;
|
||||
return 1;
|
||||
}
|
||||
|
||||
si = new socketinf;
|
||||
si = new select_socket_info;
|
||||
si->ser_num = (LONG *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (LONG));
|
||||
si->w4 = (HANDLE *) malloc (MAXIMUM_WAIT_OBJECTS * sizeof (HANDLE));
|
||||
if (!si->ser_num || !si->w4)
|
||||
|
@ -1370,7 +1403,7 @@ start_thread_socket (select_record *me, select_stuff *stuff)
|
|||
continue_outer_loop:
|
||||
;
|
||||
}
|
||||
stuff->device_specific_socket = (void *) si;
|
||||
stuff->device_specific_socket = si;
|
||||
si->start = &stuff->start;
|
||||
select_printf ("stuff_start %p", &stuff->start);
|
||||
si->thread = new cygthread (thread_socket, 0, si, "select_socket");
|
||||
|
@ -1381,7 +1414,7 @@ start_thread_socket (select_record *me, select_stuff *stuff)
|
|||
void
|
||||
socket_cleanup (select_record *, select_stuff *stuff)
|
||||
{
|
||||
socketinf *si = (socketinf *) stuff->device_specific_socket;
|
||||
select_socket_info *si = (select_socket_info *) stuff->device_specific_socket;
|
||||
select_printf ("si %p si->thread %p", si, si ? si->thread : NULL);
|
||||
if (si && si->thread)
|
||||
{
|
||||
|
@ -1400,11 +1433,11 @@ socket_cleanup (select_record *, select_stuff *stuff)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_socket::select_read (select_record *s)
|
||||
fhandler_socket::select_read (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = start_thread_socket;
|
||||
s->verify = verify_true;
|
||||
s->cleanup = socket_cleanup;
|
||||
|
@ -1416,11 +1449,11 @@ fhandler_socket::select_read (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_socket::select_write (select_record *s)
|
||||
fhandler_socket::select_write (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = start_thread_socket;
|
||||
s->verify = verify_true;
|
||||
s->cleanup = socket_cleanup;
|
||||
|
@ -1437,11 +1470,11 @@ fhandler_socket::select_write (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_socket::select_except (select_record *s)
|
||||
fhandler_socket::select_except (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = start_thread_socket;
|
||||
s->verify = verify_true;
|
||||
s->cleanup = socket_cleanup;
|
||||
|
@ -1482,11 +1515,11 @@ verify_windows (select_record *me, fd_set *rfds, fd_set *wfds,
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_windows::select_read (select_record *s)
|
||||
fhandler_windows::select_read (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
}
|
||||
s->verify = verify_windows;
|
||||
|
@ -1499,11 +1532,11 @@ fhandler_windows::select_read (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_windows::select_write (select_record *s)
|
||||
fhandler_windows::select_write (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = verify_ok;
|
||||
}
|
||||
|
@ -1516,11 +1549,11 @@ fhandler_windows::select_write (select_record *s)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_windows::select_except (select_record *s)
|
||||
fhandler_windows::select_except (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
select_record *s = ss->start.next;
|
||||
if (!s->startup)
|
||||
{
|
||||
s = new select_record;
|
||||
s->startup = no_startup;
|
||||
s->verify = verify_ok;
|
||||
}
|
||||
|
@ -1565,17 +1598,10 @@ verify_mailslot (select_record *me, fd_set *rfds, fd_set *wfds,
|
|||
|
||||
static int start_thread_mailslot (select_record *me, select_stuff *stuff);
|
||||
|
||||
struct mailslotinf
|
||||
{
|
||||
cygthread *thread;
|
||||
bool stop_thread_mailslot;
|
||||
select_record *start;
|
||||
};
|
||||
|
||||
static DWORD WINAPI
|
||||
thread_mailslot (void *arg)
|
||||
{
|
||||
mailslotinf *mi = (mailslotinf *) arg;
|
||||
select_mailslot_info *mi = (select_mailslot_info *) arg;
|
||||
bool gotone = false;
|
||||
DWORD sleep_time = 0;
|
||||
|
||||
|
@ -1587,14 +1613,14 @@ thread_mailslot (void *arg)
|
|||
{
|
||||
if (peek_mailslot (s, true))
|
||||
gotone = true;
|
||||
if (mi->stop_thread_mailslot)
|
||||
if (mi->stop_thread)
|
||||
{
|
||||
select_printf ("stopping");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* Paranoid check */
|
||||
if (mi->stop_thread_mailslot)
|
||||
if (mi->stop_thread)
|
||||
{
|
||||
select_printf ("stopping from outer loop");
|
||||
break;
|
||||
|
@ -1614,27 +1640,27 @@ start_thread_mailslot (select_record *me, select_stuff *stuff)
|
|||
{
|
||||
if (stuff->device_specific_mailslot)
|
||||
{
|
||||
me->h = *((mailslotinf *) stuff->device_specific_mailslot)->thread;
|
||||
me->h = *((select_mailslot_info *) stuff->device_specific_mailslot)->thread;
|
||||
return 1;
|
||||
}
|
||||
mailslotinf *mi = new mailslotinf;
|
||||
select_mailslot_info *mi = new select_mailslot_info;
|
||||
mi->start = &stuff->start;
|
||||
mi->stop_thread_mailslot = false;
|
||||
mi->stop_thread = false;
|
||||
mi->thread = new cygthread (thread_mailslot, 0, mi, "select_mailslot");
|
||||
me->h = *mi->thread;
|
||||
if (!me->h)
|
||||
return 0;
|
||||
stuff->device_specific_mailslot = (void *) mi;
|
||||
stuff->device_specific_mailslot = mi;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
mailslot_cleanup (select_record *, select_stuff *stuff)
|
||||
{
|
||||
mailslotinf *mi = (mailslotinf *) stuff->device_specific_mailslot;
|
||||
select_mailslot_info *mi = (select_mailslot_info *) stuff->device_specific_mailslot;
|
||||
if (mi && mi->thread)
|
||||
{
|
||||
mi->stop_thread_mailslot = true;
|
||||
mi->stop_thread = true;
|
||||
mi->thread->detach ();
|
||||
delete mi;
|
||||
stuff->device_specific_mailslot = NULL;
|
||||
|
@ -1642,10 +1668,9 @@ mailslot_cleanup (select_record *, select_stuff *stuff)
|
|||
}
|
||||
|
||||
select_record *
|
||||
fhandler_mailslot::select_read (select_record *s)
|
||||
fhandler_mailslot::select_read (select_stuff *ss)
|
||||
{
|
||||
if (!s)
|
||||
s = new select_record;
|
||||
select_record *s = ss->start.next;
|
||||
s->startup = start_thread_mailslot;
|
||||
s->peek = peek_mailslot;
|
||||
s->verify = verify_mailslot;
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/* select.h
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
2005, 2006, 2007, 2008, 2009 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
This software is a copyrighted work licensed under the terms of the
|
||||
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
||||
details. */
|
||||
|
||||
#ifndef _SELECT_H_
|
||||
#define _SELECT_H_
|
||||
|
||||
struct select_record
|
||||
{
|
||||
int fd;
|
||||
HANDLE h;
|
||||
fhandler_base *fh;
|
||||
int thread_errno;
|
||||
bool windows_handle;
|
||||
bool read_ready, write_ready, except_ready;
|
||||
bool read_selected, write_selected, except_selected;
|
||||
bool except_on_write;
|
||||
int (*startup) (select_record *me, class select_stuff *stuff);
|
||||
int (*peek) (select_record *, bool);
|
||||
int (*verify) (select_record *me, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds);
|
||||
void (*cleanup) (select_record *me, class select_stuff *stuff);
|
||||
struct select_record *next;
|
||||
void set_select_errno () {__seterrno (); thread_errno = errno;}
|
||||
int saw_error () {return thread_errno;}
|
||||
select_record () {}
|
||||
select_record (int): fd (0), h (NULL), fh (NULL), thread_errno (0),
|
||||
windows_handle (false), read_ready (false), write_ready (false),
|
||||
except_ready (false), read_selected (false), write_selected (false),
|
||||
except_selected (false), except_on_write (false),
|
||||
startup (NULL), peek (NULL), verify (NULL), cleanup (NULL),
|
||||
next (NULL) {}
|
||||
};
|
||||
|
||||
struct select_info
|
||||
{
|
||||
cygthread *thread;
|
||||
bool stop_thread;
|
||||
select_record *start;
|
||||
select_info () {}
|
||||
};
|
||||
|
||||
struct select_pipe_info: public select_info
|
||||
{
|
||||
DWORD n;
|
||||
HANDLE w4[MAXIMUM_WAIT_OBJECTS];
|
||||
select_pipe_info ();
|
||||
~select_pipe_info ();
|
||||
void add_watch_handle (fhandler_pipe *);
|
||||
};
|
||||
|
||||
struct select_socket_info: public select_info
|
||||
{
|
||||
int max_w4;
|
||||
int num_w4;
|
||||
LONG *ser_num;
|
||||
HANDLE *w4;
|
||||
};
|
||||
|
||||
struct select_serial_info: public select_info
|
||||
{
|
||||
};
|
||||
|
||||
struct select_mailslot_info: public select_info
|
||||
{
|
||||
};
|
||||
|
||||
class select_stuff
|
||||
{
|
||||
public:
|
||||
~select_stuff ();
|
||||
bool always_ready, windows_used;
|
||||
select_record start;
|
||||
|
||||
select_pipe_info *device_specific_pipe;
|
||||
select_socket_info *device_specific_socket;
|
||||
select_serial_info *device_specific_serial;
|
||||
select_mailslot_info *device_specific_mailslot;
|
||||
|
||||
bool test_and_set (int i, fd_set *readfds, fd_set *writefds,
|
||||
fd_set *exceptfds);
|
||||
int poll (fd_set *readfds, fd_set *writefds, fd_set *exceptfds);
|
||||
int wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds, DWORD ms);
|
||||
void cleanup ();
|
||||
select_stuff (): always_ready (0), windows_used (0), start (0),
|
||||
device_specific_pipe (0),
|
||||
device_specific_socket (0),
|
||||
device_specific_serial (0),
|
||||
device_specific_mailslot (0) {}
|
||||
};
|
||||
#endif /* _SELECT_H_ */
|
|
@ -151,7 +151,7 @@ __db_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n, UINT cp,
|
|||
|
||||
if (n == 0)
|
||||
return -2;
|
||||
|
||||
|
||||
if (pwc == NULL)
|
||||
pwc = &dummy;
|
||||
|
||||
|
@ -221,7 +221,7 @@ __eucjp_mbtowc (struct _reent *r, wchar_t *pwc, const char *s, size_t n,
|
|||
|
||||
if (n == 0)
|
||||
return -2;
|
||||
|
||||
|
||||
if (pwc == NULL)
|
||||
pwc = &dummy;
|
||||
|
||||
|
@ -437,7 +437,7 @@ sys_cp_wcstombs (wctomb_p f_wctomb, char *charset, char *dst, size_t len,
|
|||
bytes = 1;
|
||||
}
|
||||
else if (bytes == -1 && *charset != 'U'/*TF-8*/)
|
||||
{
|
||||
{
|
||||
/* Convert chars invalid in the current codepage to a sequence
|
||||
ASCII SO; UTF-8 representation of invalid char. */
|
||||
buf[0] = 0x0e; /* ASCII SO */
|
||||
|
@ -460,20 +460,20 @@ sys_cp_wcstombs (wctomb_p f_wctomb, char *charset, char *dst, size_t len,
|
|||
}
|
||||
bytes += __utf8_wctomb (_REENT, buf + bytes, *pwcs, charset, &ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n + bytes <= len)
|
||||
{
|
||||
n += bytes;
|
||||
if (dst)
|
||||
{
|
||||
for (int i = 0; i < bytes; ++i)
|
||||
*ptr++ = buf[i];
|
||||
}
|
||||
if (*pwcs++ == 0x00)
|
||||
{
|
||||
n += bytes;
|
||||
if (dst)
|
||||
{
|
||||
for (int i = 0; i < bytes; ++i)
|
||||
*ptr++ = buf[i];
|
||||
}
|
||||
if (*pwcs++ == 0x00)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
break;
|
||||
}
|
||||
if (n && dst)
|
||||
{
|
||||
|
@ -558,10 +558,10 @@ sys_cp_mbstowcs (mbtowc_p f_mbtowc, char *charset, wchar_t *dst, size_t dlen,
|
|||
if (bytes < 0)
|
||||
{
|
||||
/* Invalid UTF-8 sequence? Treat the ASCII SO character as
|
||||
stand-alone ASCII SO char. */
|
||||
stand-alone ASCII SO char. */
|
||||
bytes = 1;
|
||||
if (dst)
|
||||
*ptr = 0x0e;
|
||||
*ptr = 0x0e;
|
||||
memset (&ps, 0, sizeof ps);
|
||||
break;
|
||||
}
|
||||
|
@ -602,13 +602,13 @@ sys_cp_mbstowcs (mbtowc_p f_mbtowc, char *charset, wchar_t *dst, size_t dlen,
|
|||
}
|
||||
|
||||
if (bytes > 0)
|
||||
{
|
||||
pmbs += bytes;
|
||||
nms -= bytes;
|
||||
++count;
|
||||
{
|
||||
pmbs += bytes;
|
||||
nms -= bytes;
|
||||
++count;
|
||||
ptr = dst ? ptr + 1 : NULL;
|
||||
--len;
|
||||
}
|
||||
--len;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bytes == 0)
|
||||
|
|
|
@ -547,7 +547,7 @@ unlink_nt (path_conv &pc)
|
|||
way (for instance, font files) by setting the delete disposition fails
|
||||
with STATUS_CANNOT_DELETE. Strange enough, deleting these hardlinks
|
||||
using delete-on-close semantic works... most of the time.
|
||||
|
||||
|
||||
Don't use delete-on-close on remote shares. If two processes
|
||||
have open handles on a file and one of them calls unlink, the
|
||||
file is removed from the remote share even though the other
|
||||
|
@ -556,7 +556,7 @@ unlink_nt (path_conv &pc)
|
|||
Microsoft KB 837665 describes this problem as a bug in 2K3, but
|
||||
I have reproduced it on other systems. */
|
||||
if (status == STATUS_CANNOT_DELETE && !pc.isremote ())
|
||||
{
|
||||
{
|
||||
HANDLE fh2;
|
||||
UNICODE_STRING fname;
|
||||
|
||||
|
@ -573,11 +573,11 @@ unlink_nt (path_conv &pc)
|
|||
syscall_printf ("Setting delete-on-close failed, status = %p",
|
||||
status);
|
||||
/* This is really the last chance. If it hasn't been moved
|
||||
to the bin already, try it now. If moving to the bin
|
||||
to the bin already, try it now. If moving to the bin
|
||||
succeeds, we got rid of the file in some way, even if
|
||||
unlinking didn't work. */
|
||||
if (bin_stat == dont_move)
|
||||
bin_stat = try_to_bin (pc, fh, access);
|
||||
bin_stat = try_to_bin (pc, fh, access);
|
||||
if (bin_stat == has_been_moved)
|
||||
status = STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -1563,7 +1563,7 @@ static void
|
|||
start_transaction (HANDLE &old_trans, HANDLE &trans)
|
||||
{
|
||||
NTSTATUS status = NtCreateTransaction (&trans,
|
||||
SYNCHRONIZE | TRANSACTION_ALL_ACCESS,
|
||||
SYNCHRONIZE | TRANSACTION_ALL_ACCESS,
|
||||
NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
|
||||
if (NT_SUCCESS (status))
|
||||
{
|
||||
|
|
|
@ -98,7 +98,7 @@ class pinfo;
|
|||
#define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
|
||||
#define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
|
||||
|
||||
#define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
|
||||
#define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
|
||||
|
||||
/* verifyable_object should not be defined here - it's a general purpose class */
|
||||
|
||||
|
|
Loading…
Reference in New Issue