Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

select() always returns 0

I seem to have a problem with select.

while(!sendqueue.empty())
{                                   
  if(!atms_connection.connected)
  {
    //print error message
    goto RECONNECT;
  }

  //select new
  FD_ZERO(&wfds);
  FD_SET(atms_connection.socket, &wfds);

  tv.tv_sec = 1;
  tv.tv_usec = 0;

  retval = select(atms_connection.socket + 1, NULL, &wfds, NULL, &tv);

  if (retval == -1) {
    printf("Select failed\n");                      
    break;
  }                     
  else if (retval) {
    printf("Sent a Message.\n"); 
  }
  else {
    //printf("retval value is %d\n",retval);
    printf("Server buffer is full, try again...\n");                        
    break;
  }
  n = write(atms_connection.socket, sendqueue.front().c_str(), sendqueue.front().length());
}

The function belongs to a thread, which, when it acquires the lock cleans a queue using select() and writes to socket in a loop until the queue is empty.

The first time the thread gets the lock it select() fine, but the second time it gets the lock and enters the while it always returns 0.

For the record, it used to work fine a while ago, and I haven't changed that code since then.

like image 265
Alon_T Avatar asked Oct 29 '12 09:10

Alon_T


1 Answers

Selects returns 0 when it has a timeout. The following line specifies a time out to be 1 second.

tv.tv_sec = 1;

Usually a socket is ready for write and select would return immediately. However, if there is no room in the socket output buffer for the new data, select won't flag this socket as ready for write.

For example, this condition might happen when the other side of the connection is not calling recv/read. The amount of unconfirmed data grows and the buffer eventually becomes full. Since the timeout is fairly small, the select returns frequently with return value 0.

like image 82
Maksim Skurydzin Avatar answered Sep 25 '22 05:09

Maksim Skurydzin