io: add methods to set I/O handlers on AioContext
This is in preparation for making qio_channel_yield work on AioContexts other than the main one. Reviewed-by: Daniel P. Berrange <berrange@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Message-id: 20170213135235.12274-6-pbonzini@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
934ebf48c0
commit
bf88c1247f
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
|
#include "block/aio.h"
|
||||||
|
|
||||||
#define TYPE_QIO_CHANNEL "qio-channel"
|
#define TYPE_QIO_CHANNEL "qio-channel"
|
||||||
#define QIO_CHANNEL(obj) \
|
#define QIO_CHANNEL(obj) \
|
||||||
@ -132,6 +133,11 @@ struct QIOChannelClass {
|
|||||||
off_t offset,
|
off_t offset,
|
||||||
int whence,
|
int whence,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
void (*io_set_aio_fd_handler)(QIOChannel *ioc,
|
||||||
|
AioContext *ctx,
|
||||||
|
IOHandler *io_read,
|
||||||
|
IOHandler *io_write,
|
||||||
|
void *opaque);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* General I/O handling functions */
|
/* General I/O handling functions */
|
||||||
@ -525,4 +531,23 @@ void qio_channel_yield(QIOChannel *ioc,
|
|||||||
void qio_channel_wait(QIOChannel *ioc,
|
void qio_channel_wait(QIOChannel *ioc,
|
||||||
GIOCondition condition);
|
GIOCondition condition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qio_channel_set_aio_fd_handler:
|
||||||
|
* @ioc: the channel object
|
||||||
|
* @ctx: the AioContext to set the handlers on
|
||||||
|
* @io_read: the read handler
|
||||||
|
* @io_write: the write handler
|
||||||
|
* @opaque: the opaque value passed to the handler
|
||||||
|
*
|
||||||
|
* This is used internally by qio_channel_yield(). It can
|
||||||
|
* be used by channel implementations to forward the handlers
|
||||||
|
* to another channel (e.g. from #QIOChannelTLS to the
|
||||||
|
* underlying socket).
|
||||||
|
*/
|
||||||
|
void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
|
||||||
|
AioContext *ctx,
|
||||||
|
IOHandler *io_read,
|
||||||
|
IOHandler *io_write,
|
||||||
|
void *opaque);
|
||||||
|
|
||||||
#endif /* QIO_CHANNEL_H */
|
#endif /* QIO_CHANNEL_H */
|
||||||
|
@ -328,6 +328,18 @@ static int qio_channel_command_close(QIOChannel *ioc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void qio_channel_command_set_aio_fd_handler(QIOChannel *ioc,
|
||||||
|
AioContext *ctx,
|
||||||
|
IOHandler *io_read,
|
||||||
|
IOHandler *io_write,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
|
||||||
|
aio_set_fd_handler(ctx, cioc->readfd, false, io_read, NULL, NULL, opaque);
|
||||||
|
aio_set_fd_handler(ctx, cioc->writefd, false, NULL, io_write, NULL, opaque);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static GSource *qio_channel_command_create_watch(QIOChannel *ioc,
|
static GSource *qio_channel_command_create_watch(QIOChannel *ioc,
|
||||||
GIOCondition condition)
|
GIOCondition condition)
|
||||||
{
|
{
|
||||||
@ -349,6 +361,7 @@ static void qio_channel_command_class_init(ObjectClass *klass,
|
|||||||
ioc_klass->io_set_blocking = qio_channel_command_set_blocking;
|
ioc_klass->io_set_blocking = qio_channel_command_set_blocking;
|
||||||
ioc_klass->io_close = qio_channel_command_close;
|
ioc_klass->io_close = qio_channel_command_close;
|
||||||
ioc_klass->io_create_watch = qio_channel_command_create_watch;
|
ioc_klass->io_create_watch = qio_channel_command_create_watch;
|
||||||
|
ioc_klass->io_set_aio_fd_handler = qio_channel_command_set_aio_fd_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo qio_channel_command_info = {
|
static const TypeInfo qio_channel_command_info = {
|
||||||
|
@ -186,6 +186,16 @@ static int qio_channel_file_close(QIOChannel *ioc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void qio_channel_file_set_aio_fd_handler(QIOChannel *ioc,
|
||||||
|
AioContext *ctx,
|
||||||
|
IOHandler *io_read,
|
||||||
|
IOHandler *io_write,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc);
|
||||||
|
aio_set_fd_handler(ctx, fioc->fd, false, io_read, io_write, NULL, opaque);
|
||||||
|
}
|
||||||
|
|
||||||
static GSource *qio_channel_file_create_watch(QIOChannel *ioc,
|
static GSource *qio_channel_file_create_watch(QIOChannel *ioc,
|
||||||
GIOCondition condition)
|
GIOCondition condition)
|
||||||
{
|
{
|
||||||
@ -206,6 +216,7 @@ static void qio_channel_file_class_init(ObjectClass *klass,
|
|||||||
ioc_klass->io_seek = qio_channel_file_seek;
|
ioc_klass->io_seek = qio_channel_file_seek;
|
||||||
ioc_klass->io_close = qio_channel_file_close;
|
ioc_klass->io_close = qio_channel_file_close;
|
||||||
ioc_klass->io_create_watch = qio_channel_file_create_watch;
|
ioc_klass->io_create_watch = qio_channel_file_create_watch;
|
||||||
|
ioc_klass->io_set_aio_fd_handler = qio_channel_file_set_aio_fd_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo qio_channel_file_info = {
|
static const TypeInfo qio_channel_file_info = {
|
||||||
|
@ -649,11 +649,6 @@ qio_channel_socket_set_blocking(QIOChannel *ioc,
|
|||||||
qemu_set_block(sioc->fd);
|
qemu_set_block(sioc->fd);
|
||||||
} else {
|
} else {
|
||||||
qemu_set_nonblock(sioc->fd);
|
qemu_set_nonblock(sioc->fd);
|
||||||
#ifdef WIN32
|
|
||||||
WSAEventSelect(sioc->fd, ioc->event,
|
|
||||||
FD_READ | FD_ACCEPT | FD_CLOSE |
|
|
||||||
FD_CONNECT | FD_WRITE | FD_OOB);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -733,6 +728,16 @@ qio_channel_socket_shutdown(QIOChannel *ioc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qio_channel_socket_set_aio_fd_handler(QIOChannel *ioc,
|
||||||
|
AioContext *ctx,
|
||||||
|
IOHandler *io_read,
|
||||||
|
IOHandler *io_write,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
|
||||||
|
aio_set_fd_handler(ctx, sioc->fd, false, io_read, io_write, NULL, opaque);
|
||||||
|
}
|
||||||
|
|
||||||
static GSource *qio_channel_socket_create_watch(QIOChannel *ioc,
|
static GSource *qio_channel_socket_create_watch(QIOChannel *ioc,
|
||||||
GIOCondition condition)
|
GIOCondition condition)
|
||||||
{
|
{
|
||||||
@ -755,6 +760,7 @@ static void qio_channel_socket_class_init(ObjectClass *klass,
|
|||||||
ioc_klass->io_set_cork = qio_channel_socket_set_cork;
|
ioc_klass->io_set_cork = qio_channel_socket_set_cork;
|
||||||
ioc_klass->io_set_delay = qio_channel_socket_set_delay;
|
ioc_klass->io_set_delay = qio_channel_socket_set_delay;
|
||||||
ioc_klass->io_create_watch = qio_channel_socket_create_watch;
|
ioc_klass->io_create_watch = qio_channel_socket_create_watch;
|
||||||
|
ioc_klass->io_set_aio_fd_handler = qio_channel_socket_set_aio_fd_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo qio_channel_socket_info = {
|
static const TypeInfo qio_channel_socket_info = {
|
||||||
|
@ -345,6 +345,17 @@ static int qio_channel_tls_close(QIOChannel *ioc,
|
|||||||
return qio_channel_close(tioc->master, errp);
|
return qio_channel_close(tioc->master, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qio_channel_tls_set_aio_fd_handler(QIOChannel *ioc,
|
||||||
|
AioContext *ctx,
|
||||||
|
IOHandler *io_read,
|
||||||
|
IOHandler *io_write,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc);
|
||||||
|
|
||||||
|
qio_channel_set_aio_fd_handler(tioc->master, ctx, io_read, io_write, opaque);
|
||||||
|
}
|
||||||
|
|
||||||
static GSource *qio_channel_tls_create_watch(QIOChannel *ioc,
|
static GSource *qio_channel_tls_create_watch(QIOChannel *ioc,
|
||||||
GIOCondition condition)
|
GIOCondition condition)
|
||||||
{
|
{
|
||||||
@ -372,6 +383,7 @@ static void qio_channel_tls_class_init(ObjectClass *klass,
|
|||||||
ioc_klass->io_close = qio_channel_tls_close;
|
ioc_klass->io_close = qio_channel_tls_close;
|
||||||
ioc_klass->io_shutdown = qio_channel_tls_shutdown;
|
ioc_klass->io_shutdown = qio_channel_tls_shutdown;
|
||||||
ioc_klass->io_create_watch = qio_channel_tls_create_watch;
|
ioc_klass->io_create_watch = qio_channel_tls_create_watch;
|
||||||
|
ioc_klass->io_set_aio_fd_handler = qio_channel_tls_set_aio_fd_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo qio_channel_tls_info = {
|
static const TypeInfo qio_channel_tls_info = {
|
||||||
|
@ -285,6 +285,12 @@ GSource *qio_channel_create_socket_watch(QIOChannel *ioc,
|
|||||||
GSource *source;
|
GSource *source;
|
||||||
QIOChannelSocketSource *ssource;
|
QIOChannelSocketSource *ssource;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
WSAEventSelect(socket, ioc->event,
|
||||||
|
FD_READ | FD_ACCEPT | FD_CLOSE |
|
||||||
|
FD_CONNECT | FD_WRITE | FD_OOB);
|
||||||
|
#endif
|
||||||
|
|
||||||
source = g_source_new(&qio_channel_socket_source_funcs,
|
source = g_source_new(&qio_channel_socket_source_funcs,
|
||||||
sizeof(QIOChannelSocketSource));
|
sizeof(QIOChannelSocketSource));
|
||||||
ssource = (QIOChannelSocketSource *)source;
|
ssource = (QIOChannelSocketSource *)source;
|
||||||
|
11
io/channel.c
11
io/channel.c
@ -154,6 +154,17 @@ GSource *qio_channel_create_watch(QIOChannel *ioc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void qio_channel_set_aio_fd_handler(QIOChannel *ioc,
|
||||||
|
AioContext *ctx,
|
||||||
|
IOHandler *io_read,
|
||||||
|
IOHandler *io_write,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
|
||||||
|
|
||||||
|
klass->io_set_aio_fd_handler(ioc, ctx, io_read, io_write, opaque);
|
||||||
|
}
|
||||||
|
|
||||||
guint qio_channel_add_watch(QIOChannel *ioc,
|
guint qio_channel_add_watch(QIOChannel *ioc,
|
||||||
GIOCondition condition,
|
GIOCondition condition,
|
||||||
QIOChannelFunc func,
|
QIOChannelFunc func,
|
||||||
|
Loading…
Reference in New Issue
Block a user