[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 27/41] buffered_file: Introduce QEMUFileNonblock
From: |
Isaku Yamahata |
Subject: |
[Qemu-devel] [PATCH v2 27/41] buffered_file: Introduce QEMUFileNonblock for nonblock write |
Date: |
Mon, 4 Jun 2012 18:57:29 +0900 |
Signed-off-by: Isaku Yamahata <address@hidden>
---
buffered_file.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
buffered_file.h | 13 ++++++
2 files changed, 128 insertions(+), 0 deletions(-)
diff --git a/buffered_file.c b/buffered_file.c
index 22dd4c9..5198923 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -106,6 +106,121 @@ static void buffer_flush(QEMUBuffer *buf, QEMUFile *file,
/***************************************************************************
+ * Nonblocking write only file
+ */
+static ssize_t nonblock_flush_buffer_putbuf(void *opaque,
+ const void *data, size_t size)
+{
+ QEMUFileNonblock *s = opaque;
+ ssize_t ret = write(s->fd, data, size);
+ if (ret == -1) {
+ return -errno;
+ }
+ return ret;
+}
+
+static void nonblock_flush_buffer(QEMUFileNonblock *s)
+{
+ buffer_flush(&s->buf, s->file, s, &nonblock_flush_buffer_putbuf);
+
+ if (s->buf.buffer_size > 0) {
+ s->buf.freeze_output = true;
+ }
+}
+
+static int nonblock_put_buffer(void *opaque,
+ const uint8_t *buf, int64_t pos, int size)
+{
+ QEMUFileNonblock *s = opaque;
+ int error;
+ ssize_t len = 0;
+
+ error = qemu_file_get_error(s->file);
+ if (error) {
+ return error;
+ }
+
+ nonblock_flush_buffer(s);
+ error = qemu_file_get_error(s->file);
+ if (error) {
+ return error;
+ }
+
+ while (!s->buf.freeze_output && size > 0) {
+ ssize_t ret;
+ assert(s->buf.buffer_size == 0);
+
+ ret = write(s->fd, buf, size);
+ if (ret == -1) {
+ if (errno == EINTR) {
+ continue;
+ } else if (errno == EAGAIN) {
+ s->buf.freeze_output = true;
+ } else {
+ qemu_file_set_error(s->file, errno);
+ }
+ break;
+ }
+
+ len += ret;
+ buf += ret;
+ size -= ret;
+ }
+
+ if (size > 0) {
+ buffer_append(&s->buf, buf, size);
+ len += size;
+ }
+ return len;
+}
+
+int nonblock_pending_size(QEMUFileNonblock *s)
+{
+ return qemu_pending_size(s->file) + s->buf.buffer_size;
+}
+
+void nonblock_fflush(QEMUFileNonblock *s)
+{
+ s->buf.freeze_output = false;
+ nonblock_flush_buffer(s);
+ if (!s->buf.freeze_output) {
+ qemu_fflush(s->file);
+ }
+}
+
+void nonblock_wait_for_flush(QEMUFileNonblock *s)
+{
+ while (nonblock_pending_size(s) > 0) {
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(s->fd, &fds);
+ select(s->fd + 1, NULL, &fds, NULL, NULL);
+
+ nonblock_fflush(s);
+ }
+}
+
+static int nonblock_close(void *opaque)
+{
+ QEMUFileNonblock *s = opaque;
+ nonblock_wait_for_flush(s);
+ buffer_destroy(&s->buf);
+ g_free(s);
+ return 0;
+}
+
+QEMUFileNonblock *qemu_fopen_nonblock(int fd)
+{
+ QEMUFileNonblock *s = g_malloc0(sizeof(*s));
+
+ s->fd = fd;
+ fcntl_setfl(fd, O_NONBLOCK);
+ s->file = qemu_fopen_ops(s, nonblock_put_buffer, NULL, nonblock_close,
+ NULL, NULL, NULL);
+ return s;
+}
+
+/***************************************************************************
* Buffered File
*/
diff --git a/buffered_file.h b/buffered_file.h
index d3ef546..2712e01 100644
--- a/buffered_file.h
+++ b/buffered_file.h
@@ -24,6 +24,19 @@ struct QEMUBuffer {
};
typedef struct QEMUBuffer QEMUBuffer;
+struct QEMUFileNonblock {
+ int fd;
+ QEMUFile *file;
+
+ QEMUBuffer buf;
+};
+typedef struct QEMUFileNonblock QEMUFileNonblock;
+
+QEMUFileNonblock *qemu_fopen_nonblock(int fd);
+int nonblock_pending_size(QEMUFileNonblock *s);
+void nonblock_fflush(QEMUFileNonblock *s);
+void nonblock_wait_for_flush(QEMUFileNonblock *s);
+
typedef ssize_t (BufferedPutFunc)(void *opaque, const void *data, size_t size);
typedef void (BufferedPutReadyFunc)(void *opaque);
typedef void (BufferedWaitForUnfreezeFunc)(void *opaque);
--
1.7.1.1
- [Qemu-devel] [PATCH v2 18/41] QEMUFile: add qemu_file_fd() for later use, (continued)
- [Qemu-devel] [PATCH v2 18/41] QEMUFile: add qemu_file_fd() for later use, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 24/41] migration: export migrate_fd_completed() and migrate_fd_cleanup(), Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 05/41] arch_init/ram_save_live: factor out RAM_SAVE_FLAG_MEM_SIZE case, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 31/41] configure: add CONFIG_POSTCOPY option, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 22/41] savevm/QEMUFile: introduce qemu_fopen_fd, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 09/41] arch_init: introduce helper function to find ram block with id string, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 02/41] arch_init: export RAM_SAVE_xxx flags for postcopy, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 13/41] exec.c: factor out qemu_get_ram_ptr(), Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 21/41] savevm: rename QEMUFileSocket to QEMUFileFD, socket_close to fd_close, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 11/41] arch_init: factor out counting transferred bytes, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 27/41] buffered_file: Introduce QEMUFileNonblock for nonblock write,
Isaku Yamahata <=
- [Qemu-devel] [PATCH v2 07/41] arch_init/ram_save_live: factor out ram_save_limit, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 23/41] migration.c: remove redundant line in migrate_init(), Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 29/41] umem.h: import Linux umem.h, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 19/41] savevm/QEMUFile: drop qemu_stdio_fd, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 32/41] savevm: add new section that is used by postcopy, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 15/41] savevm: export qemu_peek_buffer, qemu_peek_byte, qemu_file_skip, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 25/41] migration: factor out parameters into MigrationParams, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 30/41] update-linux-headers.sh: teach umem.h to update-linux-headers.sh, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 38/41] postcopy/outgoing: add forward, backward option to specify the size of prefault, Isaku Yamahata, 2012/06/04
- [Qemu-devel] [PATCH v2 10/41] arch_init: simplify a bit by ram_find_block(), Isaku Yamahata, 2012/06/04