]> git.proxmox.com Git - spiceterm.git/commitdiff
protect command ring with mutex
authorDietmar Maurer <dietmar@proxmox.com>
Wed, 21 Aug 2013 10:58:20 +0000 (12:58 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 21 Aug 2013 10:58:20 +0000 (12:58 +0200)
Makefile
spiceterm.c
test_display_base.c
test_display_base.h

index 8d8fb41a8ecde9db386e5bfdb51c5533f097621c..2a986d4a6b6806316eca3bcc130a4bcb1b4177ae 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,10 +7,10 @@ SOURCES=test_display_base.c basic_event_loop.c
 all: ${PROGRAMS}
 
 test_display_no_ssl: ${SOURCES} ${HEADERS} test_display_no_ssl.c 
-       gcc ${SOURCES} test_display_no_ssl.c -o $@ $(shell pkg-config --cflags --libs spice-protocol,spice-server)
+       gcc ${SOURCES} test_display_no_ssl.c -o $@ $(shell pkg-config --cflags --libs  gthread-2.0,spice-protocol,spice-server)
 
 spiceterm: ${SOURCES} ${HEADERS} spiceterm.c 
-       gcc ${SOURCES} spiceterm.c -o $@ -lutil $(shell pkg-config --cflags gdk-3.0) $(shell pkg-config --cflags --libs spice-protocol,spice-server)
+       gcc ${SOURCES} spiceterm.c -o $@ -lutil $(shell pkg-config --cflags gdk-3.0) $(shell pkg-config --cflags --libs gthread-2.0,spice-protocol,spice-server)
 
 .PHONY: test1
 test1: test_display_no_ssl
index b89c7a7801de893aaf85beee410793722b9adf56..f45bccdd4e0bc195b471c87f0267102369a557ac 100644 (file)
@@ -40,6 +40,7 @@
 #include "spiceterm.h"
 #include "glyphs.h"
 
+#include <glib.h>
 #include <spice.h>
 #include <spice/enums.h>
 #include <spice/macros.h>
@@ -1760,6 +1761,8 @@ main (int argc, char** argv)
   time_t elapsed, cur_time;
   struct winsize dimensions;
 
+  g_thread_init(NULL);
+
   for (i = 1; i < argc; i++) {
     if (!strcmp (argv[i], "-c")) {
       command = argv[i+1];
index 9c0faeb338f9015d5cf9a9ae86364f2508b9b7f5..128149ac58213fc45de79053c80bb9226e91e6b6 100644 (file)
@@ -278,40 +278,46 @@ static void get_init_info(QXLInstance *qin, QXLDevInitInfo *info)
 // which cannot be done from red_worker context (not via dispatcher,
 // since you get a deadlock, and it isn't designed to be done
 // any other way, so no point testing that).
-int commands_end = 0;
-int commands_start = 0;
-struct QXLCommandExt* commands[1024];
 
-#define COMMANDS_SIZE COUNT(commands)
 
-static void push_command(QXLCommandExt *ext)
+static void push_command(Test *test, QXLCommandExt *ext)
 {
-    g_assert(commands_end - commands_start < COMMANDS_SIZE);
-    commands[commands_end % COMMANDS_SIZE] = ext;
-    commands_end++;
-}
+    g_mutex_lock(test->command_mutex);
 
-static struct QXLCommandExt *get_simple_command(void)
-{
-    struct QXLCommandExt *ret = commands[commands_start % COMMANDS_SIZE];
-    g_assert(commands_start < commands_end);
-    commands_start++;
-    return ret;
-}
+    while (test->commands_end - test->commands_start >= COMMANDS_SIZE) {
+        g_cond_wait(test->command_cond, test->command_mutex);
+    }
+    g_assert(test->commands_end - test->commands_start < COMMANDS_SIZE);
+    test->commands[test->commands_end % COMMANDS_SIZE] = ext;
+    test->commands_end++;
+    g_mutex_unlock(test->command_mutex);
 
-static int get_num_commands(void)
-{
-    return commands_end - commands_start;
+    test->qxl_worker->wakeup(test->qxl_worker);
 }
 
 // called from spice_server thread (i.e. red_worker thread)
 static int get_command(QXLInstance *qin, struct QXLCommandExt *ext)
 {
-    if (get_num_commands() == 0) {
-        return FALSE;
+    Test *test = SPICE_CONTAINEROF(qin, Test, qxl_instance);
+    int res = FALSE;
+
+    g_mutex_lock(test->command_mutex);
+    
+    if ((test->commands_end - test->commands_start) == 0) {
+        res = FALSE;
+        goto ret;
     }
-    *ext = *get_simple_command();
-    return TRUE;
+
+    *ext = *test->commands[test->commands_start % COMMANDS_SIZE];
+    g_assert(test->commands_start < test->commands_end);
+    test->commands_start++;
+    g_cond_signal(test->command_cond);
+
+    res = TRUE;
+
+ret:
+    g_mutex_unlock(test->command_mutex);
+    return res;
 }
 
 static int req_cmd_notification(QXLInstance *qin)
@@ -593,9 +599,7 @@ void test_draw_update_char(Test *test, int x, int y, int c, TextAttributes attri
 
     SimpleSpiceUpdate *update;
     update = test_draw_char(test, x, y, c, fg, bg);
-    push_command(&update->ext);
-
-    test->qxl_worker->wakeup(test->qxl_worker);
+    push_command(test, &update->ext);
 }
 
 static uint8_t kbd_get_leds(SpiceKbdInstance *sin)
@@ -623,6 +627,9 @@ Test *test_new(SpiceCoreInterface *core)
     Test *test = g_new0(Test, 1);
     SpiceServer* server = spice_server_new();
 
+    test->command_cond = g_cond_new();
+    test->command_mutex = g_mutex_new();
+
     test->on_client_connected = client_connected,
     test->on_client_disconnected = client_disconnected,
 
index 29b3319aebeb8f1c5d5ab74c6c14d03b731c9cc8..6b3c4ca409385d929ce11850bf625facede09c75 100644 (file)
@@ -86,6 +86,8 @@ struct Command {
     };
 };
 
+#define COMMANDS_SIZE 1024
+
 #define MAX_HEIGHT 2048
 #define MAX_WIDTH 2048
 
@@ -119,6 +121,13 @@ struct Test {
 
     int target_surface;
 
+    GCond* command_cond;
+    GMutex* command_mutex;
+
+    int commands_end;
+    int commands_start;
+    struct QXLCommandExt* commands[COMMANDS_SIZE];
+
     // callbacks
     void (*on_client_connected)(Test *test);
     void (*on_client_disconnected)(Test *test);