qemu-char: add watch support
This allows a front-end to request for a callback when the backend is writable again. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Amit Shah <amit.shah@redhat.com> Message-id: 96f93c0f741064604bbb6389ce962191120af8b7.1362505276.git.amit.shah@redhat.com Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
2ea5a7af7b
commit
23673ca740
@ -56,6 +56,7 @@ typedef void IOEventHandler(void *opaque, int event);
|
||||
struct CharDriverState {
|
||||
void (*init)(struct CharDriverState *s);
|
||||
int (*chr_write)(struct CharDriverState *s, const uint8_t *buf, int len);
|
||||
GSource *(*chr_add_watch)(struct CharDriverState *s, GIOCondition cond);
|
||||
void (*chr_update_read_handler)(struct CharDriverState *s);
|
||||
int (*chr_ioctl)(struct CharDriverState *s, int cmd, void *arg);
|
||||
int (*get_msgfd)(struct CharDriverState *s);
|
||||
@ -152,6 +153,9 @@ void qemu_chr_fe_close(struct CharDriverState *chr);
|
||||
void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
|
||||
GCC_FMT_ATTR(2, 3);
|
||||
|
||||
guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
|
||||
GIOFunc func, void *user_data);
|
||||
|
||||
/**
|
||||
* @qemu_chr_fe_write:
|
||||
*
|
||||
|
32
qemu-char.c
32
qemu-char.c
@ -686,7 +686,11 @@ static int io_channel_send_all(GIOChannel *fd, const void *_buf, int len1)
|
||||
status = g_io_channel_write_chars(fd, (const gchar *)buf, len,
|
||||
&bytes_written, NULL);
|
||||
if (status != G_IO_STATUS_NORMAL) {
|
||||
if (status != G_IO_STATUS_AGAIN) {
|
||||
if (status == G_IO_STATUS_AGAIN) {
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
} else {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
} else if (status == G_IO_STATUS_EOF) {
|
||||
@ -753,6 +757,12 @@ static int fd_chr_read_poll(void *opaque)
|
||||
return s->max_size;
|
||||
}
|
||||
|
||||
static GSource *fd_chr_add_watch(CharDriverState *chr, GIOCondition cond)
|
||||
{
|
||||
FDCharDriver *s = chr->opaque;
|
||||
return g_io_create_watch(s->fd_out, cond);
|
||||
}
|
||||
|
||||
static void fd_chr_update_read_handler(CharDriverState *chr)
|
||||
{
|
||||
FDCharDriver *s = chr->opaque;
|
||||
@ -796,8 +806,10 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
|
||||
s = g_malloc0(sizeof(FDCharDriver));
|
||||
s->fd_in = io_channel_from_fd(fd_in);
|
||||
s->fd_out = io_channel_from_fd(fd_out);
|
||||
fcntl(fd_out, F_SETFL, O_NONBLOCK);
|
||||
s->chr = chr;
|
||||
chr->opaque = s;
|
||||
chr->chr_add_watch = fd_chr_add_watch;
|
||||
chr->chr_write = fd_chr_write;
|
||||
chr->chr_update_read_handler = fd_chr_update_read_handler;
|
||||
chr->chr_close = fd_chr_close;
|
||||
@ -3279,6 +3291,24 @@ void qemu_chr_fe_close(struct CharDriverState *chr)
|
||||
}
|
||||
}
|
||||
|
||||
guint qemu_chr_fe_add_watch(CharDriverState *s, GIOCondition cond,
|
||||
GIOFunc func, void *user_data)
|
||||
{
|
||||
GSource *src;
|
||||
guint tag;
|
||||
|
||||
if (s->chr_add_watch == NULL) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
src = s->chr_add_watch(s, cond);
|
||||
g_source_set_callback(src, (GSourceFunc)func, user_data, NULL);
|
||||
tag = g_source_attach(src, NULL);
|
||||
g_source_unref(src);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
void qemu_chr_delete(CharDriverState *chr)
|
||||
{
|
||||
QTAILQ_REMOVE(&chardevs, chr, next);
|
||||
|
Loading…
Reference in New Issue
Block a user