[Spice-devel] [PATCH v3 5/6] Do not use a mix of g_mail_loop and basic_loop in replay
Frediano Ziglio
fziglio at redhat.com
Wed Aug 19 00:43:42 PDT 2015
Utility was not working due to strange mixing of these two loops
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
server/tests/replay.c | 104 +++++++++++++++++++++++---------------------------
1 file changed, 47 insertions(+), 57 deletions(-)
diff --git a/server/tests/replay.c b/server/tests/replay.c
index 01590c0..b55f19a 100644
--- a/server/tests/replay.c
+++ b/server/tests/replay.c
@@ -12,6 +12,7 @@
#include <sys/wait.h>
#include <fcntl.h>
#include <glib.h>
+#include <glib-unix.h>
#include <spice/macros.h>
#include "red_replay_qxl.h"
@@ -26,12 +27,9 @@ static gboolean started = FALSE;
static QXLInstance display_sin = { 0, };
static gint slow = 0;
static pid_t client_pid;
-static GMainLoop *loop = NULL;
static GAsyncQueue *aqueue = NULL;
static long total_size;
-
-static GMutex mutex;
-static guint fill_source_id = 0;
+static int close_pipe = -1;
#define MEM_SLOT_GROUP_ID 0
@@ -83,48 +81,37 @@ static void get_init_info(QXLInstance *qin, QXLDevInitInfo *info)
info->n_surfaces = MAX_SURFACE_NUM;
}
-static gboolean fill_queue_idle(gpointer user_data)
-{
- gboolean keep = FALSE;
-
- while (g_async_queue_length(aqueue) < 50) {
- QXLCommandExt *cmd = spice_replay_next_cmd(replay, qxl_worker);
- if (!cmd) {
- g_async_queue_push(aqueue, GINT_TO_POINTER(-1));
- goto end;
- }
-
- if (slow)
- g_usleep(slow);
-
- g_async_queue_push(aqueue, cmd);
- }
-end:
- if (!keep) {
- g_mutex_lock(&mutex);
- fill_source_id = 0;
- g_mutex_unlock(&mutex);
- }
- spice_qxl_wakeup(&display_sin);
-
- return keep;
-}
-
-static void fill_queue(void)
+static gboolean fill_command(void)
{
- g_mutex_lock(&mutex);
+ QXLCommandExt *cmd = spice_replay_next_cmd(replay, qxl_worker);
- if (!started)
- goto end;
+ g_async_queue_push(aqueue, cmd ? cmd : GINT_TO_POINTER(-1));
- if (fill_source_id != 0)
- goto end;
+ return cmd ? TRUE : FALSE;
+}
- fill_source_id = g_idle_add(fill_queue_idle, NULL);
-end:
- g_mutex_unlock(&mutex);
+static void fill_queue_slow(void *opaque)
+{
+ if (slow) {
+ if (fill_command()) {
+ SpiceTimer *timer = core->timer_add(fill_queue_slow, NULL);
+ core->timer_start(timer, slow);
+ }
+ spice_qxl_wakeup(&display_sin);
+ } else {
+ gboolean got_some = FALSE;
+ while (g_async_queue_length(aqueue) < 50) {
+ if (!fill_command())
+ return;
+ got_some = TRUE;
+ }
+ SpiceTimer *timer = core->timer_add(fill_queue_slow, NULL);
+ core->timer_start(timer, 1);
+ if (got_some)
+ spice_qxl_wakeup(&display_sin);
+ }
}
@@ -133,15 +120,12 @@ static int get_command(QXLInstance *qin, QXLCommandExt *ext)
{
QXLCommandExt *cmd;
- if (g_async_queue_length(aqueue) == 0) {
- /* could use a gcondition ? */
- fill_queue();
+ cmd = g_async_queue_try_pop(aqueue);
+ if (!cmd)
return FALSE;
- }
- cmd = g_async_queue_try_pop(aqueue);
if (GPOINTER_TO_INT(cmd) == -1) {
- g_main_loop_quit(loop);
+ write(close_pipe, "bye", 3);
return FALSE;
}
@@ -155,8 +139,8 @@ static int req_cmd_notification(QXLInstance *qin)
if (!started)
return TRUE;
- g_printerr("id: %d, queue length: %d",
- fill_source_id, g_async_queue_length(aqueue));
+ g_printerr("queue length: %d",
+ g_async_queue_length(aqueue));
return TRUE;
}
@@ -257,6 +241,11 @@ static gboolean progress_timer(gpointer user_data)
return TRUE;
}
+static void close_pipe_read(int fd, int event, void *opaque)
+{
+ end_replay();
+}
+
int main(int argc, char **argv)
{
GError *error = NULL;
@@ -265,6 +254,7 @@ int main(int argc, char **argv)
gint port = 5000, compression = SPICE_IMAGE_COMPRESSION_AUTO_GLZ;
gboolean wait = FALSE;
FILE *fd;
+ gint pipe[2];
GOptionEntry entries[] = {
{ "client", 'c', 0, G_OPTION_ARG_STRING, &client, "Client", "CMD" },
@@ -311,6 +301,13 @@ int main(int argc, char **argv)
core = basic_event_loop_init();
core->channel_event = replay_channel_event;
+ if (!g_unix_open_pipe(pipe, FD_CLOEXEC, &error)) {
+ g_printerr("Error creating pipe: %s\n", error->message);
+ exit(1);
+ }
+ close_pipe = pipe[1];
+ core->watch_add(pipe[0], SPICE_WATCH_EVENT_READ, close_pipe_read, NULL);
+
server = spice_server_new();
spice_server_set_image_compression(server, compression);
spice_server_set_port(server, port);
@@ -329,18 +326,11 @@ int main(int argc, char **argv)
if (!wait) {
started = TRUE;
- fill_queue();
}
- loop = g_main_loop_new(NULL, FALSE);
- g_main_loop_run(loop);
-
- end_replay();
- g_async_queue_unref(aqueue);
+ fill_queue_slow(NULL);
- /* FIXME: there should be a way to join server threads before:
- * g_main_loop_unref(loop);
- */
+ basic_event_loop_mainloop();
return 0;
}
--
2.4.3
More information about the Spice-devel
mailing list