Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2012-06-28 01:42:11 +0400
committerChristopher Faylor <me@cgf.cx>2012-06-28 01:42:11 +0400
commitb052bf2671137fbae0b70e6950af2beffb076309 (patch)
tree14ee283644bcd31247927959f8b1fa72d75b0045 /winsup
parentc60437258a05fddbb9994e8714691ffc0bfd606e (diff)
* 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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/cygwait.h4
-rw-r--r--winsup/cygwin/select.cc61
-rw-r--r--winsup/cygwin/select.h8
4 files changed, 51 insertions, 33 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index eaa6b8c75..e52a02daf 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/cygwait.h b/winsup/cygwin/cygwait.h
index 6a004626e..0303ec3b6 100644
--- a/winsup/cygwin/cygwait.h
+++ b/winsup/cygwin/cygwait.h
@@ -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
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 0186af733..8d131291e 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -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
{
diff --git a/winsup/cygwin/select.h b/winsup/cygwin/select.h
index 0afccbd9d..fe0c206d5 100644
--- a/winsup/cygwin/select.h
+++ b/winsup/cygwin/select.h
@@ -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_ */