public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Jon TURNEY <jon.turney@dronecode.org.uk>
To: cygwin@cygwin.com
Subject: Re: python select() is limited to fds < 64
Date: Thu, 24 Mar 2011 16:11:00 -0000	[thread overview]
Message-ID: <4D8B5E68.4020409@dronecode.org.uk> (raw)
In-Reply-To: <20110323201424.GD5588@ednor.casa.cgf.cx>

On 23/03/2011 20:14, Christopher Faylor wrote:
> On Wed, Mar 23, 2011 at 04:38:15PM +0000, Jon TURNEY wrote:
>> On 23/03/2011 15:00, Christopher Faylor wrote:
>>> On Wed, Mar 23, 2011 at 11:31:46AM +0000, Jon TURNEY wrote:
>>>> On 22/03/2011 20:08, Christopher Faylor wrote:
>>>>> On Tue, Mar 22, 2011 at 08:53:34PM +0100, V??clav Haisman wrote:
>>>>>> Jon TURNEY wrote, On 22.3.2011 20:29:
>>>>>>>
>>>>>>> python seems to be built with the default value of FD_SETSIZE, which is
>>>>>>> only 64 on cygwin.
>>>>>> Is this not because of the inherent limitation of
>>>>>> WaitForMultipleObjects() call?
>>>>>
>>>>> Yep.  Without a rewrite, it's a hard limit to Cygwin's select().
>>>>
>>>> Please read my email more closely.  I am not saying "python select() is
>>>> limited to waiting on 64 fds or less", I am saying "python select() is
>>>> limited to waiting on fd which are less than 64"
>>>
>>> I forgot to add one bit of data.  Unless you go out of your way to
>>> change it, Cygwin's select can't wait for an fd > 63.  It's basically a
>>> bit mask.  So, there are two limitations: 1) the number of handles that
>>> you can wait for with WaitForMultipleObjects() and 2) the size of
>>> Cygwin's fd_set.
>>
>> Yes, I know fd_set is implemented as a bitmap.  It's size is controlled by
>> FD_SETSIZE.  That is the whole point of the patch in the original mail.
> 
> I actually did see that last night and then promptly forgot it.
> 
> I assume you know that this greately increases the likelihood that
> select() will fail with an EINVAL.  Maybe python somehow deals
> gracefully with that.

Well, I believe if select() returns an error, python will raise an exception,
which is no less graceful than current behaviour.

I don't quite follow your reasoning that this change will increase the
likelihood of such exceptions, though.

To select() on more than 64 fds requires using fd numbers 64 and greater.

For existing python programs which use less than 64 fds, this change should
have no effect.

For existing python program which use more than 64 fds, at the moment they
will throw an exception on any attempt to use select() on fd number 64 or
greater.  With this change, attempts to use select() on fd number 64 or
greater will succeed, provided fewer than 64 fds in total are selected on.

However... I did test my original patch, and didn't see an EINVAL error
occurring, which, now knowing that select() has this limitation, I should
have.  So, another test case:

$ cat select_MAXIMUM_WAIT_OBJECTS_test.c

#define FD_SETSIZE 256
#include <sys/select.h>
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>

//
// gcc select_MAXIMUM_WAIT_OBJECTS_test.c -o select_MAXIMUM_WAIT_OBJECTS_test.exe
//

int main()
{
  fd_set read;
  struct timeval t;
  int i, n;

  FD_ZERO(&read);

  for (i = 0; i < FD_SETSIZE; i++)
    {
      int s = socket(AF_INET, SOCK_STREAM, 0);
      printf("socket opened with fd %d\n", s);
      FD_SET(s, &read);
    }

  t.tv_sec = 1;
  t.tv_usec = 0;

  n = select(FD_SETSIZE, &read, 0, 0, &t);
  printf("select returned %d, errno %d\n", n, errno);

  return 0;

}

$ ./select_MAXIMUM_WAIT_OBJECTS_test
socket opened with fd 3
[...]
socket opened with fd 258
select returned 0, errno 0

Assuming this tests what I think it tests, EINVAL should be returned, but isn't.

Looking at select.cc in the cygwin source code, I can see that
select_stuff::wait() has code to return EINVAL if we exceed
MAXIMUM_WAIT_OBJECTS, so this puzzled me for a while.

Looking at this in a bit more detail, it seems that start_thread_socket()
guzzles all the sockets and starts a single thread, the handle of which it
returns to wait() to WMFO on for every socket fd, even though thread_socket()
will only wait on MAXIMUM_WAIT_OBJECTS at most.

I guess I need to write a patch for this problem, also :-)

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

  reply	other threads:[~2011-03-24 15:08 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-22 19:50 Jon TURNEY
2011-03-22 20:59 ` Václav Haisman
2011-03-22 23:45   ` Christopher Faylor
2011-03-23 12:09     ` Jon TURNEY
2011-03-23 15:02       ` Christopher Faylor
2011-03-23 15:24         ` Eric Blake
2011-03-23 16:50         ` Jon TURNEY
2011-03-23 20:28           ` Christopher Faylor
2011-03-24 16:11             ` Jon TURNEY [this message]
2011-04-21  1:07 Bert Belder

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D8B5E68.4020409@dronecode.org.uk \
    --to=jon.turney@dronecode.org.uk \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).