Add a call to find the queue-length so we can see how many I/O we have in flight...
[deb_libnfs.git] / lib / socket.c
index e9c103e55b0cd124ce04baaeef1721fb43d5e5fd..d93acd80b717c9f4be0fab8168862bab3bdf6dbc 100644 (file)
    You should have received a copy of the GNU Lesser General Public License
    along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
+#ifdef WIN32
+#include "win32_compat.h"
+#else
+#include <unistd.h>
+#include <poll.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#endif/*WIN32*/
 
 #if defined(WIN32)
 #include <winsock2.h>
@@ -56,12 +66,14 @@ static int rpc_disconnect_requeue(struct rpc_context *rpc);
 
 static void set_nonblocking(int fd)
 {
+       int v = 0;
 #if defined(WIN32)
+       long nonblocking=1;
+       v = ioctlsocket(fd, FIONBIO,&nonblocking);
 #else
-       unsigned v;
        v = fcntl(fd, F_GETFL, 0);
         fcntl(fd, F_SETFL, v | O_NONBLOCK);
-#endif
+#endif //FIXME
 }
 
 int rpc_get_fd(struct rpc_context *rpc)
@@ -140,6 +152,7 @@ static int rpc_read_from_socket(struct rpc_context *rpc)
                rpc_set_error(rpc, "Ioctl FIONREAD returned error : %d. Closing socket.", errno);
                return -1;
        }
+
        if (available == 0) {
                rpc_set_error(rpc, "Socket has been closed");
                return -1;
@@ -254,11 +267,11 @@ static int rpc_read_from_socket(struct rpc_context *rpc)
 int rpc_service(struct rpc_context *rpc, int revents)
 {
        if (revents & POLLERR) {
-               int err = 0;
+               char err = 0;
                socklen_t err_size = sizeof(err);
 
                if (getsockopt(rpc->fd, SOL_SOCKET, SO_ERROR,
-                               &err, &err_size) != 0 || err != 0) {
+                               (char *)&err, &err_size) != 0 || err != 0) {
                        if (err == 0) {
                                err = errno;
                        }
@@ -283,7 +296,7 @@ int rpc_service(struct rpc_context *rpc, int revents)
                socklen_t err_size = sizeof(err);
 
                if (getsockopt(rpc->fd, SOL_SOCKET, SO_ERROR,
-                               &err, &err_size) != 0 || err != 0) {
+                               (char *)&err, &err_size) != 0 || err != 0) {
                        if (err == 0) {
                                err = errno;
                        }
@@ -302,7 +315,7 @@ int rpc_service(struct rpc_context *rpc, int revents)
 
        if (revents & POLLIN) {
                if (rpc_read_from_socket(rpc) != 0) {
-                       rpc_disconnect_requeue(rpc);
+                       rpc_disconnect_requeue(rpc);
                        return 0;
                }
        }
@@ -360,8 +373,12 @@ int rpc_connect_async(struct rpc_context *rpc, const char *server, int port, rpc
        rpc->connect_data = private_data;
 
        set_nonblocking(rpc->fd);
-
-       if (connect(rpc->fd, (struct sockaddr *)&s, socksize) != 0 && errno != EINPROGRESS) {
+#if defined(WIN32)
+       if (connect(rpc->fd, (struct sockaddr *)&s, socksize) == 0 && GetLastError() != WSAEINPROGRESS   )
+#else
+       if (connect(rpc->fd, (struct sockaddr *)&s, socksize) != 0 && errno != EINPROGRESS) 
+#endif
+       {
                rpc_set_error(rpc, "connect() to server failed");
                return -1;
        }               
@@ -488,7 +505,7 @@ int rpc_set_udp_destination(struct rpc_context *rpc, char *addr, int port, int i
        freeaddrinfo(ai);
 
        rpc->is_broadcast = is_broadcast;
-       setsockopt(rpc->fd, SOL_SOCKET, SO_BROADCAST, &is_broadcast, sizeof(is_broadcast));
+       setsockopt(rpc->fd, SOL_SOCKET, SO_BROADCAST, (char *)&is_broadcast, sizeof(is_broadcast));
 
        return 0;
 }
@@ -497,3 +514,17 @@ struct sockaddr *rpc_get_recv_sockaddr(struct rpc_context *rpc)
 {
        return (struct sockaddr *)&rpc->udp_src;
 }
+
+int rpc_queue_length(struct rpc_context *rpc)
+{
+       int i=0;
+       struct rpc_pdu *pdu;
+
+       for(pdu = rpc->outqueue; pdu; pdu = pdu->next) {
+               i++;
+       }
+       for(pdu = rpc->waitpdu; pdu; pdu = pdu->next) {
+               i++;
+       }
+       return i;
+}