You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by INOUE Seiichiro <in...@ariel-networks.com> on 2002/03/24 17:32:06 UTC

[Q] apr_poll_revents_get() before apr_accept() on Windows

Hi,

I have a question about apr_poll_revents_get() behavior on Windows.
I want to check whether the socket is apr_accept()'able.
On Unix, I can check the socket becomes readable by apr_poll().
On Windows, when I do the same thing, apr_poll_revents_get() returns APR_POLLERR.

In apr_poll_revents_get(), WSARecv() causes WSAENOTCONN,
if the socket hasn't been apr_accept()'ed yet.
(Windows2000 case. I don't know other Windows.)

I attach a sample program for an easy reproduction.

My question is,
What is a proper solution?
libapr should take care of it, or applications should?

Thanks in advance.

- INOUE Seiichiro <in...@ariel-networks.com>
  http://www.ariel-networks.com

Resend(with sample): [Q] apr_poll_revents_get() before apr_accept() on Windows

Posted by INOUE Seiichiro <in...@ariel-networks.com>.
> I attach a sample program for an easy reproduction.

Sorry, I forgot it.

- INOUE Seiichiro <in...@ariel-networks.com>
  http://www.ariel-networks.com

[PATCH] Re: Resend ([Q] apr_poll_revents_get() before apr_accept() on Windows)

Posted by Saxon <sa...@saxon.cx>.
Thanks INOUE - I was going to repost it myself in a few days :)

Here's the patch again in case the old one is missing / too hard to find:

========================================================================
--- apr/network_io/win32/poll.c.old Mon Mar 25 16:37:46 2002
+++ apr/network_io/win32/poll.c Mon Mar 25 16:38:53 2002
@@ -156,6 +156,9 @@
     DWORD dummy;
     DWORD flags = MSG_PEEK;

+    BOOL optval;
+    int optlen;
+
     /* We just want to PEEK at the data, so I am setting up a dummy WSABUF
      * variable here.
      */
@@ -164,27 +167,45 @@

     if (FD_ISSET(sock->sock, aprset->read)) {
         revents |= APR_POLLIN;
-        if (WSARecv(sock->sock, &data, 1, &dummy, &flags, NULL,
-                    NULL) == SOCKET_ERROR) {
-            /* This is only legit since we don't return the error */
-            dummy = WSAGetLastError();
-            switch (dummy) {
-                case WSAECONNRESET:
-                case WSAECONNABORTED:
-                case WSAESHUTDOWN:
-                case WSAENETRESET: {
-                    revents ^= APR_POLLIN;
-                    revents |= APR_POLLHUP;
-                    break;
-                }
-                case WSAENOTSOCK: {
-                    revents ^= APR_POLLIN;
-                    revents |= APR_POLLNVAL;
-                }
-                default: {
-                    revents ^= APR_POLLIN;
-                    revents |= APR_POLLERR;
+
+        /* Check if the socket is listening for a connection (SO_ACCEPTCONN
+         * is true) - if it is we just leave APR_POLLIN in revents and
+         * don't attempt the WSARecv, since it would return WSAENOTCONN.
+         */
+        optlen = sizeof(optval);
+        getsockopt(sock->sock, SOL_SOCKET, SO_ACCEPTCONN, (char *)&optval,
+            &optlen);
+        if (!optval) {
+            /* The socket is not listening */
+            if (WSARecv(sock->sock, &data, 1, &dummy, &flags, NULL,
+                        NULL) == SOCKET_ERROR) {
+                /* This is only legit since we don't return the error */
+                dummy = WSAGetLastError();
+                switch (dummy) {
+                    case WSAECONNRESET:
+                    case WSAECONNABORTED:
+                    case WSAESHUTDOWN:
+                    case WSAENETRESET: {
+                        revents ^= APR_POLLIN;
+                        revents |= APR_POLLHUP;
+                        break;
+                    }
+                    case WSAENOTSOCK: {
+                        revents ^= APR_POLLIN;
+                        revents |= APR_POLLNVAL;
+                    }
+                    default: {
+                        revents ^= APR_POLLIN;
+                        revents |= APR_POLLERR;
+                    }
                 }
+            }
+            else if ((dummy == 0) && (sock->type == SOCK_STREAM)) {
+                /* Zero bytes received (dummy is the number of bytes)
+                 * from a stream socket indicates graceful shutdown.
+                 */
+                revents ^= APR_POLLIN;
+                revents |= APR_POLLHUP;
             }
         }
     }

========================================================================

bye,
Saxon Druce (saxon@blocksoftware.com)

----- Original Message -----
From: "INOUE Seiichiro" <in...@ariel-networks.com>
To: <de...@apr.apache.org>
Sent: Monday, April 22, 2002 11:31 PM
Subject: Resend ([Q] apr_poll_revents_get() before apr_accept() on Windows)


> Hi,
>
> I formerly sent a question about the issue on Subject.
> For my post, Mr. Saxon showed his patch, but the patch hasn't been
committed yet.
>
> What is goint on?
>
> Thanks.
>
>
> > ----- My Original Message -----
> > From: "INOUE Seiichiro" <in...@ariel-networks.com>
> > To: <de...@apr.apache.org>
> > Sent: Monday, March 25, 2002 12:32 AM
> > Subject: [Q] apr_poll_revents_get() before apr_accept() on Windows
> > > Hi,
> > >
> > > I have a question about apr_poll_revents_get() behavior on Windows.
> > > I want to check whether the socket is apr_accept()'able.
> > > On Unix, I can check the socket becomes readable by apr_poll().
> > > On Windows, when I do the same thing, apr_poll_revents_get() returns
> > APR_POLLERR.
> > >
> > > In apr_poll_revents_get(), WSARecv() causes WSAENOTCONN,
> > > if the socket hasn't been apr_accept()'ed yet.
> > > (Windows2000 case. I don't know other Windows.)
> > >
> > > I attach a sample program for an easy reproduction.
> > >
> > > My question is,
> > > What is a proper solution?
> > > libapr should take care of it, or applications should?
> > >
> > > Thanks in advance.
> > >
> > > - INOUE Seiichiro <in...@ariel-networks.com>
> > >   http://www.ariel-networks.com


Resend ([Q] apr_poll_revents_get() before apr_accept() on Windows)

Posted by INOUE Seiichiro <in...@ariel-networks.com>.
Hi,

I formerly sent a question about the issue on Subject.
For my post, Mr. Saxon showed his patch, but the patch hasn't been committed yet.

What is goint on?

Thanks.


> ----- My Original Message -----
> From: "INOUE Seiichiro" <in...@ariel-networks.com>
> To: <de...@apr.apache.org>
> Sent: Monday, March 25, 2002 12:32 AM
> Subject: [Q] apr_poll_revents_get() before apr_accept() on Windows
> > Hi,
> >
> > I have a question about apr_poll_revents_get() behavior on Windows.
> > I want to check whether the socket is apr_accept()'able.
> > On Unix, I can check the socket becomes readable by apr_poll().
> > On Windows, when I do the same thing, apr_poll_revents_get() returns
> APR_POLLERR.
> >
> > In apr_poll_revents_get(), WSARecv() causes WSAENOTCONN,
> > if the socket hasn't been apr_accept()'ed yet.
> > (Windows2000 case. I don't know other Windows.)
> >
> > I attach a sample program for an easy reproduction.
> >
> > My question is,
> > What is a proper solution?
> > libapr should take care of it, or applications should?
> >
> > Thanks in advance.
> >
> > - INOUE Seiichiro <in...@ariel-networks.com>
> >   http://www.ariel-networks.com

Re: [Q] apr_poll_revents_get() before apr_accept() on Windows

Posted by Saxon <sa...@saxon.cx>.
Ok sure, here it is (attached).

bye,
Saxon

----- Original Message -----
From: "Sander Striker" <st...@apache.org>
To: "Saxon" <sa...@saxon.cx>; <de...@apr.apache.org>
Sent: Monday, March 25, 2002 4:27 PM
Subject: RE: [Q] apr_poll_revents_get() before apr_accept() on Windows


> > From: Saxon [mailto:saxon@saxon.cx]
> > Sent: 25 March 2002 01:25
>
> > Hi,
> >
> > I ran into the same problem a couple of days ago. I modified the
> > implementation of apr_poll_revents_get() to the attached file, to fix
the
> > problem. Basically, if the socket is listening, then the WSARecv isn't
done.
> > Also I added another fix where if the WSARecv returns zero bytes on a
> > stream-type socket, that indicates a graceful shutdown (APR_POLLHUP
instead
> > of APR_POLLIN).
> >
> > I can create a proper diff-style patch for this if people agree it's
> > sensible?
>
> Please _always_ send a unified diff.  Full files are hard to review since
> it isn't directly obvious what has changed.
>
> > cya,
> > Saxon
>
> Sander

RE: [Q] apr_poll_revents_get() before apr_accept() on Windows

Posted by Sander Striker <st...@apache.org>.
> From: Saxon [mailto:saxon@saxon.cx]
> Sent: 25 March 2002 01:25

> Hi,
> 
> I ran into the same problem a couple of days ago. I modified the
> implementation of apr_poll_revents_get() to the attached file, to fix the
> problem. Basically, if the socket is listening, then the WSARecv isn't done.
> Also I added another fix where if the WSARecv returns zero bytes on a
> stream-type socket, that indicates a graceful shutdown (APR_POLLHUP instead
> of APR_POLLIN).
> 
> I can create a proper diff-style patch for this if people agree it's
> sensible?

Please _always_ send a unified diff.  Full files are hard to review since
it isn't directly obvious what has changed.
 
> cya,
> Saxon

Sander


Re: [Q] apr_poll_revents_get() before apr_accept() on Windows

Posted by Saxon <sa...@saxon.cx>.
Hi,

I ran into the same problem a couple of days ago. I modified the
implementation of apr_poll_revents_get() to the attached file, to fix the
problem. Basically, if the socket is listening, then the WSARecv isn't done.
Also I added another fix where if the WSARecv returns zero bytes on a
stream-type socket, that indicates a graceful shutdown (APR_POLLHUP instead
of APR_POLLIN).

I can create a proper diff-style patch for this if people agree it's
sensible?

cya,
Saxon

----- Original Message -----
From: "INOUE Seiichiro" <in...@ariel-networks.com>
To: <de...@apr.apache.org>
Sent: Monday, March 25, 2002 12:32 AM
Subject: [Q] apr_poll_revents_get() before apr_accept() on Windows


> Hi,
>
> I have a question about apr_poll_revents_get() behavior on Windows.
> I want to check whether the socket is apr_accept()'able.
> On Unix, I can check the socket becomes readable by apr_poll().
> On Windows, when I do the same thing, apr_poll_revents_get() returns
APR_POLLERR.
>
> In apr_poll_revents_get(), WSARecv() causes WSAENOTCONN,
> if the socket hasn't been apr_accept()'ed yet.
> (Windows2000 case. I don't know other Windows.)
>
> I attach a sample program for an easy reproduction.
>
> My question is,
> What is a proper solution?
> libapr should take care of it, or applications should?
>
> Thanks in advance.
>
> - INOUE Seiichiro <in...@ariel-networks.com>
>   http://www.ariel-networks.com