changeset 65:dcde6d9cea7a src

ensure serialized access to the cache to avoid concurrent access on the usage counters
author mroi
date Sun, 21 Jul 2002 10:16:45 +0000
parents 2759605b41f6
children 2bd4a78eefce
files read_cache.c
diffstat 1 files changed, 19 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/read_cache.c	Wed Jul 17 15:04:28 2002 +0000
+++ b/read_cache.c	Sun Jul 21 10:16:45 2002 +0000
@@ -82,6 +82,7 @@
   read_cache_chunk_t  chunk[READ_CACHE_CHUNKS];
   int                 current;
   int                 freeing;  /* is set to one when we are about to dispose the cache */
+  pthread_mutex_t     lock;
 
   /* Bit of strange cross-linking going on here :) -- Gotta love C :) */
   dvdnav_t           *dvd_self;
@@ -342,6 +343,7 @@
     self->current = 0;
     self->freeing = 0;
     self->dvd_self = dvd_self;
+    pthread_mutex_init(&self->lock, NULL);
     dvdnav_read_cache_clear(self);
     for (i = 0; i < READ_CACHE_CHUNKS; i++) {
       self->chunk[i].cache_buffer = NULL;
@@ -356,18 +358,21 @@
   dvdnav_t *tmp;
   int i;
   
+  pthread_mutex_lock(&self->lock);
   self->freeing = 1;
   for (i = 0; i < READ_CACHE_CHUNKS; i++)
     if (self->chunk[i].cache_buffer && self->chunk[i].usage_count == 0) {
       free(self->chunk[i].cache_buffer);
       self->chunk[i].cache_buffer = NULL;
     }
+  pthread_mutex_unlock(&self->lock);
     
   for (i = 0; i < READ_CACHE_CHUNKS; i++)
     if (self->chunk[i].cache_buffer) return;
 
   /* all buffers returned, free everything */
   tmp = self->dvd_self;
+  pthread_mutex_destroy(&self->lock);
   free(self);
   free(tmp);
 }
@@ -379,9 +384,10 @@
   if(!self)
    return;
    
-  for (i = 0; i < READ_CACHE_CHUNKS; i++) {
+  pthread_mutex_lock(&self->lock);
+  for (i = 0; i < READ_CACHE_CHUNKS; i++)
     self->chunk[i].cache_valid = 0;
-  }
+  pthread_mutex_unlock(&self->lock);
 }
 
 #ifdef DVDNAV_PROFILE
@@ -409,6 +415,8 @@
   if(!self->dvd_self->use_read_ahead)
     return;
 
+  pthread_mutex_lock(&self->lock);
+
   /* find a free cache chunk that best fits the required size */
   use = -1;
   for (i = 0; i < READ_CACHE_CHUNKS; i++)
@@ -467,6 +475,8 @@
     self->chunk[use].cache_valid = 1;
   } else
     dprintf("pre_caching was impossible, no cache chunk available\n");
+  
+  pthread_mutex_unlock(&self->lock);
 }
 
 int dvdnav_read_cache_block(read_cache_t *self, int sector, size_t block_count, uint8_t **buf) {
@@ -475,6 +485,8 @@
   if(!self)
     return 0;
   
+  pthread_mutex_lock(&self->lock);
+  
   use = -1;
   if(self->dvd_self->use_read_ahead) {
     /* first check, if sector is in current chunk */
@@ -493,10 +505,12 @@
     self->chunk[use].usage_count++;
     *buf = &self->chunk[use].cache_buffer[(sector - self->chunk[use].cache_start_sector) *
       DVD_VIDEO_LB_LEN * block_count];
+    pthread_mutex_unlock(&self->lock);
     return DVD_VIDEO_LB_LEN * block_count;
   } else {
     if (self->dvd_self->use_read_ahead)
       dprintf("cache miss on sector %d\n", sector);
+    pthread_mutex_unlock(&self->lock);
     return DVDReadBlocks(self->dvd_self->file, sector, block_count, *buf);
   }
 }
@@ -512,11 +526,13 @@
   if (!cache)
     return DVDNAV_STATUS_ERR;
     
+  pthread_mutex_lock(&cache->lock);
   for (i = 0; i < READ_CACHE_CHUNKS; i++)
     if (cache->chunk[i].cache_buffer && buf >= cache->chunk[i].cache_buffer &&
         buf < cache->chunk[i].cache_buffer + cache->chunk[i].cache_malloc_size * DVD_VIDEO_LB_LEN)
       cache->chunk[i].usage_count--;
-      
+  pthread_mutex_unlock(&cache->lock);
+
   if (cache->freeing)
     /* when we want to dispose the cache, try freeing it now */
     dvdnav_read_cache_free(cache);