[Change] Attempt to make ldata and pack thread safe.

This commit is contained in:
Allanis 2014-11-15 19:46:33 +00:00
parent 2fe4e218d3
commit 01ad8a2f48
3 changed files with 65 additions and 12 deletions

View File

@ -8,7 +8,7 @@
<price>500000</price>
<fabricator>Nexus</fabricator>
<tech>9999</tech>
<description>!Used for testing!</description>
<description>Used for testing!</description>
<movement>
<thrust>320</thrust>
<turn>135</turn>
@ -30,11 +30,10 @@
<cap_cargo>600000</cap_cargo>
</characteristics>
<outfits>
<outfit quantity="1">Lancelot Fighter Bay</outfit>
<outfit quantity="20">Lancelot Fighter</outfit>
<outfit quantity="5">Lancelot Fighter Bay</outfit>
<outfit quantity="10">Lancelot Fighter</outfit>
<outfit quantity="4">Ripper MK2</outfit>
<outfit quantity="1">Banshee Launcher</outfit>
<outfit quantity="50">Banshee Rocket</outfit>
<outfit quantity="1">Headhunter Launcher</outfit>
<outfit quantity="50">Headhunter</outfit>
</outfits>

View File

@ -7,6 +7,8 @@
* filesystem instead of always looking for a packfile.
*/
#include "SDL.h"
#include "lephisto.h"
#include "log.h"
#include "md5.h"
@ -32,11 +34,16 @@ static char* ldata_packName = NULL; /**< Name of the ldata module. */
static const char** ldata_fileList = NULL; /**< List of the files in the packfile. */
static uint32_t ldata_fileNList = 0; /**< Number of files in ldata_fileList. */
/* Lock. */
static SDL_mutex* ldata_lock = NULL;
static char** filterList(const char** list, int nlist,
const char* path, uint32_t* nfiles);
/**
* @brief Check to see if path is a ldata file.
* @brief Check to see if path is an ldata file.
*
* Should be called before ldata_open.
* @param path Path to check to see if it's an ldata file.
* @return 1 if it is an ldata file, otherwise 0.
*/
@ -46,6 +53,8 @@ int ldata_check(char* path) {
/**
* @brief Set the current ldata path to use.
*
* Should be called before ldata_open
* @param path Path to set.
* @return 0 on success.
*/
@ -117,6 +126,12 @@ static int ldata_openPackfile(void) {
* @return 0 on success.
*/
int ldata_open(void) {
/* Create the lock. */
ldata_lock = SDL_CreateMutex();
if(ldata_lock == NULL) {
WARN("Unable to create ldata lock.");
return -1;
}
return 0;
}
@ -124,6 +139,8 @@ int ldata_open(void) {
* @brief Close and clean up the ldata file.
*/
void ldata_close(void) {
/* Lock the mutex. */
SDL_mutexP(ldata_lock);
/* Destroy the name. */
if(ldata_packName != NULL) {
free(ldata_packName);
@ -142,10 +159,19 @@ void ldata_close(void) {
pack_closeCache(ldata_cache);
ldata_cache = NULL;
}
/* Unlock the mutex. */
SDL_mutexV(ldata_lock);
/* Destroy the mutex. */
SDL_DestroyMutex(ldata_lock);
ldata_lock = NULL;
}
/**
* @brief Get the ldata's name.
*
* Thread safe (uses ldata_read).
* @return The ldata's name.
*/
const char* ldata_name(void) {
@ -191,6 +217,9 @@ const char* ldata_name(void) {
/**
* @brief Read a file from the ldata.
*
* Thread Safe.
*
* @param filename Name of the file to read.
* @param[out] filesize Stores the size of the file.
* @return The file data or NULL on error.
@ -200,6 +229,9 @@ void* ldata_read(const char* filename, uint32_t* filesize) {
int nbuf;
/* See if needs to load the packfile. */
if(ldata_cache == NULL) {
/* Lock the mutex. */
SDL_mutexP(ldata_lock);
/* Try to read the file as locally. */
buf = lfile_readFile(&nbuf, filename);
if(buf != NULL) {
@ -209,6 +241,9 @@ void* ldata_read(const char* filename, uint32_t* filesize) {
/* Load the packfile. */
ldata_openPackfile();
/* Unlock the mutex. */
SDL_mutexV(ldata_lock);
}
/* Get data from packfile. */
@ -217,6 +252,9 @@ void* ldata_read(const char* filename, uint32_t* filesize) {
/**
* @brief Filter a file list to match path.
*
* Uses read only data, should be thread safe.
*
* @param list List to filter.
* @param nlist Members in list.
* @param path Path to filter.
@ -258,6 +296,9 @@ static char** filterList(const char** list, int nlist,
/**
* @brief Get the list of files in the ldata.
*
* Thread safe.
*
* @param path List files in path.
* @param nfiles Number of files found.
* @return List of files found.
@ -273,6 +314,9 @@ char** ldata_list(const char* path, uint32_t* nfiles) {
/* See if we can load from local directory. */
if(ldata_cache == NULL) {
/* Lock the mutex. */
SDL_mutexP(ldata_lock);
files = lfile_readDir(&n, path);
/* Found locally. */
@ -283,10 +327,20 @@ char** ldata_list(const char* path, uint32_t* nfiles) {
/* Open packfile. */
ldata_openPackfile();
/* Unlock the mutex. */
SDL_mutexV(ldata_lock);
}
/* Lock the mutex. */
SDL_mutexP(ldata_lock);
/* Load list. */
ldata_fileList = pack_listfilesCached(ldata_cache, &ldata_fileNList);
/* Unlock the mutex. */
SDL_mutexV(ldata_lock);
return filterList(ldata_fileList, ldata_fileNList, path, nfiles);
}

View File

@ -44,6 +44,7 @@ struct Packfile_s {
#if HAS_POSIX
int fd; /**< File descriptor. */
#else
char* name; /**< Hack to emulate dup2 by calling fopen again. */
FILE* fp; /**< For non-posix. */
#endif /* HAS_POSIX */
uint32_t pos; /**< Cursor position. */
@ -121,6 +122,7 @@ Packcache_t* pack_openCache(const char* packfile) {
cache->fd = open(packfile, O_RDONLY);
if(cache->fd == -1) {
#else
cache->name = strdup(packfile);
cache->fp = fopen(packfile, "rb");
if(cache->fp == NULL) {
#endif /* HAS_POSIX */
@ -165,6 +167,7 @@ void pack_closeCache(Packcache_t* cache) {
#if HAS_POSIX
close(cache->fd);
#else
free(cache->name);
fclose(cache->fp);
#endif /* HAS_POSIX */
@ -196,7 +199,7 @@ Packfile_t* pack_openFromCache(Packcache_t* cache, const char* filename) {
#if HAS_POSIX
file->fd = dup(cache->fd);
#else
file->fp = cache->fp;
file->fp = fopen(file->name, "rb");
#endif
/* Copy information. */
@ -780,9 +783,6 @@ int pack_close(Packfile_t* file) {
#if HAS_POSIX
i = close(file->fd);
#else
if(file->flags & PACKFILE_FROMCACHE)
i = 0;
else
i = fclose(file->fp);
#endif /* HAS_POSIX */