473,408 Members | 1,786 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 software developers and data experts.

Blocking Select() does not work

Hi,

I'm using a blocking Select() call on a socket with
a timeout value of -1. I'd expect the call to block
indefinitely, but it doesn't. When I use Poll() instead,
a timeout of -1 works fine and blocks indefinitely.

The net effect is that I cannot write a select on more
than one file descripter if I want to block. (With
timeout values >= 0, both Select() and Poll() work fine.)

To reproduce, run the code below and telnet to 127.0.0.1
at port 12345 from another window. The Select() version
returns immediately even though it shouldn't, whereas
the Poll() version correctly blocks and returns once
you hit any key in the telnet window.

Cheers,

Michi.

#define SHOW_BUG

using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;

class Server
{
static void Main(string[] args)
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345));
s.Listen(1);
Socket c = s.Accept();
#if SHOW_BUG
ArrayList readList = new ArrayList();
readList.Add(c);
Socket.Select(readList, null, null, -1);
Console.WriteLine("Select returned, number of readable descriptors = " + readList.Count);
#else
bool rc = c.Poll(-1, SelectMode.SelectRead);
Console.WriteLine("Poll returned " + rc);
#endif
}
}


Nov 15 '05 #1
11 1843
Michi Henning <mi***@zeroc.com> wrote:
I'm using a blocking Select() call on a socket with
a timeout value of -1. I'd expect the call to block
indefinitely, but it doesn't. When I use Poll() instead,
a timeout of -1 works fine and blocks indefinitely.


Why would you expect it to block indefinitely? I can't see anything in
the documentation to suggest that it should - whereas the Poll
documentation *does* say that a negative value will cause a potentially
indefinite wait.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #2
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Michi Henning <mi***@zeroc.com> wrote:
I'm using a blocking Select() call on a socket with
a timeout value of -1. I'd expect the call to block
indefinitely, but it doesn't. When I use Poll() instead,
a timeout of -1 works fine and blocks indefinitely.


Why would you expect it to block indefinitely? I can't see anything in
the documentation to suggest that it should - whereas the Poll
documentation *does* say that a negative value will cause a potentially
indefinite wait.


Right, that's exactly what the doc says. But native select() (in the SDK)
blocks indefinitely when called with a negative timeout. And, if what
the documentation says is really as intended, there is simply no way
to do a blocking select on more than a single socket at a time. That's
clearly a bug -- if I have multiple sources of data that I want to monitor
for activity, I can't do that unless I do a busy wait.

If Poll() blocks indefinitely with a negative timeout, so should Select()
(which is exactly what happens when I'm using the SDK instead of
the .NET frameowork).

Cheers,

Michi.

--
Michi Henning Ph: +61 4 1118-2700
ZeroC, Inc. http://www.zeroc.com

Nov 15 '05 #3
"Michi Henning" <mi***@triodia.com> wrote in news:OZeRL$O4DHA.1596
@TK2MSFTNGP10.phx.gbl:
Right, that's exactly what the doc says. But native select() (in the SDK)
blocks indefinitely when called with a negative timeout. And, if what
the documentation says is really as intended, there is simply no way
to do a blocking select on more than a single socket at a time. That's


You can bypass and interface to Winsock2 yourself.
--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"
ELKNews - Get your free copy at http://www.atozedsoftware.com

Nov 15 '05 #4
Michi Henning <mi***@triodia.com> wrote:
Why would you expect it to block indefinitely? I can't see anything in
the documentation to suggest that it should - whereas the Poll
documentation *does* say that a negative value will cause a potentially
indefinite wait.
Right, that's exactly what the doc says. But native select() (in the SDK)
blocks indefinitely when called with a negative timeout. And, if what
the documentation says is really as intended, there is simply no way
to do a blocking select on more than a single socket at a time.


Well, you can block for a fairly long time, and do so repeatedly, of
course... it's not exactly a tricky problem to code round, and you
could very easily have a utility method which does exactly what you
want it to. I don't expect the performance penalty for calling the
method once every half hour (which according to some quick calculations
is roughly what the maximum parameter gives) would be significant.

Select() *does* block, just not indefinitely, so saying "there is
simply no way to do a blocking select on more than a single socket at a
time" is incorrect, unless I've missed something.
That's clearly a bug -- if I have multiple sources of data that I want
to monitor for activity, I can't do that unless I do a busy wait.
To me, a bug is when something does not behave as documented, which
isn't the case here.
If Poll() blocks indefinitely with a negative timeout, so should
Select()
(which is exactly what happens when I'm using the SDK instead of
the .NET frameowork).


I presume by "SDK" you mean "Win32 API". I'm not saying it wouldn't be
a good idea for Select to be designed to work the same way as Poll, and
I'm interested as to why it isn't, but saying it "does not work" is
wrong IMO, as it's working exactly as documented.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #5
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Well, you can block for a fairly long time, and do so repeatedly, of
course... it's not exactly a tricky problem to code round, and you
could very easily have a utility method which does exactly what you
want it to. I don't expect the performance penalty for calling the
method once every half hour (which according to some quick calculations
is roughly what the maximum parameter gives) would be significant.
Right. The performance penalty is clearly unnoticeable. But it means
that I have to write special code, just in case I need to block for more
than roughly 35 minutes. Why should I have to write that special code?
And the discrepancy between the .NET versions and the SDK versions
of Poll() and Select() is jarring.
Select() *does* block, just not indefinitely, so saying "there is
simply no way to do a blocking select on more than a single socket at a
time" is incorrect, unless I've missed something.
Right. I can block for 35 minutes, but no longer. (I seem to remember
a Windows Update patch for Win98 that fixed a crash if a machine
was up for more than 28 days or so.) With the current behavior, sooner or
later, we'll have patch for programs that wait for socket input for more
than 35 minutes.
That's clearly a bug -- if I have multiple sources of data that I want
to monitor for activity, I can't do that unless I do a busy wait.


To me, a bug is when something does not behave as documented, which
isn't the case here.


Correct. It's not documented so, according to the documentation, I'm
complaining about nothing. Of course, we can discuss fundamentals here.
On the other hand, the problem is clearly caused by a trivial oversight
in the implementation of Socket.Select(), and fixing it would be equally
trivial. So, why not fix it?
I presume by "SDK" you mean "Win32 API".
Sorry, yes. I'm not a Windows expert.
I'm not saying it wouldn't be
a good idea for Select to be designed to work the same way as Poll, and
I'm interested as to why it isn't, but saying it "does not work" is
wrong IMO, as it's working exactly as documented.


Yes, no argument there. But to say that it works exactly as documented
is stretching a truth a little. In fact, the documentation for Select() that
ships with the C# compiler doesn't mention the fourth parameter to
Select() at all...

Cheers,

Michi.

--
Michi Henning Ph: +61 4 1118-2700
ZeroC, Inc. http://www.zeroc.com

Nov 15 '05 #6
"Chad Z. Hower aka Kudzu" <cp**@hower.org> wrote in message
news:Xn******************@127.0.0.1...
"Michi Henning" <mi***@triodia.com> wrote in news:OZeRL$O4DHA.1596
@TK2MSFTNGP10.phx.gbl:
Right, that's exactly what the doc says. But native select() (in the SDK)
blocks indefinitely when called with a negative timeout. And, if what
the documentation says is really as intended, there is simply no way
to do a blocking select on more than a single socket at a time. That's


You can bypass and interface to Winsock2 yourself.


Yes, that's in fact precisely what I did. But the effort of using platform
invoke is not exactly on par with calling Socket.Select() :-)

If platform invoke were as convenient as using the .NET framework,
we wouldn't need the framework now, would we? ;-)

Cheers,

Michi.

--
Michi Henning Ph: +61 4 1118-2700
ZeroC, Inc. http://www.zeroc.com

Nov 15 '05 #7
"Michi Henning" <mi***@triodia.com> wrote in
news:OH**************@TK2MSFTNGP11.phx.gbl:
Yes, that's in fact precisely what I did. But the effort of using
platform invoke is not exactly on par with calling Socket.Select() :-)

If platform invoke were as convenient as using the .NET framework,
we wouldn't need the framework now, would we? ;-)


It depends. I havent done PInokes in VB or C# as all my code there has been
pure managed, but at least in Delphi its just a matter of declaring the
interface to the DLL and Delphi manages the rest.
--
Chad Z. Hower (a.k.a. Kudzu) - http://www.hower.org/Kudzu/
"Programming is an art form that fights back"
ELKNews - Get your free copy at http://www.atozedsoftware.com

Nov 15 '05 #8
"Chad Z. Hower aka Kudzu" <cp**@hower.org> wrote in message
news:Xn******************@127.0.0.1...
"Michi Henning" <mi***@triodia.com> wrote in

If platform invoke were as convenient as using the .NET framework,
we wouldn't need the framework now, would we? ;-)


It depends. I havent done PInokes in VB or C# as all my code there has been
pure managed, but at least in Delphi its just a matter of declaring the
interface to the DLL and Delphi manages the rest.


I have no experience with Delphi. From C#, platform invoke is
simple as long as the parameters are simple. Once things are passed
by pointer, or you are getting a pointer as an out parameter from
a C call that you are supposed to later deallocated, things are not
as simple and take quite a while to figure out. The same is true
for passing structures or unions that play tricks with arrays as
the last field to pad the structure to a desired size. Not trivial
to call something like that with platform invoke (at least not
until you've finally figured out how to do it or located the
obscure bit of the relevant documentation -- the platform
invoke doc is -- how shall I put it -- obtuse?)

Cheers,

Michi.

--
Michi Henning Ph: +61 4 1118-2700
ZeroC, Inc. http://www.zeroc.com

Nov 15 '05 #9
Michi Henning <mi***@triodia.com> wrote:
Well, you can block for a fairly long time, and do so repeatedly, of
course... it's not exactly a tricky problem to code round, and you
could very easily have a utility method which does exactly what you
want it to. I don't expect the performance penalty for calling the
method once every half hour (which according to some quick calculations
is roughly what the maximum parameter gives) would be significant.


Right. The performance penalty is clearly unnoticeable. But it means
that I have to write special code, just in case I need to block for more
than roughly 35 minutes. Why should I have to write that special code?
And the discrepancy between the .NET versions and the SDK versions
of Poll() and Select() is jarring.


I agree that it would be desirable for you not to have to write that
special code. On the other hand, unless I'm mistaken it's almost
trivial to write.
Select() *does* block, just not indefinitely, so saying "there is
simply no way to do a blocking select on more than a single socket at a
time" is incorrect, unless I've missed something.


Right. I can block for 35 minutes, but no longer. (I seem to remember
a Windows Update patch for Win98 that fixed a crash if a machine
was up for more than 28 days or so.) With the current behavior, sooner or
later, we'll have patch for programs that wait for socket input for more
than 35 minutes.


I don't think so: any program which wants to wait for socket input for
more than 35 minutes but not indefinitely will have found that it can't
due to the range of int. Any program which wants to wait for socket
input indefinitely will have run into the problem already, and
presumably written the extra code to just loop. I can't see any
patching being required unless coders have been *really* dumb about it.
That's clearly a bug -- if I have multiple sources of data that I want
to monitor for activity, I can't do that unless I do a busy wait.


To me, a bug is when something does not behave as documented, which
isn't the case here.


Correct. It's not documented so, according to the documentation, I'm
complaining about nothing. Of course, we can discuss fundamentals here.
On the other hand, the problem is clearly caused by a trivial oversight
in the implementation of Socket.Select(), and fixing it would be equally
trivial. So, why not fix it?


Indeed - and I'm not saying that it shouldn't be changed appropriately.
I'm just saying it's important to get the terminology here - I don't
believe it's a trivial oversight in the *implementation* of
Socket.Select, for instance - it's a trivial oversight in the *design*
which would also be trivial to fix in the implementation.
I presume by "SDK" you mean "Win32 API".


Sorry, yes. I'm not a Windows expert.


Me either - but as there's a .NET SDK, I thought it would be best to
check we're talking about the same thing.
I'm not saying it wouldn't be
a good idea for Select to be designed to work the same way as Poll, and
I'm interested as to why it isn't, but saying it "does not work" is
wrong IMO, as it's working exactly as documented.


Yes, no argument there. But to say that it works exactly as documented
is stretching a truth a little. In fact, the documentation for Select() that
ships with the C# compiler doesn't mention the fourth parameter to
Select() at all...


Really? The version I've got (in the SDK) specifies:

microSeconds
The time to wait for a response, in microseconds.

It doesn't mention it after that, but it goes that far. Certainly the
documentation isn't as full as it might be, but there's nothing in the
implementation which actually goes against what the documentation
states.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #10
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
I agree that it would be desirable for you not to have to write that
special code. On the other hand, unless I'm mistaken it's almost
trivial to write.
No, you are not mistaken :-)
With the current behavior, sooner or
later, we'll have patch for programs that wait for socket input for more
than 35 minutes.


I don't think so: any program which wants to wait for socket input for
more than 35 minutes but not indefinitely will have found that it can't
due to the range of int. Any program which wants to wait for socket
input indefinitely will have run into the problem already, and
presumably written the extra code to just loop. I can't see any
patching being required unless coders have been *really* dumb about it.


Yes, I agree with you there -- I didn't think thius through enough, so I'll
withdraw the comment.
On the other hand, the problem is clearly caused by a trivial oversight
in the implementation of Socket.Select(), and fixing it would be equally
trivial. So, why not fix it?


Indeed - and I'm not saying that it shouldn't be changed appropriately.
I'm just saying it's important to get the terminology here - I don't
believe it's a trivial oversight in the *implementation* of
Socket.Select, for instance - it's a trivial oversight in the *design*
which would also be trivial to fix in the implementation.


Ah, OK, I guess you can look at it from that angle equally well.
I presume by "SDK" you mean "Win32 API".


Sorry, yes. I'm not a Windows expert.


Me either - but as there's a .NET SDK, I thought it would be best to
check we're talking about the same thing.


The help doc that comes with the C# compiler uses the term
"Platform SDK", at least when I'm using the index and want to
restrict the hits to the Win32 API. I don't know myself which term
is more appropriate. Seems that "Win32 API" is more commonly
used?
In fact, the documentation for Select() that
ships with the C# compiler doesn't mention the fourth parameter to
Select() at all...


Really? The version I've got (in the SDK) specifies:

microSeconds
The time to wait for a response, in microseconds.


Ah, yes, that's what I get when I click on the parameter. But the
parameter isn't mentioned in the body of the text.
It doesn't mention it after that, but it goes that far. Certainly the
documentation isn't as full as it might be, but there's nothing in the
implementation which actually goes against what the documentation
states.


I have to agree there. On the other hand, if a negative argument for the
timeout is non-sensical (in the sense that it does the same thing as a zero
timeout), shouldn't a negative value result in a ArgumentException?

Anyway, this is getting into the finer details of API design and different
people have different opinions in that space.

Anyway, I think it would be really nice if Select() would treat a negative
timeout the same way as Poll() does, both because that would be
convenient and for consistency with the Win32 API behavior.

Cheers,

Michi.

--
Michi Henning Ph: +61 4 1118-2700
ZeroC, Inc. http://www.zeroc.com

Nov 15 '05 #11
<snipping lots as I go>

Michi Henning <mi***@triodia.com> wrote:
Me either - but as there's a .NET SDK, I thought it would be best to
check we're talking about the same thing.
The help doc that comes with the C# compiler uses the term
"Platform SDK", at least when I'm using the index and want to
restrict the hits to the Win32 API. I don't know myself which term
is more appropriate. Seems that "Win32 API" is more commonly
used?


Well, "Platform SDK" is unfortunately a really vague term - it could be
the API for *any* platform. :(
Anyway, I think it would be really nice if Select() would treat a negative
timeout the same way as Poll() does, both because that would be
convenient and for consistency with the Win32 API behavior.


Agreed. That seems a pretty good point at which to draw this thread to
a close :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Tero Saarni | last post by:
Hi, I have several threads communicating with each other using events stored in Queues. Threads block on Queue.get() until somebody publishes an event in thread's event queue. I need to add...
4
by: Jonathan Fine | last post by:
Hello I have written a program that interacts with a command line program. Roughly speaking, it mimics human interaction. (With more speed and accuracy, less intelligence.) It works fine...
3
by: David Sworder | last post by:
This message was already cross-posted to C# and ADO.NET, but I forgot to post to this "general" group... sorry about that. It just occured to me after my first post that the "general" group readers...
3
by: Mario | last post by:
Hello, I couldn't find a solution to the following problem (tried google and dejanews), maybe I'm using the wrong keywords? Is there a way to open a file (a linux fifo pipe actually) in...
2
by: Bruce Vander Werf | last post by:
How can I cleanly stop a thread that is currently blocking on Socket.Receive? I don't want to use Thread.Abort, because I would like the thread method to exit cleanly, and the same code must run...
7
by: David Sworder | last post by:
Hi, I'm developing an application that will support several thousand simultaneous connections on the server-side. I'm trying to maximize throughput. The client (WinForms) and server communicate...
2
by: Tash Robinson | last post by:
I have been searching and can not seem to find a good example of a working UDP client that listens, but does not block while waiting for data arrival. I am trying to write a client application...
0
by: nielsgron | last post by:
Hi, I am trying to find a way to query for the (lock) blocking connection on my DB2 server. I am using DB2 for LUW 8.1 and 8.2. I have two connections, one which has an exclusive lock, and the...
5
by: Thomas Christensen | last post by:
This issue has been raised a couple of times I am sure. But I have yet to find a satisfying answer. I am reading from a subprocess and this subprocess sometimes hang, in which case a call to...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.