#include "gras/Transport/transport_private.h"
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(gras_trp);
+/* check transport_private.h for an explanation of this variable */
+gras_socket_t _gras_lastly_selected_socket = NULL;
+
/**
* gras_trp_select:
*
with this tiny optimisation on BillWare */
fd_set FDS;
int ready; /* return of select: number of socket ready to be serviced */
- int fd_setsize; /* FD_SETSIZE not always defined. Get this portably */
+ static int fd_setsize=-1; /* FD_SETSIZE not always defined. Get this portably */
gras_socket_t sock_iter; /* iterating over all sockets */
int cursor; /* iterating over all sockets */
-
- /* Compute FD_SETSIZE */
+ /* Check whether there is more data to read from the socket we selected last time.
+ This can happen with tcp buffered sockets since we try to get as much data as we can for them */
+ if (_gras_lastly_selected_socket && _gras_lastly_selected_socket->moredata) {
+ VERB0("Returning _gras_lastly_selected_socket since there is more data on it");
+ return _gras_lastly_selected_socket;
+ }
+
+ /* Compute FD_SETSIZE on need */
+ if (fd_setsize < 0) {
#ifdef HAVE_SYSCONF
- fd_setsize = sysconf( _SC_OPEN_MAX );
+ fd_setsize = sysconf( _SC_OPEN_MAX );
#else
# ifdef HAVE_GETDTABLESIZE
- fd_setsize = getdtablesize();
+ fd_setsize = getdtablesize();
# else
- fd_setsize = FD_SETSIZE;
+ fd_setsize = FD_SETSIZE;
# endif /* !USE_SYSCONF */
#endif
+ }
while (done == -1) {
if (timeout > 0) { /* did we timeout already? */
now = gras_os_time();
DEBUG2("wakeup=%f now=%f",wakeup, now);
if (now == -1 || now >= wakeup) {
- /* didn't find anything */
+ /* didn't find anything; no need to update _gras_lastly_selected_socket since its moredata is 0 (or we would have returned it directly) */
THROW1(timeout_error,0,
"Timeout (%f) elapsed with selecting for incomming connexions",
timeout);
#ifndef HAVE_WINSOCK_H
if (max_fds < sock_iter->sd)
max_fds = sock_iter->sd;
+#else
+ max_fds = 0;
+
#endif
FD_SET(sock_iter->sd, &FDS);
} else {
} 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;
}