From: Felix Fietkau Date: Fri, 9 Sep 2011 15:53:22 +0000 (+0200) Subject: make the socket non-blocking, explicitly wait for data using poll() X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fubus.git;a=commitdiff_plain;h=7c59d4069c7bfe5f02abda8c1b7f387c4f64bf90 make the socket non-blocking, explicitly wait for data using poll() --- diff --git a/libubus.c b/libubus.c index aed615d..af8cc46 100644 --- a/libubus.c +++ b/libubus.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -88,6 +89,14 @@ out: return err; } +static void wait_data(int fd, bool write) +{ + struct pollfd pfd = { .fd = fd }; + + pfd.events = write ? POLLOUT : POLLIN; + poll(&pfd, 1, 0); +} + static int writev_retry(int fd, struct iovec *iov, int iov_len) { int len = 0; @@ -97,9 +106,7 @@ static int writev_retry(int fd, struct iovec *iov, int iov_len) if (cur_len < 0) { switch(errno) { case EAGAIN: - /* turn off non-blocking mode */ - fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & - ~O_NONBLOCK); + wait_data(fd, true); break; case EINTR: break; @@ -165,6 +172,9 @@ static bool recv_retry(int fd, struct iovec *iov, bool wait) int bytes; while (iov->iov_len > 0) { + if (wait) + wait_data(fd, false); + bytes = read(fd, iov->iov_base, iov->iov_len); if (bytes < 0) { bytes = 0; @@ -860,6 +870,8 @@ struct ubus_context *ubus_connect(const char *path) if (!ctx->local_id) goto error_close; + fcntl(ctx->sock.fd, F_SETFL, fcntl(ctx->sock.fd, F_GETFL) | O_NONBLOCK); + return ctx; error_free_buf: