summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2010-09-14 16:31:53 +0200
committerAlexander Larsson <alexl@redhat.com>2010-09-20 10:25:17 +0200
commit1f2b0bc13355bb18454eebf45ba2bdb199ec4b13 (patch)
tree62543493ceae2c0289aeee7d580e6295ece1e17b
parent6355188f854e9024dd0edfb4f4f926d85482ec8b (diff)
Protect cursor cache against concurrent access
-rw-r--r--display/qxldd.h1
-rw-r--r--display/res.c18
2 files changed, 18 insertions, 1 deletions
diff --git a/display/qxldd.h b/display/qxldd.h
index 51ace78..8b07f1d 100644
--- a/display/qxldd.h
+++ b/display/qxldd.h
@@ -188,6 +188,7 @@ typedef struct DevRes {
HSEMAPHORE cursor_sem; /* Protects cursor_ring */
HSEMAPHORE surface_sem; /* Protects surfaces allocation */
HSEMAPHORE image_cache_sem; /* Protects image cache */
+ HSEMAPHORE cursor_cache_sem; /* Protects cursor cache */
CacheImage cache_image_pool[IMAGE_POOL_SIZE];
Ring cache_image_lru;
diff --git a/display/res.c b/display/res.c
index 4488340..93ab05b 100644
--- a/display/res.c
+++ b/display/res.c
@@ -411,6 +411,10 @@ void CleanGlobalRes()
EngDeleteSemaphore(res->image_cache_sem);
res->image_cache_sem = NULL;
}
+ if (res->cursor_cache_sem) {
+ EngDeleteSemaphore(res->cursor_cache_sem);
+ res->cursor_cache_sem = NULL;
+ }
EngFreeMem(res);
}
}
@@ -480,6 +484,10 @@ static void InitRes(PDev *pdev)
if (!pdev->Res->image_cache_sem) {
PANIC(pdev, "Res cache sem creation failed\n");
}
+ pdev->Res->cursor_cache_sem = EngCreateSemaphore();
+ if (!pdev->Res->cursor_cache_sem) {
+ PANIC(pdev, "Res cache sem creation failed\n");
+ }
InitMspace(pdev->Res, MSPACE_TYPE_DEVRAM, pdev->io_pages_virt, pdev->num_io_pages * PAGE_SIZE);
InitMspace(pdev->Res, MSPACE_TYPE_VRAM, pdev->fb, pdev->fb_size);
@@ -2769,6 +2777,7 @@ typedef struct InternalCursor {
#define CURSOR_HASH_VAL(hsurf) (HSURF_HASH_VAL(hsurf) & CURSOR_HASH_NASKE)
+/* Called with cursor_cache_sem held */
static void CursorCacheRemove(PDev *pdev, InternalCursor *cursor)
{
InternalCursor **internal;
@@ -2785,7 +2794,7 @@ static void CursorCacheRemove(PDev *pdev, InternalCursor *cursor)
RingRemove(pdev, &cursor->lru_link);
RELEASE_RES(pdev, (Resource *)((UINT8 *)cursor - sizeof(Resource)));
pdev->Res->num_cursors--;
- return;
+ break;
}
DEBUG_PRINT((pdev, 0, "%s: unexpected\n", __FUNCTION__));
}
@@ -2804,6 +2813,7 @@ static void CursorCacheAdd(PDev *pdev, InternalCursor *cursor)
return;
}
+ EngAcquireSemaphore(pdev->Res->cursor_cache_sem);
if (pdev->Res->num_cursors == CURSOR_CACHE_SIZE) {
ASSERT(pdev, RingGetTail(pdev, &pdev->Res->cursors_lru));
CursorCacheRemove(pdev, CONTAINEROF(RingGetTail(pdev, &pdev->Res->cursors_lru),
@@ -2817,6 +2827,7 @@ static void CursorCacheAdd(PDev *pdev, InternalCursor *cursor)
RingAdd(pdev, &pdev->Res->cursors_lru, &cursor->lru_link);
GET_RES((Resource *)((UINT8 *)cursor - sizeof(Resource)));
pdev->Res->num_cursors++;
+ EngReleaseSemaphore(pdev->Res->cursor_cache_sem);
}
static InternalCursor *CursorCacheGet(PDev *pdev, HSURF hsurf, UINT32 unique)
@@ -2828,6 +2839,7 @@ static InternalCursor *CursorCacheGet(PDev *pdev, HSURF hsurf, UINT32 unique)
return NULL;
}
+ EngAcquireSemaphore(pdev->Res->cursor_cache_sem);
internal = &pdev->Res->cursor_cache[CURSOR_HASH_VAL(hsurf)];
while (*internal) {
InternalCursor *now = *internal;
@@ -2835,6 +2847,7 @@ static InternalCursor *CursorCacheGet(PDev *pdev, HSURF hsurf, UINT32 unique)
if (now->unique == unique) {
RingRemove(pdev, &now->lru_link);
RingAdd(pdev, &pdev->Res->cursors_lru, &now->lru_link);
+ EngReleaseSemaphore(pdev->Res->cursor_cache_sem);
return now;
}
CursorCacheRemove(pdev, now);
@@ -2842,6 +2855,7 @@ static InternalCursor *CursorCacheGet(PDev *pdev, HSURF hsurf, UINT32 unique)
}
internal = &now->next;
}
+ EngReleaseSemaphore(pdev->Res->cursor_cache_sem);
return NULL;
}
@@ -2950,7 +2964,9 @@ static BOOL GetCursorCommon(PDev *pdev, QXLCursorCmd *cmd, LONG hot_x, LONG hot_
cursor = info->cursor = &internal->cursor;
cursor->header.type = type;
+ EngAcquireSemaphore(pdev->Res->cursor_cache_sem);
cursor->header.unique = unique ? ++pdev->Res->last_cursor_id : 0;
+ EngReleaseSemaphore(pdev->Res->cursor_cache_sem);
cursor->header.width = (UINT16)local_surf->sizlBitmap.cx;
cursor->header.height = (type == SPICE_CURSOR_TYPE_MONO) ? (UINT16)local_surf->sizlBitmap.cy >> 1 :
(UINT16)local_surf->sizlBitmap.cy;