Skip to content

Commit

Permalink
qemu-char: add watch support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Anthony Liguori committed Mar 8, 2013
1 parent 2ea5a7a commit 23673ca
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
4 changes: 4 additions & 0 deletions include/char/char.h
Expand Up @@ -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);
Expand Down Expand Up @@ -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:
*
Expand Down
32 changes: 31 additions & 1 deletion qemu-char.c
Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 23673ca

Please sign in to comment.