Reputation: 2450
I have a WinSock mySocket
that receives in a loop like so:
while(keepGoing){
FD_SET fsd;
FD_ZERO(&fds);
FD_SET(mySocket, &fds);
int result = select(1+mySocket, &fds, (fd_set *)0, (fd_set *)0, &timeout);
if(result>0 && FD_ISSET(mySocket, &fds){
result = recvfrom(mySocket, buff, NUM_BYTES, (struct sockaddr *)&add, &length);
// do stuff
}
}
If I want to stop receiving I can set keepGoing
to false, but the socket may still be waiting for timeout
before it sees that keepGoing
has changed.
Assuming that we do not want to change the value of the timeout, is there a reliable way to tell the socket to stop receiving without waiting for the timeout to occur?
Upvotes: 3
Views: 1280
Reputation: 70372
You can raise a benign signal and check the keepGoing
flag when the errno
is EINTR
. Or, you can create a pipe
and add the read end to your select
set. Close the write end after setting the keepGoing
flag.
int quitfds[2];
pipe(quitfds);
//...
FD_SET(quitfds[0], &fds);
//...
if (FD_ISSET(quitfds[0], &fds)) {
close(quitfds[0]);
continue;
}
Edit: Adam points out that I missed the Winsock
reference in the question. You can use a socketpair
instead of a pipe
. It doesn't seem to be implemented on Windows, but I found a workaround here. Ben points out that WSAEventSelect
allows mixing of different event objects. Thanks to both.
Upvotes: 1