[Spice-devel] [PATCH 05/17] Protect surface id allocation with semaphore

alexl at redhat.com alexl at redhat.com
Tue Sep 14 12:08:55 PDT 2010


From: Alexander Larsson <alexl at redhat.com>

---
 display/qxldd.h   |    1 +
 display/res.c     |   14 +++++++++++---
 display/surface.h |   19 +++++++++++++++----
 3 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/display/qxldd.h b/display/qxldd.h
index ad373ae..8c5516d 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -181,6 +181,7 @@ typedef struct DevRes {
 
     HSEMAPHORE print_sem;
     HSEMAPHORE cmd_sem;
+    HSEMAPHORE surface_sem; /* Protects surfaces allocation */
 
     CacheImage cache_image_pool[IMAGE_POOL_SIZE];
     Ring cache_image_lru;
diff --git a/display/res.c b/display/res.c
index c1d0cb5..faf3b9c 100644
--- a/display/res.c
+++ b/display/res.c
@@ -394,6 +394,10 @@ void CleanGlobalRes()
                     EngDeleteSemaphore(res->print_sem);
                     res->print_sem = NULL;
                 }
+                if (res->surface_sem) {
+                    EngDeleteSemaphore(res->surface_sem);
+                    res->surface_sem = NULL;
+                }
                 EngFreeMem(res);
             }
         }
@@ -427,9 +431,13 @@ static void InitRes(PDev *pdev)
 {
     UINT32 i;
 
-   pdev->Res->surfaces_info = (SurfaceInfo *)EngAllocMem(FL_ZERO_MEMORY,
-							 sizeof(SurfaceInfo) * pdev->n_surfaces, 
-							 ALLOC_TAG);
+    pdev->Res->surface_sem = EngCreateSemaphore();
+    if (!pdev->Res->surface_sem) {
+        PANIC(pdev, "Res surface sem creation failed\n");
+    }
+    pdev->Res->surfaces_info = (SurfaceInfo *)EngAllocMem(FL_ZERO_MEMORY,
+							  sizeof(SurfaceInfo) * pdev->n_surfaces, 
+							  ALLOC_TAG);
     if (!pdev->Res->surfaces_info) {
         PANIC(pdev, "Res surfaces_info allocation failed\n");
     }
diff --git a/display/surface.h b/display/surface.h
index a25cbd9..028f97e 100644
--- a/display/surface.h
+++ b/display/surface.h
@@ -37,26 +37,37 @@ static _inline void FreeSurface(PDev *pdev, UINT32 surface_id)
     if (surface_id == 0) {
         return;
     }
+
+    EngAcquireSemaphore(pdev->Res->surface_sem);
+
     surface = &pdev->Res->surfaces_info[surface_id];
     surface->draw_area.base_mem = NULL; /* Mark as not used */
     surface->u.next_free = pdev->Res->free_surfaces;
     pdev->Res->free_surfaces = surface;
+
+    EngReleaseSemaphore(pdev->Res->surface_sem);
 }
 
 
 static UINT32 GetFreeSurface(PDev *pdev)
 {
-    UINT32 x;
+    UINT32 x, id;
     SurfaceInfo *surface;
 
+    EngAcquireSemaphore(pdev->Res->surface_sem);
+
     surface = pdev->Res->free_surfaces;
     if (surface == NULL) {
-        return 0;
+        id = 0;
+    } else {
+      pdev->Res->free_surfaces = surface->u.next_free;
+
+      id = surface - pdev->Res->surfaces_info;
     }
 
-    pdev->Res->free_surfaces = surface->u.next_free;
+    EngReleaseSemaphore(pdev->Res->surface_sem);
 
-    return surface - pdev->Res->surfaces_info;
+    return id;
 }
 
 enum {
-- 
1.7.2.2



More information about the Spice-devel mailing list