using select() and getting WSAEINPROGRESS

Started by
7 comments, last by hplus0603 19 years, 2 months ago
Hi all, I developed a network library for my game that is non-blocking udp. In my original design, I had two threads for communication, one for receiving and one for sending. In the receving thread, there is a select() call that blocks until a read event occurs and then handles that. In a seperate thread, I have another select() for writes (which, I guess, doesn't seem necessary since it never blocks but I keep it there for safety) and I basically have a queue where I add messages to. This thread goes past a select() statment, checks the queue size, calls sendto() for each message and then goes to sleep for a set amount of time (or until something is put into the queue in which case the thread is awakened). Now, this was working fine when I was testing it on PCs. But, now I'm testing the code with an Xbox. And Xbox doesn't like me using the same socket to do another operation if it is already blocking (it's blocking on the select() call for reading) even though I have a seperate thread. I get issued the WSAEINPROGRESS error code. Is there a workaround for this where I can still use one socket? Thanks, Lehel
Advertisement
The specifics of the XDK network API are covered by the XDK NDA, so we shouldn't discuss them here.

Because the socket is non-blocking, you don't need the threads, and you don't need the select() calls. You don't even need the threads. If you still want the threads, you could keep one thread that "pumps" data both in and out, and puts the received data in a queue for the main thread to pick up.
enum Bool { True, False, FileNotFound };
Well, originally I my design was just one thread with a select() that handled both read and write events. The problem was that the select() would never block because everytime it was called, it was signaled that I could write--so, basically, it just spun and used up the cpu.

I didn't want to put a sleep in that thread because the my reads would be delayed by the amount of sleep delay.

My solution was to create another thread with a select call handling writes only but now this isn't quite working.

Your suggestion was to have one thread pumping, but how can I do this without the thread spinning like crazy or slowing down the reading with sleep()s?
Quote:Original post by Lehel Kovach
Well, originally I my design was just one thread with a select() that handled both read and write events. The problem was that the select() would never block because everytime it was called, it was signaled that I could write--so, basically, it just spun and used up the cpu.

I didn't want to put a sleep in that thread because the my reads would be delayed by the amount of sleep delay.

My solution was to create another thread with a select call handling writes only but now this isn't quite working.

Your suggestion was to have one thread pumping, but how can I do this without the thread spinning like crazy or slowing down the reading with sleep()s?



You should be able to so a Sleep(0) to avoid enforced sleep delay.


LOOP forever
if select (detect incoming)
process any incoming packets(and set flag)

if outbound app packets
process all outgoing packets

if flag
loop immediately (goto top)
else
sleep(0);
LOOPEND


wont sleep until no pending incomming





Quote:Original post by Anonymous Poster
You should be able to so a Sleep(0) to avoid enforced sleep delay.


LOOP forever
if select (detect incoming)
process any incoming packets(and set flag)

if outbound app packets
process all outgoing packets

if flag
loop immediately (goto top)
else
sleep(0);
LOOPEND


wont sleep until no pending incomming


what I'm concerned with is if there is no more incomming data and the thread goes to sleep, so the thread pauses on the sleep()..but afterwards data comes in and is ready to be read...the next time the select() will be called is after the thread is reawakened. How do I handle that or am I missing something?
Oh sorry...didn't realize the functionality of Sleep(0) thanks.
You should not select() for write-ability, unless you have queued data to send. Thus, you won't wake up spuriously when calling select(). The timeout for select() should be the time until the next scheduled event/poll interval, if you have things happening on timers in addition to reactive from network data.
enum Bool { True, False, FileNotFound };
Quote:Original post by hplus0603
Because the socket is non-blocking, you don't need the threads, and you don't need the select() calls. You don't even need the threads.


Just out of curiosity, if I didn't want to use select(), how would I design my game so that I don't have a seperate thread checking for readability? Do I just have a function handling all network processing that is called in my game loop that has a call recvfrom() (and do something with data if any comes in)?
@Lehel: Yes, you could do that. You'd have to use non-blocking sockets so that you don't hang inside the service routine. Handling networking data isn't very different from reading the joystick/keyboard, say -- and most people don't think reading the keyboard should be in a separate thread ;-)
enum Bool { True, False, FileNotFound };

This topic is closed to new replies.

Advertisement