mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
QIOChannel: Add flags on io_writev and introduce io_flush callback
Add flags to io_writev and introduce io_flush as optional callback to QIOChannelClass, allowing the implementation of zero copy writes by subclasses. How to use them: - Write data using qio_channel_writev*(...,QIO_CHANNEL_WRITE_FLAG_ZERO_COPY), - Wait write completion with qio_channel_flush(). Notes: As some zero copy write implementations work asynchronously, it's recommended to keep the write buffer untouched until the return of qio_channel_flush(), to avoid the risk of sending an updated buffer instead of the buffer state during write. As io_flush callback is optional, if a subclass does not implement it, then: - io_flush will return 0 without changing anything. Also, some functions like qio_channel_writev_full_all() were adapted to receive a flag parameter. That allows shared code between zero copy and non-zero copy writev, and also an easier implementation on new flags. Signed-off-by: Leonardo Bras <leobras@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Juan Quintela <quintela@redhat.com> Message-Id: <20220513062836.965425-3-leobras@redhat.com> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
This commit is contained in:
parent
354081d43d
commit
b88651cb4d
13 changed files with 88 additions and 14 deletions
|
@ -32,12 +32,15 @@ OBJECT_DECLARE_TYPE(QIOChannel, QIOChannelClass,
|
|||
|
||||
#define QIO_CHANNEL_ERR_BLOCK -2
|
||||
|
||||
#define QIO_CHANNEL_WRITE_FLAG_ZERO_COPY 0x1
|
||||
|
||||
typedef enum QIOChannelFeature QIOChannelFeature;
|
||||
|
||||
enum QIOChannelFeature {
|
||||
QIO_CHANNEL_FEATURE_FD_PASS,
|
||||
QIO_CHANNEL_FEATURE_SHUTDOWN,
|
||||
QIO_CHANNEL_FEATURE_LISTEN,
|
||||
QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY,
|
||||
};
|
||||
|
||||
|
||||
|
@ -104,6 +107,7 @@ struct QIOChannelClass {
|
|||
size_t niov,
|
||||
int *fds,
|
||||
size_t nfds,
|
||||
int flags,
|
||||
Error **errp);
|
||||
ssize_t (*io_readv)(QIOChannel *ioc,
|
||||
const struct iovec *iov,
|
||||
|
@ -136,6 +140,8 @@ struct QIOChannelClass {
|
|||
IOHandler *io_read,
|
||||
IOHandler *io_write,
|
||||
void *opaque);
|
||||
int (*io_flush)(QIOChannel *ioc,
|
||||
Error **errp);
|
||||
};
|
||||
|
||||
/* General I/O handling functions */
|
||||
|
@ -228,6 +234,7 @@ ssize_t qio_channel_readv_full(QIOChannel *ioc,
|
|||
* @niov: the length of the @iov array
|
||||
* @fds: an array of file handles to send
|
||||
* @nfds: number of file handles in @fds
|
||||
* @flags: write flags (QIO_CHANNEL_WRITE_FLAG_*)
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Write data to the IO channel, reading it from the
|
||||
|
@ -260,6 +267,7 @@ ssize_t qio_channel_writev_full(QIOChannel *ioc,
|
|||
size_t niov,
|
||||
int *fds,
|
||||
size_t nfds,
|
||||
int flags,
|
||||
Error **errp);
|
||||
|
||||
/**
|
||||
|
@ -837,6 +845,7 @@ int qio_channel_readv_full_all(QIOChannel *ioc,
|
|||
* @niov: the length of the @iov array
|
||||
* @fds: an array of file handles to send
|
||||
* @nfds: number of file handles in @fds
|
||||
* @flags: write flags (QIO_CHANNEL_WRITE_FLAG_*)
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
*
|
||||
|
@ -846,6 +855,14 @@ int qio_channel_readv_full_all(QIOChannel *ioc,
|
|||
* to be written, yielding from the current coroutine
|
||||
* if required.
|
||||
*
|
||||
* If QIO_CHANNEL_WRITE_FLAG_ZERO_COPY is passed in flags,
|
||||
* instead of waiting for all requested data to be written,
|
||||
* this function will wait until it's all queued for writing.
|
||||
* In this case, if the buffer gets changed between queueing and
|
||||
* sending, the updated buffer will be sent. If this is not a
|
||||
* desired behavior, it's suggested to call qio_channel_flush()
|
||||
* before reusing the buffer.
|
||||
*
|
||||
* Returns: 0 if all bytes were written, or -1 on error
|
||||
*/
|
||||
|
||||
|
@ -853,6 +870,25 @@ int qio_channel_writev_full_all(QIOChannel *ioc,
|
|||
const struct iovec *iov,
|
||||
size_t niov,
|
||||
int *fds, size_t nfds,
|
||||
Error **errp);
|
||||
int flags, Error **errp);
|
||||
|
||||
/**
|
||||
* qio_channel_flush:
|
||||
* @ioc: the channel object
|
||||
* @errp: pointer to a NULL-initialized error object
|
||||
*
|
||||
* Will block until every packet queued with
|
||||
* qio_channel_writev_full() + QIO_CHANNEL_WRITE_FLAG_ZERO_COPY
|
||||
* is sent, or return in case of any error.
|
||||
*
|
||||
* If not implemented, acts as a no-op, and returns 0.
|
||||
*
|
||||
* Returns -1 if any error is found,
|
||||
* 1 if every send failed to use zero copy.
|
||||
* 0 otherwise.
|
||||
*/
|
||||
|
||||
int qio_channel_flush(QIOChannel *ioc,
|
||||
Error **errp);
|
||||
|
||||
#endif /* QIO_CHANNEL_H */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue