THROW3(system_error,EINVAL,"invalid select: nb fds: %d, timeout: %d.%d",
max_fds, (int)tout.tv_sec,(int) tout.tv_usec);
case ENOMEM:
- xbt_assert0(0,"Malloc error during the select");
+ xbt_die("Malloc error during the select");
default:
THROW2(system_error,errno,"Error during select: %s (%d)",
strerror(errno),errno);
accepted->meas = sock_iter->meas;
break;
- } else if (sock_iter->recv_ok) {
+ } else {
/* 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);
+ recvd = read(sock_iter->sd, &sock_iter->recvd_val, 1);
if (recvd < 0) {
WARN2("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 */
} else {
/* Got a suited socket ! */
XBT_OUT;
+ sock_iter->recvd = 1;
_gras_lastly_selected_socket = sock_iter;
- /* break sync dynar iteration */
- xbt_dynar_cursor_unlock(sockets);
+ /* break sync dynar iteration */
+ xbt_dynar_cursor_unlock(sockets);
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;
- 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 */
sock->outgoing = incoming ? 0:1;
sock->accepting = incoming ? 1:0;
sock->meas = 0;
- sock->recv_ok = 1;
+ sock->recvd = 0;
sock->valid = 1;
sock->moredata = 0;
res->sd = 1; /* stdout */
}
- res->recv_ok=0;
DEBUG5("sock_client_from_file(%s): sd=%d in=%c out=%c accept=%c",
path,
res->sd,
res->outgoing?'y':'n',
res->accepting?'y':'n');
- res->recv_ok=0;
xbt_dynar_push(((gras_trp_procdata_t)
gras_libdata_by_id(gras_trp_libdata_id))->sockets,&res);
return res;
xbt_assert0(sock->incoming, "Cannot recv on client file socket");
xbt_assert0(size >= 0, "Cannot receive a negative amount of data");
+ if (sock->recvd) {
+ data[0] = sock->recvd_val;
+ sock->recvd = 0;
+ got++;
+ size--;
+ }
+
while (size) {
int status = 0;
status = read(sock->sd, data+got, (long int)size);
DEBUG3("read(%d, %p, %ld);", sock->sd, data+got, size);
- if (status == -1) {
+ if (status < 0) {
THROW4(system_error,0,"read(%d,%p,%d) failed: %s",
sock->sd, data+got, (int)size,
strerror(errno));
size -= status;
got += status;
} else {
- THROW0(system_error,0,"file descriptor closed");
+ THROW1(system_error,errno,"file descriptor closed after %d bytes",got);
}
}
return got;
int got = 0;
+ if (sock->recvd) {
+ data[0] = sock->recvd_val;
+ sock->recvd = 0;
+ got++;
+ bufsize--;
+ }
+
while (size>got) {
int status = 0;
bufsize -= status;
got += status;
} else {
- THROW1(system_error,0,"Socket closed by remote side (got %d bytes before this)",
+ THROW1(system_error,errno,"Socket closed by remote side (got %d bytes before this)",
got);
}
}
int outgoing :1; /* true if we can write on this sock */
int accepting :1; /* true if master incoming sock in tcp */
int meas :1; /* true if this is an experiment socket instead of messaging */
- int recv_ok :1; /* true if it is valid to recv() on the socket (false if it is a file) */
int valid :1; /* false if a select returned that the peer quitted, forcing us to "close" the socket */
int moredata :1; /* TCP socket use a buffer and read operation get as much
data as possible. It is possible that several messages
don't call select in that case. Note that measurement
sockets are not concerned since they use the TCP
interface directly, with no buffer. */
-
+
+ int recvd :1; /* true if the recvd_val field contains one byte of the stream (that we peek'ed to check the socket validity) */
+ char recvd_val; /* what we peeked from the socket, if any */
+
unsigned long int buf_size; /* what to say to the OS.
Field here to remember it when accepting */