Wallace
Wallace

Reputation: 651

Do We Need Add Lock To the Code of Recv/Send/Close For a Same Socket Among Threads

From posts like this, I know on linux the recv/send functions are thread safe and user is allowed to operate on the same socket from different threads simultaneously.

Though this is not a good design, in following situation I wonder what shall we do from user level code in order to keep data consistency and healthy running state: There are threads operating on the same sockets, the first one for creating and closing socket, the second for reading socket and the last one for sending sockets. See the pseudo code

 struct SocketInfo
 {
      int SockFd;
      int SockType;
      queue<Packet*> RecvPacks;
 };

 map<int, SocketInfo*> gSocketInfoMap;
 pthread_mutex_t       gSocketsLock;

 //Thread1
 pthread_mutex_lock(&gSocketsLock);
 // get information for sock
 SocketInfo* info = gSocketInfoMap[sock];
 pthread_mutex_unlock(&gSocketsLock);

 close(sock);         // line-1
 .....


 //thread-2
 pthread_mutex_lock(&gSocketsLock);
 SocketInfo* info = gSocketInfoMap[sock];
 pthread_mutex_unlock(&gSocketsLock);

 recv(sock, buffer, sizeof(buffer));         // line-2
 .....

 //thread-3
 pthread_mutex_lock(&gSocketsLock);
 SocketInfo* info = gSocketInfoMap[sock];
 pthread_mutex_unlock(&gSocketsLock);

 send(sock, buffer, sizeof buffer);         // line-3
 .....

I wonder if I need to move the Line-1, Line-2 and Line-3 into the protection scope of gSocketsLock? Why?

Upvotes: 3

Views: 1340

Answers (1)

rici
rici

Reputation: 241911

As the linked question states, socket operations are threadsafe. In any event, receiving and sending data are independent operations which do not interfere with each other.

Obviously, it is not a great idea to close a socket which is actively being read from and written to, but putting the close() inside a critical section does not do anything to prevent that bug. Whatever mechanism ensures that active sockets are not closed or that closed sockets are not accessed is at a higher level than the critical sections shown in the OP.

If one thread closes a socket that another thread is trying to use for I/O, the worst that can happen is that the recv/send call will return an error.

In short: no, it would not be a good idea to put the socket operations inside the critical section. It has not benefit, and it unnecessarily increases the likelihood of lock contention.

Upvotes: 3

Related Questions