tags:

views:

445

answers:

5

From one thread I got the following code:

int next_stuff(char **code){
    ...       
    len=read(file_desc,buffer+end_len,packet_size-end_len);
    if(len<=0)
    {
        if(len==-1 && errno==EAGAIN) return(0);
        else return(-1);
    }
    ...
}

while (next_stuff(&buff) == 0)
{
    ...
}

On the other thread I'd like to finish that socket and exit this operation, but only doing a

close(file_desc);

does not cause read to return nonblocked. Am I missing something?

EDIT:

shutdown does not work as well. And I am trying that on Linux 2.6.23

A: 

If your read() call is nonblocking, it should return fairly fast, as all it will be doing is inserting memory. To prevent doing any damage, you would use a mutex around your call to read() and close() such that they cant both run at the same time.

If your socket is blocking, i think you should make it nonblocking.

Zuu
Actually, you need no mutex because these calls are thread-safe per se.
jpalecek
+1  A: 

In general, if you do not want blocking socket calls, you would use select() to see if the socket is ready to read, write, or is in the error state. In addition, pass a timeout value to select() so that this call isn't blocking forever. After the select() call returns, you can see if the application wants to quit and if so do the "right" thing (that's for you to decide).

Tommy Hui
+1  A: 

shutdown(fd, SHUT_RD);

$ man -s 2 shutdown

NAME shutdown -- shut down part of a full-duplex connection

SYNOPSIS

 #include <sys/socket.h>

 int     shutdown(int socket, int how);

DESCRIPTION

 The shutdown() call causes all or part of a full-duplex connection on the socket 
 associated with socket to be shut down.  
 If how is SHUT_RD, further receives will be disallowed.  If how is 
 SHUT_WR, further sends will be
 disallowed.  If how is SHUT_RDWR, further sends and receives will be disallowed.

RETURN VALUES

 The shutdown() function returns the value 0 if successful; otherwise the value -1 is 
 returned and the global variable errno is set to indicate the error.
yogman
Sorry, as I commented above shutdown does not do it was well. It does not make the read call return.
Edu Felipe
Why don't you install a signal hander, and issue kill(getpid(), SIGHUP)? read will return with an errno value of EINTR
yogman
A: 

The other answers about non-blocking sockets are good, and I recommend recoding to use that approach.

As a direct answer to your question, though, try calling shutdown() and see if that will break the other thread out of read. I'm afraid close() is just decrementing the usage count, while shutdown() will actively tear down the socket.

dwc
A: 

I don't think you've provided enough information to answer this question, yet. For example if the socket that you've opened is UDP, then a close on the sending side will have no effect on the receiving side. If it is TCP, then something else is broken. I suggest that if you are really dealing with sockets, you use recv or recvfrom instead of read.

In the case of TCP, your read will return 0 bytes, an indication that the other side has closed the connection.

If you are really doing this between two threads instead of two processes, a pipe may be more appropriate. That's not to say that a pipe could not also be used between two separate processes, it just takes a bit more set up in that case.

Johnny Edge