diff --git a/dat/ship.xml b/dat/ship.xml index d7f23c7..f8a03c8 100644 --- a/dat/ship.xml +++ b/dat/ship.xml @@ -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> diff --git a/src/ldata.c b/src/ldata.c index 58d6300..a20304c 100644 --- a/src/ldata.c +++ b/src/ldata.c @@ -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); } diff --git a/src/pack.c b/src/pack.c index ad2185c..b1a2129 100644 --- a/src/pack.c +++ b/src/pack.c @@ -44,8 +44,9 @@ struct Packfile_s { #if HAS_POSIX int fd; /**< File descriptor. */ #else - FILE* fp; /**< For non-posix. */ -#endif /* HAS_POSIX */ + char* name; /**< Hack to emulate dup2 by calling fopen again. */ + FILE* fp; /**< For non-posix. */ +#endif /* HAS_POSIX */ uint32_t pos; /**< Cursor position. */ uint32_t start; /**< File start. */ uint32_t end; /**< File end. */ @@ -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,10 +783,7 @@ 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); + i = fclose(file->fp); #endif /* HAS_POSIX */ /* Free memory. */