* cygwait.h (cancelable_wait): Make extern to avoid always including.
* select.cc (allocfd_set): Try to make a little more efficient. (cygwin_select): Break into two functions to avoid what seems to be a strange compiler problem with alloca and sel constructor. (select): New function. Always honor return from call_signal_handler. (select_stuff::wait): Always honor return from call_signal_handler. * select.h (select_stuff::select_stuff): Use NULL to initialize pointers rather than 0.
This commit is contained in:
parent
c60437258a
commit
b052bf2671
@ -1,3 +1,14 @@
|
||||
2012-06-27 Christopher Faylor <me.cygwin2012@cgf.cx>
|
||||
|
||||
* cygwait.h (cancelable_wait): Make extern to avoid always including.
|
||||
* select.cc (allocfd_set): Try to make a little more efficient.
|
||||
(cygwin_select): Break into two functions to avoid what seems to be a
|
||||
strange compiler problem with alloca and sel constructor.
|
||||
(select): New function. Always honor return from call_signal_handler.
|
||||
(select_stuff::wait): Always honor return from call_signal_handler.
|
||||
* select.h (select_stuff::select_stuff): Use NULL to initialize
|
||||
pointers rather than 0.
|
||||
|
||||
2012-06-27 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* exceptions.cc (exception::handle): Cast exception code to NTSTATUS
|
||||
|
@ -29,11 +29,11 @@ DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
|
||||
unsigned = cw_std_mask)
|
||||
__attribute__ ((regparm (3)));
|
||||
|
||||
static inline DWORD __attribute__ ((always_inline))
|
||||
extern inline DWORD __attribute__ ((always_inline))
|
||||
cancelable_wait (HANDLE h, DWORD howlong, unsigned mask)
|
||||
{
|
||||
PLARGE_INTEGER pli_howlong;
|
||||
LARGE_INTEGER li_howlong;
|
||||
PLARGE_INTEGER pli_howlong;
|
||||
if (howlong == INFINITE)
|
||||
pli_howlong = NULL;
|
||||
else
|
||||
|
@ -73,7 +73,13 @@ typedef long fd_mask;
|
||||
#define UNIX_FD_ZERO(p, 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 allocfd_set(n) ({\
|
||||
size_t __sfds = sizeof_fd_set (n) + 8; \
|
||||
void *__res = alloca (__sfds); \
|
||||
memset (__res, 0, __sfds); \
|
||||
(fd_set *) __res; \
|
||||
})
|
||||
|
||||
#define copyfd_set(to, from, n) memcpy (to, from, sizeof_fd_set (n));
|
||||
|
||||
#define set_handle_or_return_if_not_open(h, s) \
|
||||
@ -84,31 +90,15 @@ typedef long fd_mask;
|
||||
return -1; \
|
||||
}
|
||||
|
||||
/* The main select code.
|
||||
*/
|
||||
static int select (int, fd_set *, fd_set *, fd_set *, DWORD);
|
||||
|
||||
/* The main select code. */
|
||||
extern "C" int
|
||||
cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
struct timeval *to)
|
||||
{
|
||||
select_printf ("select(%d, %p, %p, %p, %p)", maxfds, readfds, writefds, exceptfds, to);
|
||||
|
||||
select_stuff sel;
|
||||
fd_set *dummy_readfds = allocfd_set (maxfds);
|
||||
fd_set *dummy_writefds = allocfd_set (maxfds);
|
||||
fd_set *dummy_exceptfds = allocfd_set (maxfds);
|
||||
|
||||
/* Allocate some fd_set structures using the number of fds as a guide. */
|
||||
fd_set *r = allocfd_set (maxfds);
|
||||
fd_set *w = allocfd_set (maxfds);
|
||||
fd_set *e = allocfd_set (maxfds);
|
||||
|
||||
if (!readfds)
|
||||
readfds = dummy_readfds;
|
||||
if (!writefds)
|
||||
writefds = dummy_writefds;
|
||||
if (!exceptfds)
|
||||
exceptfds = dummy_exceptfds;
|
||||
|
||||
pthread_testcancel ();
|
||||
|
||||
/* Convert to milliseconds or INFINITE if to == NULL */
|
||||
@ -121,12 +111,33 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
else
|
||||
select_printf ("to NULL, ms %x", ms);
|
||||
|
||||
sel.return_on_signal = &_my_tls == _main_tls;
|
||||
int res = select (maxfds, readfds ?: allocfd_set (maxfds),
|
||||
writefds ?: allocfd_set (maxfds),
|
||||
exceptfds ?: allocfd_set (maxfds), ms);
|
||||
syscall_printf ("%R = select(%d, %p, %p, %p, %p)", res, maxfds, readfds,
|
||||
writefds, exceptfds, to);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* This function is arbitrarily split out from cygwin_select to avoid odd
|
||||
gcc issues with the use of allocfd_set and improper constructor handling
|
||||
for the sel variable. */
|
||||
static int
|
||||
select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
DWORD ms)
|
||||
{
|
||||
int res = select_stuff::select_loop;
|
||||
|
||||
LONGLONG start_time = gtod.msecs (); /* Record the current time for later use. */
|
||||
|
||||
select_stuff sel;
|
||||
sel.return_on_signal = 0;
|
||||
|
||||
/* Allocate some fd_set structures using the number of fds as a guide. */
|
||||
fd_set *r = allocfd_set (maxfds);
|
||||
fd_set *w = allocfd_set (maxfds);
|
||||
fd_set *e = allocfd_set (maxfds);
|
||||
|
||||
while (res == select_stuff::select_loop)
|
||||
{
|
||||
/* Build the select record per fd linked list and set state as
|
||||
@ -146,8 +157,7 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
{
|
||||
case WAIT_SIGNALED:
|
||||
select_printf ("signal received");
|
||||
_my_tls.call_signal_handler ();
|
||||
if (!sel.return_on_signal)
|
||||
if (_my_tls.call_signal_handler ())
|
||||
res = select_stuff::select_loop; /* Emulate linux behavior */
|
||||
else
|
||||
{
|
||||
@ -199,8 +209,6 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
||||
|
||||
if (res < -1)
|
||||
res = -1;
|
||||
syscall_printf ("%R = select(%d, %p, %p, %p, %p)", res, maxfds, readfds,
|
||||
writefds, exceptfds, to);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -365,8 +373,7 @@ next_while:;
|
||||
be assured that a signal handler won't jump out of select entirely. */
|
||||
cleanup ();
|
||||
destroy ();
|
||||
_my_tls.call_signal_handler ();
|
||||
if (!return_on_signal)
|
||||
if (_my_tls.call_signal_handler ())
|
||||
res = select_loop;
|
||||
else
|
||||
{
|
||||
|
@ -97,9 +97,9 @@ public:
|
||||
|
||||
select_stuff (): return_on_signal (false), always_ready (false),
|
||||
windows_used (false), start (0),
|
||||
device_specific_pipe (0),
|
||||
device_specific_socket (0),
|
||||
device_specific_serial (0),
|
||||
device_specific_mailslot (0) {}
|
||||
device_specific_pipe (NULL),
|
||||
device_specific_socket (NULL),
|
||||
device_specific_serial (NULL),
|
||||
device_specific_mailslot (NULL) {}
|
||||
};
|
||||
#endif /* _SELECT_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user