LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   socket blocking problem (https://www.linuxquestions.org/questions/programming-9/socket-blocking-problem-446827/)

pervert 05-20-2006 05:36 PM

socket blocking problem
 
select() is staying blocked after close() is called, surely this isn't normal? The program connects to my local webserver and waits for input, about 1 second after waiting, threadfunction calls close(), select never returns. Well that's what I get when the program is run from a shell, if it's run in gdb, select returns -1 and errno is 9 (bad file descriptor).

Is this normal behaviour? ...I can't see how it is. Can somebody please compile my code and report the behaviour. I'm feeling my system is screwed up :(

Code:

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <unistd.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdio.h>
#include <errno.h>

void * threadfunction(void *arg)
{
        printf("threadfunction started\n");
       
        int fd=*(int *)arg;
       
        sleep(1);
       
        printf("closing socket\n");
        close(fd);
}

int main()
{
        int fd=socket(AF_INET,SOCK_STREAM,0);
       
        struct sockaddr_in addr;
        addr.sin_family=AF_INET;
        addr.sin_addr.s_addr=inet_addr("127.0.0.1");
        addr.sin_port=htons(80);
       
        connect(fd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in));
       
        fd_set readfds;
        FD_ZERO(&readfds);
        FD_SET(fd,&readfds);
       
        pthread_t thread;
        pthread_create(&thread,NULL,threadfunction,&fd);
       
        printf("calling select()\n");
        int ret=select(fd+1,&readfds,NULL,NULL,NULL);
       
        printf("select returned %i\n",ret);
       
        printf("errno is %i\n",errno);
       
        return 0;
}

gcc test.c -o test -lpthread

If it needs to be known, i'm running:
Slackware 10.2
Linux kernel 2.4.31
libpthread-0.10.so
libc-2.3.5.so

Thanx ;)

randyding 05-20-2006 11:16 PM

The way the program is written there is no guarantee which will execute first, the statements after pthread_create() or the code in the thread function.
Its possible the debugger is just intrusive enough to change the outcome.

If the thread function closes the socket before the select call then a socket error should occur.
On the other hand if the select call is first then it should block.

pervert 05-21-2006 01:24 AM

Even if I used a syncronisation object, I couldn't be sure which was called first. sleep() should suffice though, the main thread should be running while threadfunction is sleeping. The weird thing is, when I stop the process (ctrl z) during sleep(1), I can see select has been called, looking at thread 1's backtrace, yet when the process runs through it's as if close was called first.

Anywayz, the issue with the debugger wasn't my original problem. My original problem was, select is not returning after close is called.

Quote:

On the other hand if the select call is first then it should block.
You're kidding me? :( But it doesn't make any sense to keep an i/o function blocked when the file or socket has been closed - it will never return.

btw, program still blocks when select is replaced by recv.

randyding 05-21-2006 11:02 AM

I know it seems like a good idea to have select() break when one of the file descriptors its waiting on is no longer valid, but actually thats not how it works. Select simply waits for the data read or write events. When the socket is closed this is not a data read event so select() does not break.

I always use non-blocking sockets so send() does not block, and supply a timeout with select() to test for received data. Its the user's responsibility to test for errors and handle them, select() is not designed to do that for the user.

pervert 05-21-2006 01:28 PM

It's fixed! I'm using shutdown() instead. I read somewhere that close() only closes the connection when the descriptor's reference count is equal to 0, I suspect this is the problem?

Oh well, thanks anyway. :)


All times are GMT -5. The time now is 02:18 PM.