summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2010-09-13 17:04:46 +0200
committerAlexander Larsson <alexl@redhat.com>2010-09-20 10:25:16 +0200
commit08a4554b7ad1083393e2f136c45fdc5e51c0a62c (patch)
treeea07929a7eb849a219c7ac9416854822d2f96596
parent404251dd0f5001c68f2c0b3d7b84530f3e1b5a40 (diff)
Protect surface id allocation with semaphore
-rw-r--r--display/qxldd.h1
-rw-r--r--display/res.c14
-rw-r--r--display/surface.h19
3 files changed, 27 insertions, 7 deletions
diff --git a/display/qxldd.h b/display/qxldd.h
index 206b994..1a9bfe6 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -185,6 +185,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 a31832d..8b276bb 100644
--- a/display/res.c
+++ b/display/res.c
@@ -398,6 +398,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);
}
}
@@ -431,9 +435,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 {