diff xsocket.c @ 262:ebbe0f198322

Fix DDS client connection retry
author Daniele Nicolodi <daniele.nicolodi@obspm.fr>
date Tue, 16 Jun 2015 17:16:11 +0200
parents a03df7dc98f8
children 8d9a4c5eb7a4
line wrap: on
line diff
--- a/xsocket.c	Tue Jun 16 15:09:23 2015 +0200
+++ b/xsocket.c	Tue Jun 16 17:16:11 2015 +0200
@@ -20,6 +20,17 @@
 
 #include "xsocket.h"
 
+#define XRETRY(code)								\
+	({												\
+		int __r, __n = 0;							\
+		while (__n++ < 2) {							\
+			__r = (code);							\
+			if (__r != -EAGAIN)						\
+				break;								\
+		}											\
+		__r;										\
+	})
+
 
 struct xsocket * xsocket(const char *hostname, const int port)
 {
@@ -72,86 +83,97 @@
 
 int xsend(struct xsocket *s, const char *data, size_t len)
 {
-	int r, retry = 2;
+	int r;
 
-	while (--retry) {
-		
-		r = xconnect(s);
-		if (r < 0)
-			return r;
+	r = xconnect(s);
+	if (r < 0)
+		return r;
 	
-		r = send(s->fd, data, len, 0);
-		if (r < 0) {
-			close(s->fd);
-			s->fd = -1;
-			continue;
-		}
+	r = send(s->fd, data, len, 0);
+	if (r < 0)
+		return -errno;
 
-		break;
-	}
-
-	return (r < 0) ? -errno : 0;
+	return r;
 }
 
 
 int xrecv(struct xsocket *s, char *buffer, size_t len)
 {
-	return recv(s->fd, buffer, len, 0);
+	int r;
+	
+	r = recv(s->fd, buffer, len, 0);
+	if (r < 0)
+		return -errno;
+	if (r == 0) {
+		close(s->fd);
+		s->fd = -1;
+		return -EAGAIN;
+	}
+
+	return r;
 }
 
 
-int msend(struct xsocket *s, const char *data, size_t len)
+static inline int __exchange(struct xsocket *s, const char *out, size_t outlen, char *in, size_t inlen)
 {
-	char *buffer = malloc(len + 2);
-	memcpy(buffer, data, len);
-	
-	buffer[len++] = '\r';
-	buffer[len++] = '\n';
+	int r;
 
-	return xsend(s, buffer, len);
+	r = xsend(s, out, outlen);
+	if (r < 0)
+		return r;
+		
+	r = xrecv(s, in, inlen);
+	if (r < 0)
+		return r;
+
+	return r;
 }
 
 
-int mrecv(struct xsocket *s, char *buffer, size_t len)
+int xask(struct xsocket *s, const char *cmd, size_t len, char *buffer, size_t bufferlen)
 {
-	int n;
+	int r;
+	char *data;
+
+	data = malloc(len + 2);
+	memcpy(data, cmd, len);	
+	data[len++] = '\r';
+	data[len++] = '\n';
 
-	n = xrecv(s, buffer, len);
-	if (n < 0)
-		return n;
+	r = XRETRY(__exchange(s, data, len, buffer, bufferlen));
+	if (r < 0)
+		return r;
 
-	if ((buffer[--n] != '\n') || (buffer[--n] != '\r'))
+	if ((buffer[--r] != '\n') || (buffer[--r] != '\r'))
 		return -EINVAL;
-
-	buffer[n] = '\0';
-
-	return n;
+	buffer[r] = '\0';
+		
+	return 0;
 }
 
 
-int command(struct xsocket *s, char *frmt, ...)
+int xcommand(struct xsocket *s, const char *frmt, ...)
 {
-	int r, n;
+	int r, len;
 	char buffer[1024];
 	va_list v;
-
+	
 	va_start(v, frmt);
-	n = vsnprintf(buffer, sizeof(buffer) - 2, frmt, v);
+	len = vsnprintf(buffer, sizeof(buffer) - 2, frmt, v);
 	va_end(v);
+	buffer[len++] = '\r';
+	buffer[len++] = '\n';
 
-	buffer[n++] = '\r';
-	buffer[n++] = '\n';
-
-	r = xsend(s, buffer, n);
+	r = XRETRY(__exchange(s, buffer, len, buffer, sizeof(buffer)));
 	if (r < 0)
 		return r;
 
-	r = mrecv(s, buffer, sizeof(buffer));
-	if (r < 0)
-		return r;
+	if ((buffer[--r] != '\n') || (buffer[--r] != '\r'))
+		return -EINVAL;
+	buffer[r] = '\0';
 
 	if (strcmp(buffer, "OK") != 0)
 		return -EINVAL;
-
+	
 	return 0;
 }