[Spice-commits] 2 commits - server/red_channel.c server/red_channel.h server/red_worker.c

Yonit Halperin yhalperi at kemper.freedesktop.org
Mon May 28 03:20:06 PDT 2012


 server/red_channel.c |   19 -------------------
 server/red_channel.h |    9 ---------
 server/red_worker.c  |   16 ++++++----------
 3 files changed, 6 insertions(+), 38 deletions(-)

New commits:
commit d691602784b3592fdd4e2e54cddc29f53fafdfef
Author: Yonit Halperin <yhalperi at redhat.com>
Date:   Thu May 24 11:05:58 2012 +0300

    server/red_worker: fix red_wait_pipe_item_sent
    
    Resolves: rhbz#824384
    
    red_wait_pipe_item_sent mistakingly returned without waiting for sending the given pipe item
    when the channel wasn't blocked. As a result, we failed when we had to
    destroy a surface (e.g., QXL_IO_DESTROY_ALL_SURFACES) and to release all
    the drawables that are depended on it (by removing them or waiting they will be sent).
    In addition, red_wait_pipe_item_sent increased and decreased the reference to the pipe item
    using channel_cbs->hold_item, and channel_cbs->release_item. However,
    these calls can be called only by red_channel, otherwise
    display_channel_client_release_item_before_push is called twice and
    leads to a double call to ring_remove(&dpi->base).
    Instead ref/put_drawable_pipe_item should be called.

diff --git a/server/red_worker.c b/server/red_worker.c
index 2709486..c712180 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -1998,6 +1998,7 @@ static void red_clear_surface_drawables_from_pipe(DisplayChannelClient *dcc, int
         }
 
         if (depend_found) {
+            spice_debug("surface %d dependent item found %p, %p", surface_id, drawable, item);
             if (force) {
                 break;
             } else {
@@ -10334,16 +10335,13 @@ static void red_wait_outgoing_items(RedChannel *channel)
 /* TODO: more evil sync stuff. anything with the word wait in it's name. */
 static void red_wait_pipe_item_sent(RedChannelClient *rcc, PipeItem *item)
 {
-    RedChannel *channel = rcc->channel;
+    DrawablePipeItem *dpi;
     uint64_t end_time;
     int item_in_pipe;
 
-    if (!red_channel_client_blocked(rcc)) {
-        return;
-    }
-
     spice_printerr("");
-    channel->channel_cbs.hold_item(rcc, item);
+    dpi = SPICE_CONTAINEROF(item, DrawablePipeItem, dpi_pipe_item);
+    ref_drawable_pipe_item(dpi);
 
     end_time = red_now() + CHANNEL_PUSH_TIMEOUT;
 
@@ -10366,7 +10364,7 @@ static void red_wait_pipe_item_sent(RedChannelClient *rcc, PipeItem *item)
     } else {
         red_wait_outgoing_item(rcc);
     }
-    channel->channel_cbs.release_item(rcc, item, FALSE);
+    put_drawable_pipe_item(dpi);
 }
 
 static void surface_dirty_region_to_rects(RedSurface *surface,
commit c59b2884a2f7fc953fdb263085830b65e8bdcaef
Author: Yonit Halperin <yhalperi at redhat.com>
Date:   Thu May 24 11:00:33 2012 +0300

    server/red_channel: remove red_channel_client_item_being_sent
    
    The above routine was risky, since red_channel_client_init_send_data
    can also be called with item==NULL. Thus, not all pipe items can be tracked.
    The one call that was made for this routine was not necessary.

diff --git a/server/red_channel.c b/server/red_channel.c
index a7ef934..83a9f37 100644
--- a/server/red_channel.c
+++ b/server/red_channel.c
@@ -1374,25 +1374,6 @@ int red_channel_get_first_socket(RedChannel *channel)
                              RedChannelClient, channel_link)->stream->socket;
 }
 
-int red_channel_client_item_being_sent(RedChannelClient *rcc, PipeItem *item)
-{
-    return rcc->send_data.item == item;
-}
-
-int red_channel_item_being_sent(RedChannel *channel, PipeItem *item)
-{
-    RingItem *link;
-    RedChannelClient *rcc;
-
-    RING_FOREACH(link, &channel->clients) {
-        rcc = SPICE_CONTAINEROF(link, RedChannelClient, channel_link);
-        if (rcc->send_data.item == item) {
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
 int red_channel_no_item_being_sent(RedChannel *channel)
 {
     RingItem *link;
diff --git a/server/red_channel.h b/server/red_channel.h
index 5418210..765b74e 100644
--- a/server/red_channel.h
+++ b/server/red_channel.h
@@ -432,15 +432,6 @@ int red_channel_client_blocked(RedChannelClient *rcc);
 /* helper for channels that have complex logic that can possibly ready a send */
 int red_channel_client_send_message_pending(RedChannelClient *rcc);
 
-/* returns TRUE if item is being sent by one of the channel clients. This will
- * be true if someone called init_send_data but send has not completed (or perhaps
- * hasn't even begun, i.e. no one called begin_send_).
- * However, note that red_channel_client_init_send_data can also be called with
- * item==NULL, thus not all pipe items can be tracked.
- */
-int red_channel_item_being_sent(RedChannel *channel, PipeItem *item);
-int red_channel_client_item_being_sent(RedChannelClient *rcc, PipeItem *item);
-
 int red_channel_no_item_being_sent(RedChannel *channel);
 int red_channel_client_no_item_being_sent(RedChannelClient *rcc);
 
diff --git a/server/red_worker.c b/server/red_worker.c
index 9e5624b..2709486 100644
--- a/server/red_worker.c
+++ b/server/red_worker.c
@@ -10364,9 +10364,7 @@ static void red_wait_pipe_item_sent(RedChannelClient *rcc, PipeItem *item)
         spice_printerr("timeout");
         red_channel_client_disconnect(rcc);
     } else {
-        if (red_channel_client_item_being_sent(rcc, item)) {
-            red_wait_outgoing_item(rcc);
-        }
+        red_wait_outgoing_item(rcc);
     }
     channel->channel_cbs.release_item(rcc, item, FALSE);
 }


More information about the Spice-commits mailing list