- xbt_dynar_foreach(sockets,cursor,sock_iter) {
- if(!FD_ISSET(sock_iter->sd, &FDS)) { /* this socket is not ready */
- continue;
- }
-
- /* Got a socket to serve */
- ready--;
-
- if ( sock_iter->accepting
- && sock_iter->plugin->socket_accept) {
- /* not a socket but an ear. accept on it and serve next socket */
- gras_socket_t accepted=NULL;
-
- accepted = (sock_iter->plugin->socket_accept)(sock_iter);
- DEBUG2("accepted=%p,&accepted=%p",accepted,&accepted);
- accepted->meas = sock_iter->meas;
-
- } else if (sock_iter->recv_ok) {
- /* Make sure the socket is still alive by reading the first byte */
- char lookahead;
- int recvd;
-
- recvd = recv(sock_iter->sd, &lookahead, 1, MSG_PEEK);
- if (recvd < 0) {
- WARN2("socket %d failed: %s", sock_iter->sd, strerror(errno));
- /* done with this socket */
- gras_socket_close(sock_iter);
- cursor--;
- } else if (recvd == 0) {
- /* Connection reset (=closed) by peer. */
- DEBUG1("Connection %d reset by peer", sock_iter->sd);
- sock_iter->valid=0; /* don't close it. User may keep references to it */
- } else {
- /* Got a suited socket ! */
- XBT_OUT;
- _gras_lastly_selected_socket = sock_iter;
- return sock_iter;
- }
-
- } else {
- /* This is a file socket. Cannot recv() on it, but it must be alive */
- XBT_OUT;
- _gras_lastly_selected_socket = sock_iter;
- return sock_iter;
- }
-
-
- /* if we're here, the socket we found wasn't really ready to be served */
- if (ready == 0) /* exausted all sockets given by select. Request new ones */
- break;
+ xbt_dynar_foreach(sockets, cursor, sock_iter) {
+ if (!FD_ISSET(sock_iter->sd, &FDS)) { /* this socket is not ready */
+ continue;
+ }
+
+ /* Got a socket to serve */
+ ready--;
+
+ if (sock_iter->accepting && sock_iter->plugin->socket_accept) {
+ /* not a socket but an ear. accept on it and serve next socket */
+ gras_socket_t accepted = NULL;
+
+ /* release mutex before accept; it will change the sockets dynar, so we have to break the foreach asap */
+ xbt_dynar_cursor_unlock(sockets);
+ accepted = (sock_iter->plugin->socket_accept) (sock_iter);
+
+ XBT_DEBUG("accepted=%p,&accepted=%p", accepted, &accepted);
+ accepted->meas = sock_iter->meas;
+ break;
+
+ } else {
+ /* Make sure the socket is still alive by reading the first byte */
+ int recvd;
+
+ if (sock_iter->recvd) {
+ /* Socket wasn't used since last time! Don't bother checking whether it's still alive */
+ recvd = 1;
+ } else {
+ recvd = read(sock_iter->sd, &sock_iter->recvd_val, 1);
+ }
+
+ if (recvd < 0) {
+ XBT_WARN("socket %d failed: %s", sock_iter->sd, strerror(errno));
+ /* done with this socket; remove it and break the foreach since it will change the dynar */
+ xbt_dynar_cursor_unlock(sockets);
+ gras_socket_close(sock_iter);
+ break;
+ } else if (recvd == 0) {
+ /* Connection reset (=closed) by peer. */
+ XBT_DEBUG("Connection %d reset by peer", sock_iter->sd);
+ sock_iter->valid = 0; /* don't close it. User may keep references to it */
+ } else {
+ /* Got a suited socket ! */
+ XBT_OUT();
+ sock_iter->recvd = 1;
+ XBT_DEBUG("Filled little buffer (%c %x %d)", sock_iter->recvd_val,
+ sock_iter->recvd_val, recvd);
+ _gras_lastly_selected_socket = sock_iter;
+ /* break sync dynar iteration */
+ xbt_dynar_cursor_unlock(sockets);
+ return sock_iter;
+ }
+ }
+
+ /* if we're here, the socket we found wasn't really ready to be served */
+ if (ready == 0) { /* exausted all sockets given by select. Request new ones */
+
+ xbt_dynar_cursor_unlock(sockets);
+ break;
+ }