Browse Source

ubusd: retry sending messages on EINTR

Avoids unnecessary delays and/or blocking on messages

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Felix Fietkau 5 years ago
parent
commit
588baa3cd7
1 changed files with 12 additions and 6 deletions
  1. 12 6
      ubusd.c

+ 12 - 6
ubusd.c

@@ -109,16 +109,16 @@ static int ubus_msg_writev(int fd, struct ubus_msg_buf *ub, int offset)
 		.msg_control = &fd_buf,
 		.msg_controllen = sizeof(fd_buf),
 	};
+	struct ubus_msghdr hdr;
+	int ret;
 
 	fd_buf.fd = ub->fd;
-	if (ub->fd < 0) {
+	if (ub->fd < 0 || offset) {
 		msghdr.msg_control = NULL;
 		msghdr.msg_controllen = 0;
 	}
 
 	if (offset < sizeof(ub->hdr)) {
-		struct ubus_msghdr hdr;
-
 		hdr.version = ub->hdr.version;
 		hdr.type = ub->hdr.type;
 		hdr.seq = cpu_to_be16(ub->hdr.seq);
@@ -128,12 +128,18 @@ static int ubus_msg_writev(int fd, struct ubus_msg_buf *ub, int offset)
 		iov[0].iov_len = sizeof(hdr) - offset;
 		iov[1].iov_base = (char *) ub->data;
 		iov[1].iov_len = ub->len;
-
-		return sendmsg(fd, &msghdr, 0);
 	} else {
 		offset -= sizeof(ub->hdr);
-		return write(fd, ((char *) ub->data) + offset, ub->len - offset);
+		iov[0].iov_base = ((char *) ub->data) + offset;
+		iov[0].iov_len = ub->len - offset;
+		msghdr.msg_iovlen = 1;
 	}
+
+	do {
+		ret = sendmsg(fd, &msghdr, 0);
+	} while (ret < 0 && errno == EINTR);
+
+	return ret;
 }
 
 static void ubus_msg_enqueue(struct ubus_client *cl, struct ubus_msg_buf *ub)