You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Justin Erenkrantz <ju...@erenkrantz.com> on 2008/08/27 07:18:32 UTC
[PATCH] apr_pollset_poll() returns WSAEINVAL if no sockets are in the pollset
The patch below fixes a cosmetic problem seen with serf on Win32 if
apr_pollset_poll is called without any sockets already in the pollset.
select on Win32 will immediately return WSAEINVAL (730022) in this
case.
The MSDN docs for select() -
http://msdn.microsoft.com/en-us/library/ms740141.aspx - says:
---
Any two of the parameters, readfds, writefds, or exceptfds, can be
given as null. At least one must be non-null, and any non-null
descriptor set must contain at least one handle to a socket.
---
Earlier in the doc, it says that select() ignores the first parameter
(nfds), so it looks like while other OSes may have a short-circuit
success on the 0 nfds case, Win32 will just return WSAEINVAL in this
case. Instead of returning an error, I believe the right thing is for
APR to hide this and return success.
So, any objections to committing the following? (If we're going to do
1.3.5, I'd like to see this backported too.)
Thanks! -- justin
Index: poll/unix/select.c
===================================================================
--- poll/unix/select.c (revision 689358)
+++ poll/unix/select.c (working copy)
@@ -453,6 +453,17 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pol
fd_set readset, writeset, exceptset;
apr_status_t rv = APR_SUCCESS;
+#ifdef WIN32
+ /* On Win32, select() must be presented with at least one socket to
+ * poll on, or select() will return WSAEINVAL. So, we'll just
+ * short-circuit and bail now.
+ */
+ if (pollset->nelts == 0) {
+ (*num) = 0;
+ return APR_SUCCESS;
+ }
+#endif
+
if (timeout < 0) {
tvptr = NULL;
}
Re: [PATCH] apr_pollset_poll() returns WSAEINVAL if no sockets are
in the pollset
Posted by Stefan Ruppert <ml...@ruppert-it.de>.
Hello Justin,
I think your fix is not correct. In some of my applications I crossed
exactly this situation and my main event loop took 100% CPU time because
of this returned error. I use an event loop like the following one
(running is modified by another thread which causes the event loop to
terminate):
volatile apr_int32_t running = 1;
void my_event_loop()
{
apr_interval_time_t timeout = 1000000; /* one second
const apr_pollfd_t *desc;
apr_int32_t num=0;
apr_status_t rc;
do {
rc = apr_pollset_poll(mypollset, timeout, &num, &desc);
if(APR_STATUS_IS_EINVAL(rc)) {
apr_sleep(timeout);
num=0;
rc = APR_TIMEUP;
}
} while(running);
}
Note the if-statement with APR_STATUS_IS_EINVAL() check. I think this
has to go into the APR source apr_pollset_poll() for Windows. Otherwise
this eventloop will do a busy looping and consume 100% CPU time of the
current thread!
Also I think the EINVAL return code should be returned if the timeout
value is INFINITE!?
Any comments?
Regards,
Stefan
Justin Erenkrantz wrote:
> The patch below fixes a cosmetic problem seen with serf on Win32 if
> apr_pollset_poll is called without any sockets already in the pollset.
> select on Win32 will immediately return WSAEINVAL (730022) in this
> case.
>
> The MSDN docs for select() -
> http://msdn.microsoft.com/en-us/library/ms740141.aspx - says:
>
> ---
> Any two of the parameters, readfds, writefds, or exceptfds, can be
> given as null. At least one must be non-null, and any non-null
> descriptor set must contain at least one handle to a socket.
> ---
>
> Earlier in the doc, it says that select() ignores the first parameter
> (nfds), so it looks like while other OSes may have a short-circuit
> success on the 0 nfds case, Win32 will just return WSAEINVAL in this
> case. Instead of returning an error, I believe the right thing is for
> APR to hide this and return success.
>
> So, any objections to committing the following? (If we're going to do
> 1.3.5, I'd like to see this backported too.)
>
> Thanks! -- justin
>
> Index: poll/unix/select.c
> ===================================================================
> --- poll/unix/select.c (revision 689358)
> +++ poll/unix/select.c (working copy)
> @@ -453,6 +453,17 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pol
> fd_set readset, writeset, exceptset;
> apr_status_t rv = APR_SUCCESS;
>
> +#ifdef WIN32
> + /* On Win32, select() must be presented with at least one socket to
> + * poll on, or select() will return WSAEINVAL. So, we'll just
> + * short-circuit and bail now.
> + */
> + if (pollset->nelts == 0) {
> + (*num) = 0;
> + return APR_SUCCESS;
> + }
> +#endif
> +
> if (timeout < 0) {
> tvptr = NULL;
> }
>
>
Re: [PATCH] apr_pollset_poll() returns WSAEINVAL if no sockets are
in the pollset
Posted by Mladen Turk <mt...@apache.org>.
Justin Erenkrantz wrote:
>
> So, any objections to committing the following? (If we're going to do
> 1.3.5, I'd like to see this backported too.)
>
For trunk you might add extra check for wakeup socket if
pollset was created with APR_POLLSET_WAKEABLE in which case
there is at least one socket in the pollset, but this one
is used only for interrupt operation.
In that case the check should be (pollset->nelts < 2)
Regards
--
^(TM)
Re: [PATCH] apr_pollset_poll() returns WSAEINVAL if no sockets are
in the pollset
Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
Justin Erenkrantz wrote:
> So, any objections to committing the following? (If we're going to do
> 1.3.5, I'd like to see this backported too.)
+1 to apply to trunk and 1.3 branch, commit away.