All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Lieven <pl@kamp.de>
To: Gerd Hoffmann <kraxel@redhat.com>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [RfC PATCH 02/10] io: pull Buffer code out of VNC module
Date: Fri, 25 Sep 2015 11:57:31 +0200	[thread overview]
Message-ID: <56051A8B.8010109@kamp.de> (raw)
In-Reply-To: <1443084128-25552-3-git-send-email-kraxel@redhat.com>

Am 24.09.2015 um 10:42 schrieb Gerd Hoffmann:
> From: "Daniel P. Berrange" <berrange@redhat.com>
>
> The Buffer code in the VNC server is useful for the IO channel
> code, so pull it out into a shared module, QIOBuffer.
>
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
>  include/io/buffer.h | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  io/Makefile.objs    |   1 +
>  io/buffer.c         |  65 +++++++++++++++++++++++++++++
>  ui/vnc-auth-sasl.c  |   4 +-
>  ui/vnc-enc-tight.c  |  38 ++++++++---------
>  ui/vnc-enc-zlib.c   |   6 +--
>  ui/vnc-enc-zrle.c   |  18 ++++----
>  ui/vnc-jobs.c       |  15 +++----
>  ui/vnc-ws.c         |  36 ++++++++--------
>  ui/vnc-ws.h         |   6 +--
>  ui/vnc.c            |  67 ++++++-----------------------
>  ui/vnc.h            |  50 ++++++++--------------
>  12 files changed, 276 insertions(+), 148 deletions(-)
>  create mode 100644 include/io/buffer.h
>  create mode 100644 io/Makefile.objs
>  create mode 100644 io/buffer.c
>
> diff --git a/include/io/buffer.h b/include/io/buffer.h
> new file mode 100644
> index 0000000..2b1b261
> --- /dev/null
> +++ b/include/io/buffer.h
> @@ -0,0 +1,118 @@
> +/*
> + * QEMU I/O buffers
> + *
> + * Copyright (c) 2015 Red Hat, Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +#ifndef QIO_BUFFER_H__
> +#define QIO_BUFFER_H__
> +
> +#include "qemu-common.h"
> +
> +typedef struct QIOBuffer QIOBuffer;
> +
> +/**
> + * QIOBuffer:
> + *
> + * The QIOBuffer object provides a simple dynamically resizing
> + * array, with separate tracking of capacity and usage. This
> + * is typically useful when buffering I/O data.
> + */
> +
> +struct QIOBuffer {
> +    size_t capacity;
> +    size_t offset;
> +    uint8_t *buffer;
> +};
> +
> +/**
> + * qio_buffer_reserve:
> + * @buffer: the buffer object
> + * @len: the minimum required free space
> + *
> + * Ensure that the buffer has space allocated for at least
> + * @len bytes. If the current buffer is too small, it will
> + * be reallocated, possibly to a larger size than requested.
> + */
> +void qio_buffer_reserve(QIOBuffer *buffer, size_t len);
> +
> +/**
> + * qio_buffer_reset:
> + * @buffer: the buffer object
> + *
> + * Reset the length of the stored data to zero, but do
> + * not free / reallocate the memory buffer
> + */
> +void qio_buffer_reset(QIOBuffer *buffer);
> +
> +/**
> + * qio_buffer_free:
> + * @buffer: the buffer object
> + *
> + * Reset the length of the stored data to zero and also
> + * free the internal memory buffer
> + */
> +void qio_buffer_free(QIOBuffer *buffer);
> +
> +/**
> + * qio_buffer_append:
> + * @buffer: the buffer object
> + * @data: the data block to append
> + * @len: the length of @data in bytes
> + *
> + * Append the contents of @data to the end of the buffer.
> + * The caller must ensure that the buffer has sufficient
> + * free space for @len bytes, typically by calling the
> + * qio_buffer_reserve() method prior to appending.
> + */
> +void qio_buffer_append(QIOBuffer *buffer, const void *data, size_t len);
> +
> +/**
> + * qio_buffer_advance:
> + * @buffer: the buffer object
> + * @len: the number of bytes to skip
> + *
> + * Remove @len bytes of data from the head of the buffer.
> + * The internal buffer will not be reallocated, so will
> + * have at least @len bytes of free space after this
> + * call completes
> + */
> +void qio_buffer_advance(QIOBuffer *buffer, size_t len);
> +
> +/**
> + * qio_buffer_end:
> + * @buffer: the buffer object
> + *
> + * Get a pointer to the tail end of the internal buffer
> + * The returned pointer is only valid until the next
> + * call to qio_buffer_reserve().
> + *
> + * Returns: the tail of the buffer
> + */
> +uint8_t *qio_buffer_end(QIOBuffer *buffer);
> +
> +/**
> + * qio_buffer_empty:
> + * @buffer: the buffer object
> + *
> + * Determine if the buffer contains any current data
> + *
> + * Returns: true if the buffer holds data, false otherwise
> + */
> +gboolean qio_buffer_empty(QIOBuffer *buffer);
> +
> +#endif /* QIO_BUFFER_H__ */
> diff --git a/io/Makefile.objs b/io/Makefile.objs
> new file mode 100644
> index 0000000..3de4e47
> --- /dev/null
> +++ b/io/Makefile.objs
> @@ -0,0 +1 @@
> +io-obj-y = buffer.o
> diff --git a/io/buffer.c b/io/buffer.c
> new file mode 100644
> index 0000000..68ae68d
> --- /dev/null
> +++ b/io/buffer.c
> @@ -0,0 +1,65 @@
> +/*
> + * QEMU I/O buffers
> + *
> + * Copyright (c) 2015 Red Hat, Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, see <http://www.gnu.org/licenses/>.
> + *
> + */
> +
> +#include "io/buffer.h"
> +
> +void qio_buffer_reserve(QIOBuffer *buffer, size_t len)
> +{
> +    if ((buffer->capacity - buffer->offset) < len) {
> +        buffer->capacity += (len + 1024);
> +        buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
> +    }
> +}
> +
> +gboolean qio_buffer_empty(QIOBuffer *buffer)
> +{
> +    return buffer->offset == 0;
> +}
> +
> +uint8_t *qio_buffer_end(QIOBuffer *buffer)
> +{
> +    return buffer->buffer + buffer->offset;
> +}
> +
> +void qio_buffer_reset(QIOBuffer *buffer)
> +{
> +    buffer->offset = 0;
> +}
> +
> +void qio_buffer_free(QIOBuffer *buffer)
> +{
> +    g_free(buffer->buffer);
> +    buffer->offset = 0;
> +    buffer->capacity = 0;
> +    buffer->buffer = NULL;
> +}
> +
> +void qio_buffer_append(QIOBuffer *buffer, const void *data, size_t len)
> +{
> +    memcpy(buffer->buffer + buffer->offset, data, len);
> +    buffer->offset += len;
> +}
> +
> +void qio_buffer_advance(QIOBuffer *buffer, size_t len)
> +{
> +    memmove(buffer->buffer, buffer->buffer + len,
> +            (buffer->offset - len));
> +    buffer->offset -= len;
> +}
> diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
> index fc732bd..d118266 100644
> --- a/ui/vnc-auth-sasl.c
> +++ b/ui/vnc-auth-sasl.c
> @@ -113,8 +113,8 @@ long vnc_client_read_sasl(VncState *vs)
>          return vnc_client_io_error(vs, -1, -EIO);
>      VNC_DEBUG("Read SASL Encoded %p size %ld Decoded %p size %d\n",
>                encoded, ret, decoded, decodedLen);
> -    buffer_reserve(&vs->input, decodedLen);
> -    buffer_append(&vs->input, decoded, decodedLen);
> +    qio_buffer_reserve(&vs->input, decodedLen);
> +    qio_buffer_append(&vs->input, decoded, decodedLen);
>      return decodedLen;
>  }
>  
> diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
> index 9a9ddf2..772ec79 100644
> --- a/ui/vnc-enc-tight.c
> +++ b/ui/vnc-enc-tight.c
> @@ -856,7 +856,7 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
>      }
>  
>      /* reserve memory in output buffer */
> -    buffer_reserve(&vs->tight.zlib, bytes + 64);
> +    qio_buffer_reserve(&vs->tight.zlib, bytes + 64);
>  
>      /* set pointers */
>      zstream->next_in = vs->tight.tight.buffer;
> @@ -879,7 +879,7 @@ static int tight_compress_data(VncState *vs, int stream_id, size_t bytes,
>      tight_send_compact_size(vs, bytes);
>      vnc_write(vs, vs->tight.zlib.buffer, bytes);
>  
> -    buffer_reset(&vs->tight.zlib);
> +    qio_buffer_reset(&vs->tight.zlib);
>  
>      return bytes;
>  }
> @@ -1053,7 +1053,7 @@ static bool send_gradient_rect(VncState *vs, int x, int y, int w, int h)
>      vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4);
>      vnc_write_u8(vs, VNC_TIGHT_FILTER_GRADIENT);
>  
> -    buffer_reserve(&vs->tight.gradient, w * 3 * sizeof (int));
> +    qio_buffer_reserve(&vs->tight.gradient, w * 3 * sizeof(int));
>  
>      if (vs->tight.pixel24) {
>          tight_filter_gradient24(vs, vs->tight.tight.buffer, w, h);
> @@ -1066,7 +1066,7 @@ static bool send_gradient_rect(VncState *vs, int x, int y, int w, int h)
>          bytes = 2;
>      }
>  
> -    buffer_reset(&vs->tight.gradient);
> +    qio_buffer_reset(&vs->tight.gradient);
>  
>      bytes = w * h * bytes;
>      vs->tight.tight.offset = bytes;
> @@ -1149,7 +1149,7 @@ static int send_palette_rect(VncState *vs, int x, int y,
>  static void jpeg_init_destination(j_compress_ptr cinfo)
>  {
>      VncState *vs = cinfo->client_data;
> -    Buffer *buffer = &vs->tight.jpeg;
> +    QIOBuffer *buffer = &vs->tight.jpeg;
>  
>      cinfo->dest->next_output_byte = (JOCTET *)buffer->buffer + buffer->offset;
>      cinfo->dest->free_in_buffer = (size_t)(buffer->capacity - buffer->offset);
> @@ -1159,10 +1159,10 @@ static void jpeg_init_destination(j_compress_ptr cinfo)
>  static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo)
>  {
>      VncState *vs = cinfo->client_data;
> -    Buffer *buffer = &vs->tight.jpeg;
> +    QIOBuffer *buffer = &vs->tight.jpeg;
>  
>      buffer->offset = buffer->capacity;
> -    buffer_reserve(buffer, 2048);
> +    qio_buffer_reserve(buffer, 2048);
>      jpeg_init_destination(cinfo);
>      return TRUE;
>  }
> @@ -1171,7 +1171,7 @@ static boolean jpeg_empty_output_buffer(j_compress_ptr cinfo)
>  static void jpeg_term_destination(j_compress_ptr cinfo)
>  {
>      VncState *vs = cinfo->client_data;
> -    Buffer *buffer = &vs->tight.jpeg;
> +    QIOBuffer *buffer = &vs->tight.jpeg;
>  
>      buffer->offset = buffer->capacity - cinfo->dest->free_in_buffer;
>  }
> @@ -1190,7 +1190,7 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality)
>          return send_full_color_rect(vs, x, y, w, h);
>      }
>  
> -    buffer_reserve(&vs->tight.jpeg, 2048);
> +    qio_buffer_reserve(&vs->tight.jpeg, 2048);
>  
>      cinfo.err = jpeg_std_error(&jerr);
>      jpeg_create_compress(&cinfo);
> @@ -1227,7 +1227,7 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality)
>  
>      tight_send_compact_size(vs, vs->tight.jpeg.offset);
>      vnc_write(vs, vs->tight.jpeg.buffer, vs->tight.jpeg.offset);
> -    buffer_reset(&vs->tight.jpeg);
> +    qio_buffer_reset(&vs->tight.jpeg);
>  
>      return 1;
>  }
> @@ -1270,7 +1270,7 @@ static void png_write_data(png_structp png_ptr, png_bytep data,
>  {
>      VncState *vs = png_get_io_ptr(png_ptr);
>  
> -    buffer_reserve(&vs->tight.png, vs->tight.png.offset + length);
> +    qio_buffer_reserve(&vs->tight.png, vs->tight.png.offset + length);
>      memcpy(vs->tight.png.buffer + vs->tight.png.offset, data, length);
>  
>      vs->tight.png.offset += length;
> @@ -1351,7 +1351,7 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
>  
>      png_write_info(png_ptr, info_ptr);
>  
> -    buffer_reserve(&vs->tight.png, 2048);
> +    qio_buffer_reserve(&vs->tight.png, 2048);
>      linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, w);
>      buf = (uint8_t *)pixman_image_get_data(linebuf);
>      for (dy = 0; dy < h; dy++)
> @@ -1377,14 +1377,14 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
>  
>      tight_send_compact_size(vs, vs->tight.png.offset);
>      vnc_write(vs, vs->tight.png.buffer, vs->tight.png.offset);
> -    buffer_reset(&vs->tight.png);
> +    qio_buffer_reset(&vs->tight.png);
>      return 1;
>  }
>  #endif /* CONFIG_VNC_PNG */
>  
>  static void vnc_tight_start(VncState *vs)
>  {
> -    buffer_reset(&vs->tight.tight);
> +    qio_buffer_reset(&vs->tight.tight);
>  
>      // make the output buffer be the zlib buffer, so we can compress it later
>      vs->tight.tmp = vs->output;
> @@ -1686,13 +1686,13 @@ void vnc_tight_clear(VncState *vs)
>          }
>      }
>  
> -    buffer_free(&vs->tight.tight);
> -    buffer_free(&vs->tight.zlib);
> -    buffer_free(&vs->tight.gradient);
> +    qio_buffer_free(&vs->tight.tight);
> +    qio_buffer_free(&vs->tight.zlib);
> +    qio_buffer_free(&vs->tight.gradient);
>  #ifdef CONFIG_VNC_JPEG
> -    buffer_free(&vs->tight.jpeg);
> +    qio_buffer_free(&vs->tight.jpeg);
>  #endif
>  #ifdef CONFIG_VNC_PNG
> -    buffer_free(&vs->tight.png);
> +    qio_buffer_free(&vs->tight.png);
>  #endif
>  }
> diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c
> index d1b97f2..47ba146 100644
> --- a/ui/vnc-enc-zlib.c
> +++ b/ui/vnc-enc-zlib.c
> @@ -47,7 +47,7 @@ void vnc_zlib_zfree(void *x, void *addr)
>  
>  static void vnc_zlib_start(VncState *vs)
>  {
> -    buffer_reset(&vs->zlib.zlib);
> +    qio_buffer_reset(&vs->zlib.zlib);
>  
>      // make the output buffer be the zlib buffer, so we can compress it later
>      vs->zlib.tmp = vs->output;
> @@ -96,7 +96,7 @@ static int vnc_zlib_stop(VncState *vs)
>      }
>  
>      // reserve memory in output buffer
> -    buffer_reserve(&vs->output, vs->zlib.zlib.offset + 64);
> +    qio_buffer_reserve(&vs->output, vs->zlib.zlib.offset + 64);
>  
>      // set pointers
>      zstream->next_in = vs->zlib.zlib.buffer;
> @@ -148,5 +148,5 @@ void vnc_zlib_clear(VncState *vs)
>      if (vs->zlib.stream.opaque) {
>          deflateEnd(&vs->zlib.stream);
>      }
> -    buffer_free(&vs->zlib.zlib);
> +    qio_buffer_free(&vs->zlib.zlib);
>  }
> diff --git a/ui/vnc-enc-zrle.c b/ui/vnc-enc-zrle.c
> index ed3b484..bd1e320 100644
> --- a/ui/vnc-enc-zrle.c
> +++ b/ui/vnc-enc-zrle.c
> @@ -36,7 +36,7 @@ static const int bits_per_packed_pixel[] = {
>  
>  static void vnc_zrle_start(VncState *vs)
>  {
> -    buffer_reset(&vs->zrle.zrle);
> +    qio_buffer_reset(&vs->zrle.zrle);
>  
>      /* make the output buffer be the zlib buffer, so we can compress it later */
>      vs->zrle.tmp = vs->output;
> @@ -53,10 +53,10 @@ static void vnc_zrle_stop(VncState *vs)
>  static void *zrle_convert_fb(VncState *vs, int x, int y, int w, int h,
>                               int bpp)
>  {
> -    Buffer tmp;
> +    QIOBuffer tmp;
>  
> -    buffer_reset(&vs->zrle.fb);
> -    buffer_reserve(&vs->zrle.fb, w * h * bpp + bpp);
> +    qio_buffer_reset(&vs->zrle.fb);
> +    qio_buffer_reserve(&vs->zrle.fb, w * h * bpp + bpp);
>  
>      tmp = vs->output;
>      vs->output = vs->zrle.fb;
> @@ -72,7 +72,7 @@ static int zrle_compress_data(VncState *vs, int level)
>  {
>      z_streamp zstream = &vs->zrle.stream;
>  
> -    buffer_reset(&vs->zrle.zlib);
> +    qio_buffer_reset(&vs->zrle.zlib);
>  
>      if (zstream->opaque != vs) {
>          int err;
> @@ -92,7 +92,7 @@ static int zrle_compress_data(VncState *vs, int level)
>      }
>  
>      /* reserve memory in output buffer */
> -    buffer_reserve(&vs->zrle.zlib, vs->zrle.zrle.offset + 64);
> +    qio_buffer_reserve(&vs->zrle.zlib, vs->zrle.zrle.offset + 64);
>  
>      /* set pointers */
>      zstream->next_in = vs->zrle.zrle.buffer;
> @@ -360,7 +360,7 @@ void vnc_zrle_clear(VncState *vs)
>      if (vs->zrle.stream.opaque) {
>          deflateEnd(&vs->zrle.stream);
>      }
> -    buffer_free(&vs->zrle.zrle);
> -    buffer_free(&vs->zrle.fb);
> -    buffer_free(&vs->zrle.zlib);
> +    qio_buffer_free(&vs->zrle.zrle);
> +    qio_buffer_free(&vs->zrle.fb);
> +    qio_buffer_free(&vs->zrle.zlib);
>  }
> diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c
> index 22c9abc..9824c34 100644
> --- a/ui/vnc-jobs.c
> +++ b/ui/vnc-jobs.c
> @@ -54,7 +54,7 @@ struct VncJobQueue {
>      QemuCond cond;
>      QemuMutex mutex;
>      QemuThread thread;
> -    Buffer buffer;
> +    QIOBuffer buffer;
>      bool exit;
>      QTAILQ_HEAD(, VncJob) jobs;
>  };
> @@ -167,7 +167,7 @@ void vnc_jobs_consume_buffer(VncState *vs)
>      vnc_lock_output(vs);
>      if (vs->jobs_buffer.offset) {
>          vnc_write(vs, vs->jobs_buffer.buffer, vs->jobs_buffer.offset);
> -        buffer_reset(&vs->jobs_buffer);
> +        qio_buffer_reset(&vs->jobs_buffer);
>      }
>      flush = vs->csock != -1 && vs->abort != true;
>      vnc_unlock_output(vs);
> @@ -196,7 +196,7 @@ static void vnc_async_encoding_start(VncState *orig, VncState *local)
>      local->output =  queue->buffer;
>      local->csock = -1; /* Don't do any network work on this thread */
>  
> -    buffer_reset(&local->output);
> +    qio_buffer_reset(&local->output);
>  }
>  
>  static void vnc_async_encoding_end(VncState *orig, VncState *local)
> @@ -273,10 +273,11 @@ static int vnc_worker_thread_loop(VncJobQueue *queue)
>      vs.output.buffer[saved_offset + 1] = n_rectangles & 0xFF;
>  
>      vnc_lock_output(job->vs);
> +
>      if (job->vs->csock != -1) {
> -        buffer_reserve(&job->vs->jobs_buffer, vs.output.offset);
> -        buffer_append(&job->vs->jobs_buffer, vs.output.buffer,
> -                      vs.output.offset);
> +        qio_buffer_reserve(&job->vs->jobs_buffer, vs.output.offset);
> +        qio_buffer_append(&job->vs->jobs_buffer, vs.output.buffer,
> +                          vs.output.offset);
>          /* Copy persistent encoding data */
>          vnc_async_encoding_end(job->vs, &vs);
>  
> @@ -310,7 +311,7 @@ static void vnc_queue_clear(VncJobQueue *q)
>  {
>      qemu_cond_destroy(&queue->cond);
>      qemu_mutex_destroy(&queue->mutex);
> -    buffer_free(&queue->buffer);
> +    qio_buffer_free(&queue->buffer);
>      g_free(q);
>      queue = NULL; /* Unset global queue */
>  }
> diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
> index 175ea50..2fe4476 100644
> --- a/ui/vnc-ws.c
> +++ b/ui/vnc-ws.c
> @@ -95,8 +95,8 @@ void vncws_handshake_read(void *opaque)
>      /* Typical HTTP headers from novnc are 512 bytes, so limiting
>       * total header size to 4096 is easily enough. */
>      size_t want = 4096 - vs->ws_input.offset;
> -    buffer_reserve(&vs->ws_input, want);
> -    ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), want);
> +    qio_buffer_reserve(&vs->ws_input, want);
> +    ret = vnc_client_read_buf(vs, qio_buffer_end(&vs->ws_input), want);
>  
>      if (!ret) {
>          if (vs->csock == -1) {
> @@ -111,7 +111,7 @@ void vncws_handshake_read(void *opaque)
>      if (handshake_end) {
>          qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
>          vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset);
> -        buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer +
> +        qio_buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer +
>                  strlen(WS_HANDSHAKE_END));
>      } else if (vs->ws_input.offset >= 4096) {
>          VNC_DEBUG("End of headers not found in first 4096 bytes\n");
> @@ -127,8 +127,8 @@ long vnc_client_read_ws(VncState *vs)
>      size_t payload_size, header_size;
>      VNC_DEBUG("Read websocket %p size %zd offset %zd\n", vs->ws_input.buffer,
>              vs->ws_input.capacity, vs->ws_input.offset);
> -    buffer_reserve(&vs->ws_input, 4096);
> -    ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096);
> +    qio_buffer_reserve(&vs->ws_input, 4096);
> +    ret = vnc_client_read_buf(vs, qio_buffer_end(&vs->ws_input), 4096);
>      if (!ret) {
>          return 0;
>      }
> @@ -146,7 +146,7 @@ long vnc_client_read_ws(VncState *vs)
>                  return err;
>              }
>  
> -            buffer_advance(&vs->ws_input, header_size);
> +            qio_buffer_advance(&vs->ws_input, header_size);
>          }
>          if (vs->ws_payload_remain != 0) {
>              err = vncws_decode_frame_payload(&vs->ws_input,
> @@ -162,10 +162,10 @@ long vnc_client_read_ws(VncState *vs)
>              }
>              ret += err;
>  
> -            buffer_reserve(&vs->input, payload_size);
> -            buffer_append(&vs->input, payload, payload_size);
> +            qio_buffer_reserve(&vs->input, payload_size);
> +            qio_buffer_append(&vs->input, payload, payload_size);
>  
> -            buffer_advance(&vs->ws_input, payload_size);
> +            qio_buffer_advance(&vs->ws_input, payload_size);
>          }
>      } while (vs->ws_input.offset > 0);
>  
> @@ -178,13 +178,13 @@ long vnc_client_write_ws(VncState *vs)
>      VNC_DEBUG("Write WS: Pending output %p size %zd offset %zd\n",
>                vs->output.buffer, vs->output.capacity, vs->output.offset);
>      vncws_encode_frame(&vs->ws_output, vs->output.buffer, vs->output.offset);
> -    buffer_reset(&vs->output);
> +    qio_buffer_reset(&vs->output);
>      ret = vnc_client_write_buf(vs, vs->ws_output.buffer, vs->ws_output.offset);
>      if (!ret) {
>          return 0;
>      }
>  
> -    buffer_advance(&vs->ws_output, ret);
> +    qio_buffer_advance(&vs->ws_output, ret);
>  
>      if (vs->ws_output.offset == 0) {
>          qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
> @@ -267,8 +267,8 @@ void vncws_process_handshake(VncState *vs, uint8_t *line, size_t size)
>      g_free(key);
>  }
>  
> -void vncws_encode_frame(Buffer *output, const void *payload,
> -        const size_t payload_size)
> +void vncws_encode_frame(QIOBuffer *output, const void *payload,
> +                        const size_t payload_size)
>  {
>      size_t header_size = 0;
>      unsigned char opcode = WS_OPCODE_BINARY_FRAME;
> @@ -295,12 +295,12 @@ void vncws_encode_frame(Buffer *output, const void *payload,
>          header_size = 10;
>      }
>  
> -    buffer_reserve(output, header_size + payload_size);
> -    buffer_append(output, header.buf, header_size);
> -    buffer_append(output, payload, payload_size);
> +    qio_buffer_reserve(output, header_size + payload_size);
> +    qio_buffer_append(output, header.buf, header_size);
> +    qio_buffer_append(output, payload, payload_size);
>  }
>  
> -int vncws_decode_frame_header(Buffer *input,
> +int vncws_decode_frame_header(QIOBuffer *input,
>                                size_t *header_size,
>                                size_t *payload_remain,
>                                WsMask *payload_mask)
> @@ -354,7 +354,7 @@ int vncws_decode_frame_header(Buffer *input,
>      return 1;
>  }
>  
> -int vncws_decode_frame_payload(Buffer *input,
> +int vncws_decode_frame_payload(QIOBuffer *input,
>                                 size_t *payload_remain, WsMask *payload_mask,
>                                 uint8_t **payload, size_t *payload_size)
>  {
> diff --git a/ui/vnc-ws.h b/ui/vnc-ws.h
> index 4ab0a8c..2a222a8 100644
> --- a/ui/vnc-ws.h
> +++ b/ui/vnc-ws.h
> @@ -77,13 +77,13 @@ void vncws_handshake_read(void *opaque);
>  long vnc_client_write_ws(VncState *vs);
>  long vnc_client_read_ws(VncState *vs);
>  void vncws_process_handshake(VncState *vs, uint8_t *line, size_t size);
> -void vncws_encode_frame(Buffer *output, const void *payload,
> +void vncws_encode_frame(QIOBuffer *output, const void *payload,
>              const size_t payload_size);
> -int vncws_decode_frame_header(Buffer *input,
> +int vncws_decode_frame_header(QIOBuffer *input,
>                                size_t *header_size,
>                                size_t *payload_remain,
>                                WsMask *payload_mask);
> -int vncws_decode_frame_payload(Buffer *input,
> +int vncws_decode_frame_payload(QIOBuffer *input,
>                                 size_t *payload_remain, WsMask *payload_mask,
>                                 uint8_t **payload, size_t *payload_size);
>  
> diff --git a/ui/vnc.c b/ui/vnc.c
> index bbe1e91..e4b0e3a 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -647,49 +647,6 @@ void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
>      vnc_write_s32(vs, encoding);
>  }
>  
> -void buffer_reserve(Buffer *buffer, size_t len)
> -{
> -    if ((buffer->capacity - buffer->offset) < len) {
> -        buffer->capacity += (len + 1024);
> -        buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
> -    }
> -}
> -
> -static int buffer_empty(Buffer *buffer)
> -{
> -    return buffer->offset == 0;
> -}
> -
> -uint8_t *buffer_end(Buffer *buffer)
> -{
> -    return buffer->buffer + buffer->offset;
> -}
> -
> -void buffer_reset(Buffer *buffer)
> -{
> -        buffer->offset = 0;
> -}
> -
> -void buffer_free(Buffer *buffer)
> -{
> -    g_free(buffer->buffer);
> -    buffer->offset = 0;
> -    buffer->capacity = 0;
> -    buffer->buffer = NULL;
> -}
> -
> -void buffer_append(Buffer *buffer, const void *data, size_t len)
> -{
> -    memcpy(buffer->buffer + buffer->offset, data, len);
> -    buffer->offset += len;
> -}
> -
> -void buffer_advance(Buffer *buf, size_t len)
> -{
> -    memmove(buf->buffer, buf->buffer + len,
> -            (buf->offset - len));
> -    buf->offset -= len;
> -}
>  
>  static void vnc_desktop_resize(VncState *vs)
>  {
> @@ -1236,10 +1193,10 @@ void vnc_disconnect_finish(VncState *vs)
>      vnc_lock_output(vs);
>      vnc_qmp_event(vs, QAPI_EVENT_VNC_DISCONNECTED);
>  
> -    buffer_free(&vs->input);
> -    buffer_free(&vs->output);
> -    buffer_free(&vs->ws_input);
> -    buffer_free(&vs->ws_output);
> +    qio_buffer_free(&vs->input);
> +    qio_buffer_free(&vs->output);
> +    qio_buffer_free(&vs->ws_input);
> +    qio_buffer_free(&vs->ws_output);
>  
>      qapi_free_VncClientInfo(vs->info);
>  
> @@ -1267,7 +1224,7 @@ void vnc_disconnect_finish(VncState *vs)
>      if (vs->bh != NULL) {
>          qemu_bh_delete(vs->bh);
>      }
> -    buffer_free(&vs->jobs_buffer);
> +    qio_buffer_free(&vs->jobs_buffer);
>  
>      for (i = 0; i < VNC_STAT_ROWS; ++i) {
>          g_free(vs->lossy_rect[i]);
> @@ -1409,7 +1366,7 @@ static ssize_t vnc_client_write_plain(VncState *vs)
>      if (!ret)
>          return 0;
>  
> -    buffer_advance(&vs->output, ret);
> +    qio_buffer_advance(&vs->output, ret);
>  
>      if (vs->output.offset == 0) {
>          qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs);
> @@ -1512,8 +1469,8 @@ static ssize_t vnc_client_read_plain(VncState *vs)
>      ssize_t ret;
>      VNC_DEBUG("Read plain %p size %zd offset %zd\n",
>                vs->input.buffer, vs->input.capacity, vs->input.offset);
> -    buffer_reserve(&vs->input, 4096);
> -    ret = vnc_client_read_buf(vs, buffer_end(&vs->input), 4096);
> +    qio_buffer_reserve(&vs->input, 4096);
> +    ret = vnc_client_read_buf(vs, qio_buffer_end(&vs->input), 4096);
>      if (!ret)
>          return 0;
>      vs->input.offset += ret;
> @@ -1571,7 +1528,7 @@ void vnc_client_read(void *opaque)
>          }
>  
>          if (!ret) {
> -            buffer_advance(&vs->input, len);
> +            qio_buffer_advance(&vs->input, len);
>          } else {
>              vs->read_handler_expect = ret;
>          }
> @@ -1580,13 +1537,13 @@ void vnc_client_read(void *opaque)
>  
>  void vnc_write(VncState *vs, const void *data, size_t len)
>  {
> -    buffer_reserve(&vs->output, len);
> +    qio_buffer_reserve(&vs->output, len);
>  
> -    if (vs->csock != -1 && buffer_empty(&vs->output)) {
> +    if (vs->csock != -1 && qio_buffer_empty(&vs->output)) {
>          qemu_set_fd_handler(vs->csock, vnc_client_read, vnc_client_write, vs);
>      }
>  
> -    buffer_append(&vs->output, data, len);
> +    qio_buffer_append(&vs->output, data, len);
>  }
>  
>  void vnc_write_s32(VncState *vs, int32_t value)
> diff --git a/ui/vnc.h b/ui/vnc.h
> index 4dd769c..339a1bf 100644
> --- a/ui/vnc.h
> +++ b/ui/vnc.h
> @@ -34,6 +34,7 @@
>  #include "audio/audio.h"
>  #include "qemu/bitmap.h"
>  #include "crypto/tlssession.h"
> +#include "io/buffer.h"
>  #include <zlib.h>
>  #include <stdbool.h>
>  
> @@ -56,13 +57,6 @@
>   *
>   *****************************************************************************/
>  
> -typedef struct Buffer
> -{
> -    size_t capacity;
> -    size_t offset;
> -    uint8_t *buffer;
> -} Buffer;
> -
>  typedef struct VncState VncState;
>  typedef struct VncJob VncJob;
>  typedef struct VncRect VncRect;
> @@ -191,15 +185,15 @@ typedef struct VncTight {
>      uint8_t quality;
>      uint8_t compression;
>      uint8_t pixel24;
> -    Buffer tight;
> -    Buffer tmp;
> -    Buffer zlib;
> -    Buffer gradient;
> +    QIOBuffer tight;
> +    QIOBuffer tmp;
> +    QIOBuffer zlib;
> +    QIOBuffer gradient;
>  #ifdef CONFIG_VNC_JPEG
> -    Buffer jpeg;
> +    QIOBuffer jpeg;
>  #endif
>  #ifdef CONFIG_VNC_PNG
> -    Buffer png;
> +    QIOBuffer png;
>  #endif
>      int levels[4];
>      z_stream stream[4];
> @@ -210,18 +204,18 @@ typedef struct VncHextile {
>  } VncHextile;
>  
>  typedef struct VncZlib {
> -    Buffer zlib;
> -    Buffer tmp;
> +    QIOBuffer zlib;
> +    QIOBuffer tmp;
>      z_stream stream;
>      int level;
>  } VncZlib;
>  
>  typedef struct VncZrle {
>      int type;
> -    Buffer fb;
> -    Buffer zrle;
> -    Buffer tmp;
> -    Buffer zlib;
> +    QIOBuffer fb;
> +    QIOBuffer zrle;
> +    QIOBuffer tmp;
> +    QIOBuffer zlib;
>      z_stream stream;
>      VncPalette palette;
>  } VncZrle;
> @@ -290,10 +284,10 @@ struct VncState
>  
>      VncClientInfo *info;
>  
> -    Buffer output;
> -    Buffer input;
> -    Buffer ws_input;
> -    Buffer ws_output;
> +    QIOBuffer output;
> +    QIOBuffer input;
> +    QIOBuffer ws_input;
> +    QIOBuffer ws_output;
>      size_t ws_payload_remain;
>      WsMask ws_payload_mask;
>      /* current output mode information */
> @@ -315,7 +309,7 @@ struct VncState
>      bool initialized;
>      QemuMutex output_mutex;
>      QEMUBH *bh;
> -    Buffer jobs_buffer;
> +    QIOBuffer jobs_buffer;
>  
>      /* Encoding specific, if you add something here, don't forget to
>       *  update vnc_async_encoding_start()
> @@ -535,14 +529,6 @@ ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, int last_errno);
>  void start_client_init(VncState *vs);
>  void start_auth_vnc(VncState *vs);
>  
> -/* Buffer management */
> -void buffer_reserve(Buffer *buffer, size_t len);
> -void buffer_reset(Buffer *buffer);
> -void buffer_free(Buffer *buffer);
> -void buffer_append(Buffer *buffer, const void *data, size_t len);
> -void buffer_advance(Buffer *buf, size_t len);
> -uint8_t *buffer_end(Buffer *buffer);
> -
>  
>  /* Misc helpers */
>  

Reviewed-by: Peter Lieven <pl@kamp.de>

  reply	other threads:[~2015-09-25  9:57 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-24  8:41 [Qemu-devel] [RfC PATCH 00/10] vnc buffer handling Gerd Hoffmann
2015-09-24  8:41 ` [Qemu-devel] [RfC PATCH 01/10] io/ makefile fluff Gerd Hoffmann
2015-09-24  8:42 ` [Qemu-devel] [RfC PATCH 02/10] io: pull Buffer code out of VNC module Gerd Hoffmann
2015-09-25  9:57   ` Peter Lieven [this message]
2015-09-24  8:42 ` [Qemu-devel] [RfC PATCH 03/10] vnc: make the Buffer capacity increase in powers of two Gerd Hoffmann
2015-09-24  8:42 ` [Qemu-devel] [RfC PATCH 04/10] io: add qio_buffer_init Gerd Hoffmann
2015-09-25  9:56   ` Peter Lieven
2015-09-24  8:42 ` [Qemu-devel] [RfC PATCH 05/10] io: add qio_buffer_move_empty Gerd Hoffmann
2015-09-25  9:56   ` Peter Lieven
2015-09-24  8:42 ` [Qemu-devel] [RfC PATCH 06/10] io: add qio_buffer_move Gerd Hoffmann
2015-09-25  9:57   ` Peter Lieven
2015-09-24  8:42 ` [Qemu-devel] [RfC PATCH 07/10] io: add qio_buffer tracing Gerd Hoffmann
2015-09-25  8:10   ` Peter Lieven
2015-09-24  8:42 ` [Qemu-devel] [RfC PATCH 08/10] name vnc buffers Gerd Hoffmann
2015-09-25  7:28   ` Peter Lieven
2015-09-25  7:58   ` Peter Lieven
2015-09-24  8:42 ` [Qemu-devel] [RfC PATCH 09/10] vnc: kill jobs queue buffer Gerd Hoffmann
2015-09-25  9:57   ` Peter Lieven
2015-09-24  8:42 ` [Qemu-devel] [RfC PATCH 10/10] vnc-jobs: move buffer reset, use new buffer move Gerd Hoffmann
2015-09-25  9:39   ` Peter Lieven
2015-09-24 16:25 ` [Qemu-devel] [RfC PATCH 00/10] vnc buffer handling Daniel P. Berrange
2015-09-25  9:56 ` Peter Lieven

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56051A8B.8010109@kamp.de \
    --to=pl@kamp.de \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.