diff options
author | Alexander Larsson <alexl@redhat.com> | 2010-09-14 16:31:53 +0200 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2010-09-20 10:25:17 +0200 |
commit | 1f2b0bc13355bb18454eebf45ba2bdb199ec4b13 (patch) | |
tree | 62543493ceae2c0289aeee7d580e6295ece1e17b | |
parent | 6355188f854e9024dd0edfb4f4f926d85482ec8b (diff) |
Protect cursor cache against concurrent access
-rw-r--r-- | display/qxldd.h | 1 | ||||
-rw-r--r-- | display/res.c | 18 |
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; |