* 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:
Christopher Faylor 2012-06-27 21:42:11 +00:00
parent c60437258a
commit b052bf2671
4 changed files with 51 additions and 33 deletions

View File

@ -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

View File

@ -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

View File

@ -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
{

View File

@ -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_ */