Skip to content
Snippets Groups Projects
Commit f7ea2038 authored by Marc-André Lureau's avatar Marc-André Lureau
Browse files

char-pty: remove write_lock usage


The lock usage was described with its introduction in commit
9005b2a7. It was necessary because PTY
write() shares more state than GIOChannel with other
operations.

This made char-pty a bit different from other chardev, that only lock
around the write operation.  This was apparent in commit
7b3621f4, which introduced an idle
source to avoid the lock.

By removing the PTY chardev state sharing on write() with previous
patch, we can remove the lock and the idle source.

Signed-off-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20190206174328.9736-7-marcandre.lureau@redhat.com>
Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent f8278c7d
No related branches found
No related tags found
No related merge requests found
......@@ -36,15 +36,12 @@ typedef struct {
QIOChannel *ioc;
int read_bytes;
/* Protected by the Chardev chr_write_lock. */
int connected;
GSource *timer_src;
GSource *open_source;
} PtyChardev;
#define PTY_CHARDEV(obj) OBJECT_CHECK(PtyChardev, (obj), TYPE_CHARDEV_PTY)
static void pty_chr_update_read_handler_locked(Chardev *chr);
static void pty_chr_state(Chardev *chr, int connected);
static void pty_chr_timer_cancel(PtyChardev *s)
......@@ -56,32 +53,19 @@ static void pty_chr_timer_cancel(PtyChardev *s)
}
}
static void pty_chr_open_src_cancel(PtyChardev *s)
{
if (s->open_source) {
g_source_destroy(s->open_source);
g_source_unref(s->open_source);
s->open_source = NULL;
}
}
static gboolean pty_chr_timer(gpointer opaque)
{
struct Chardev *chr = CHARDEV(opaque);
PtyChardev *s = PTY_CHARDEV(opaque);
qemu_mutex_lock(&chr->chr_write_lock);
pty_chr_timer_cancel(s);
pty_chr_open_src_cancel(s);
if (!s->connected) {
/* Next poll ... */
pty_chr_update_read_handler_locked(chr);
qemu_chr_be_update_read_handlers(chr, chr->gcontext);
}
qemu_mutex_unlock(&chr->chr_write_lock);
return FALSE;
}
/* Called with chr_write_lock held. */
static void pty_chr_rearm_timer(Chardev *chr, int ms)
{
PtyChardev *s = PTY_CHARDEV(chr);
......@@ -94,8 +78,7 @@ static void pty_chr_rearm_timer(Chardev *chr, int ms)
g_free(name);
}
/* Called with chr_write_lock held. */
static void pty_chr_update_read_handler_locked(Chardev *chr)
static void pty_chr_update_read_handler(Chardev *chr)
{
PtyChardev *s = PTY_CHARDEV(chr);
GPollFD pfd;
......@@ -117,14 +100,6 @@ static void pty_chr_update_read_handler_locked(Chardev *chr)
}
}
static void pty_chr_update_read_handler(Chardev *chr)
{
qemu_mutex_lock(&chr->chr_write_lock);
pty_chr_update_read_handler_locked(chr);
qemu_mutex_unlock(&chr->chr_write_lock);
}
/* Called with chr_write_lock held. */
static int char_pty_chr_write(Chardev *chr, const uint8_t *buf, int len)
{
PtyChardev *s = PTY_CHARDEV(chr);
......@@ -179,23 +154,11 @@ static gboolean pty_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
return TRUE;
}
static gboolean qemu_chr_be_generic_open_func(gpointer opaque)
{
Chardev *chr = CHARDEV(opaque);
PtyChardev *s = PTY_CHARDEV(opaque);
s->open_source = NULL;
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
return FALSE;
}
/* Called with chr_write_lock held. */
static void pty_chr_state(Chardev *chr, int connected)
{
PtyChardev *s = PTY_CHARDEV(chr);
if (!connected) {
pty_chr_open_src_cancel(s);
remove_fd_in_watch(chr);
s->connected = 0;
/* (re-)connect poll interval for idle guests: once per second.
......@@ -205,13 +168,8 @@ static void pty_chr_state(Chardev *chr, int connected)
} else {
pty_chr_timer_cancel(s);
if (!s->connected) {
g_assert(s->open_source == NULL);
s->open_source = g_idle_source_new();
s->connected = 1;
g_source_set_callback(s->open_source,
qemu_chr_be_generic_open_func,
chr, NULL);
g_source_attach(s->open_source, chr->gcontext);
qemu_chr_be_event(chr, CHR_EVENT_OPENED);
}
if (!chr->gsource) {
chr->gsource = io_add_watch_poll(chr, s->ioc,
......@@ -227,11 +185,9 @@ static void char_pty_finalize(Object *obj)
Chardev *chr = CHARDEV(obj);
PtyChardev *s = PTY_CHARDEV(obj);
qemu_mutex_lock(&chr->chr_write_lock);
pty_chr_state(chr, 0);
object_unref(OBJECT(s->ioc));
pty_chr_timer_cancel(s);
qemu_mutex_unlock(&chr->chr_write_lock);
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment