From: Andre Noll Date: Sat, 10 Jan 2009 16:09:16 +0000 (+0100) Subject: upd_send.c: Use write_nonblock() rather than write_all(). X-Git-Tag: v0.3.4~75^2~29 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=a6cbab95272b31c55b2b41e1d3dd55743c7c774f;ds=sidebyside upd_send.c: Use write_nonblock() rather than write_all(). To this aim, move write_nonblock() from send_common.c to fd.c. --- diff --git a/fd.c b/fd.c index 6042a58f..9942eb92 100644 --- a/fd.c +++ b/fd.c @@ -40,6 +40,45 @@ int write_all(int fd, const char *buf, size_t *len) return 1; } +/** + * Write a buffer to a non-blocking file descriptor. + * + * \param fd The file descriptor. + * \param buf the buffer to write. + * \param len the number of bytes of \a buf. + * \param max_bytes_per_write Do not write more than that many bytes at once. + * + * If \a max_bytes_per_write is non-zero, do not send more than that many bytes + * per write(). + * + * EAGAIN is not considered an error condition. For example CCID3 has a + * sending wait queue which fills up and is emptied asynchronously. The EAGAIN + * case means that there is currently no space in the wait queue, but this can + * change at any moment. + * + * \return Negative on errors, number of bytes written else. + */ +int write_nonblock(int fd, const char *buf, size_t len, + size_t max_bytes_per_write) +{ + size_t written = 0; + int ret = 0; + + while (written < len) { + size_t num = len - written; + + if (max_bytes_per_write && max_bytes_per_write < num) + num = max_bytes_per_write; + ret = write(fd, buf + written, num); + if (ret < 0 && errno == EAGAIN) + return written; + if (ret < 0) + return -ERRNO_TO_PARA_ERROR(errno); + written += ret; + } + return written; +} + /** * Check whether a file exists. * diff --git a/fd.h b/fd.h index ae3624d7..041a7732 100644 --- a/fd.h +++ b/fd.h @@ -25,3 +25,5 @@ int mmap_full_file(const char *filename, int open_mode, void **map, int para_munmap(void *start, size_t length); int write_ok(int fd); void valid_fd_012(void); +int write_nonblock(int fd, const char *buf, size_t len, + size_t max_bytes_per_write); diff --git a/send_common.c b/send_common.c index 30cf939d..e1f3b11d 100644 --- a/send_common.c +++ b/send_common.c @@ -93,45 +93,6 @@ void shutdown_clients(struct sender_status *ss) shutdown_client(sc, ss); } -/** - * Write a buffer to a non-blocking file descriptor. - * - * \param fd The file descriptor. - * \param buf the buffer to write. - * \param len the number of bytes of \a buf. - * \param max_bytes_per_write Do not write more than that many bytes at once. - * - * If \a max_bytes_per_write is non-zero, do not send more than that many bytes - * per write(). - * - * EAGAIN is not considered an error condition. For example CCID3 has a - * sending wait queue which fills up and is emptied asynchronously. The EAGAIN - * case means that there is currently no space in the wait queue, but this can - * change at any moment. - * - * \return Negative on errors, number of bytes written else. - */ -static int write_nonblock(int fd, const char *buf, size_t len, - size_t max_bytes_per_write) -{ - size_t written = 0; - int ret = 0; - - while (written < len) { - size_t num = len - written; - - if (max_bytes_per_write && max_bytes_per_write < num) - num = max_bytes_per_write; - ret = write(fd, buf + written, num); - if (ret < 0 && errno == EAGAIN) - return written; - if (ret < 0) - return -ERRNO_TO_PARA_ERROR(errno); - written += ret; - } - return written; -} - static int queue_chunk_or_shutdown(struct sender_client *sc, struct sender_status *ss, const char *buf, size_t num_bytes) { diff --git a/udp_send.c b/udp_send.c index 50161c13..8bbcbae7 100644 --- a/udp_send.c +++ b/udp_send.c @@ -61,14 +61,13 @@ static void udp_send_buf(char *buf, size_t len) int ret; list_for_each_entry_safe(ut, tmp, &targets, node) { - size_t written = len; if (ut->fd < 0) continue; - ret = write_all(ut->fd, buf, &written); + ret = write_nonblock(ut->fd, buf, len, len); if (ret < 0) /* TODO: Use chunk queueing */ return udp_delete_target(ut, "send error"); - if (written != len) - PARA_WARNING_LOG("short write %zu/%zu\n", written, len); + if (ret != len) + PARA_WARNING_LOG("short write %zu/%zu\n", ret, len); } }