cedric's eet race patch

SVN revision: 33544
This commit is contained in:
Carsten Haitzler 2008-01-21 01:09:51 +00:00
parent 033737bdd9
commit b35e3bd260
4 changed files with 247 additions and 203 deletions

View File

@ -253,7 +253,7 @@ extern "C" {
* If the eet file handle is not valid NULL is returned and size_ret is
* filled with 0.
*/
EAPI void *eet_read_direct (Eet_File *ef, const char *name, int *size_ret);
EAPI const void *eet_read_direct(Eet_File *ef, const char *name, int *size_ret);
/**
* Write a specified entry to an eet file handle

View File

@ -906,7 +906,7 @@ EAPI void *
eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
{
void *data_dec;
void *data;
const void *data;
int size;
int required_free = 0;

View File

@ -733,7 +733,7 @@ eet_data_image_read(Eet_File *ef, const char *name,
unsigned int *d = NULL;
int free_data = 0;
data = eet_read_direct (ef, name, &size);
data = (void*) eet_read_direct (ef, name, &size);
if (!data)
{
data = eet_read(ef, name, &size);
@ -759,7 +759,7 @@ eet_data_image_header_read(Eet_File *ef, const char *name,
int d;
int free_data = 0;
data = eet_read_direct (ef, name, &size);
data = (void*) eet_read_direct (ef, name, &size);
if (!data)
{
data = eet_read(ef, name, &size);

View File

@ -26,7 +26,7 @@ struct _Eet_File
char *path;
FILE *fp;
Eet_File_Header *header;
unsigned char *data;
const unsigned char *data;
int magic;
int references;
@ -454,151 +454,22 @@ eet_clearcache(void)
}
}
EAPI Eet_File *
eet_open(const char *file, Eet_File_Mode mode)
static Eet_File*
eet_internal_read (Eet_File *ef)
{
Eet_File *ef;
struct stat file_stat;
#ifdef _WIN32
HANDLE h;
#endif
if (!file)
return NULL;
/* find the current file handle in cache*/
ef = NULL;
if (mode == EET_FILE_MODE_READ)
{
ef = eet_cache_find((char *)file, eet_writers, eet_writers_num);
if (ef)
{
eet_flush(ef);
ef->delete_me_now = 1;
eet_close(ef);
}
ef = eet_cache_find((char *)file, eet_readers, eet_readers_num);
}
else if ((mode == EET_FILE_MODE_WRITE) || (mode == EET_FILE_MODE_READ_WRITE))
{
ef = eet_cache_find((char *)file, eet_readers, eet_readers_num);
if (ef)
{
ef->delete_me_now = 1;
eet_close(ef);
}
ef = eet_cache_find((char *)file, eet_writers, eet_writers_num);
}
if (stat(file, &file_stat))
{
if (mode == EET_FILE_MODE_WRITE)
memset(&file_stat, 0, sizeof(file_stat));
else
return NULL;
}
else if ((mode == EET_FILE_MODE_READ) &&
(file_stat.st_size < (sizeof(int) * 3)))
{
return NULL;
}
/* We found one */
if (ef && (file_stat.st_mtime != ef->mtime))
{
ef->delete_me_now = 1;
eet_close(ef);
ef = NULL;
}
if (ef)
{
/* reference it up and return it */
ef->references++;
return ef;
}
/* Allocate struct for eet file and have it zero'd out */
ef = malloc(sizeof(Eet_File) + strlen(file) + 1);
if (!ef)
return NULL;
/* fill some of the members */
ef->path = ((char *)ef) + sizeof(Eet_File);
strcpy(ef->path, file);
ef->magic = EET_MAGIC_FILE;
ef->references = 1;
ef->mode = mode;
ef->header = NULL;
ef->mtime = file_stat.st_mtime;
ef->delete_me_now = 0;
ef->data = NULL;
ef->data_size = 0;
/* try open the file based on mode */
if ((ef->mode == EET_FILE_MODE_READ) || (ef->mode == EET_FILE_MODE_READ_WRITE))
ef->fp = fopen(ef->path, "rb");
else
{
if (eet_test_close(ef->mode != EET_FILE_MODE_WRITE, ef))
return NULL;
else
{
/* opening for write - delete old copy of file right away */
unlink(ef->path);
ef->fp = fopen(ef->path, "wb");
}
}
/* if we can't open - bail out */
if (eet_test_close(!ef->fp, ef))
return NULL;
#ifndef _WIN32
fcntl(fileno(ef->fp), F_SETFD, FD_CLOEXEC);
#else
/* FIXME: check if that code is needed / correct */
h = (HANDLE) _get_osfhandle (fileno(ef->fp));
if (h == (HANDLE) -1)
return NULL;
SetHandleInformation (h, HANDLE_FLAG_INHERIT, 0);
#endif
/* if we opened for read or read-write */
if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
{
unsigned char *dyn_buf = NULL;
unsigned char *p = NULL;
const unsigned char *dyn_buf = NULL;
const unsigned char *p = NULL;
int index = 0;
int num_entries;
int byte_entries;
int i;
#ifdef _WIN32
HANDLE fm;
#endif
ef->data_size = file_stat.st_size;
#ifndef _WIN32
ef->data = mmap(NULL, ef->data_size, PROT_READ,
MAP_SHARED, fileno(ef->fp), 0);
#else
fm = CreateFileMapping((HANDLE) _get_osfhandle (fileno(ef->fp)),
NULL,
PAGE_READONLY,
0,
0,
NULL);
ef->data = MapViewOfFile(fm,
FILE_MAP_READ,
0,
0,
ef->data_size);
CloseHandle(fm);
#endif
if (eet_test_close((ef->data == (void *)-1) || (ef->data == NULL), ef))
return NULL;
if (eet_test_close(ef->data_size < sizeof(int) * 3, ef))
return NULL;
/* build header table if read mode */
/* geat header */
index += sizeof(int);
@ -618,8 +489,8 @@ eet_open(const char *file, Eet_File_Mode mode)
EXTRACT_INT(byte_entries, ef->data, index);
/* we cant have <= 0 values here - invalid */
// if (eet_test_close((num_entries <= 0) || (byte_entries <= 0), ef))
// return NULL;
if (eet_test_close((num_entries <= 0) || (byte_entries <= 0), ef))
return NULL;
/* we can't have more entires than minimum bytes for those! invalid! */
if (eet_test_close((num_entries * 20) > byte_entries, ef))
@ -729,7 +600,7 @@ eet_open(const char *file, Eet_File_Mode mode)
ef->header->directory->nodes[hash] = efn;
/* read-only mode, so currently we have no data loaded */
if (mode == EET_FILE_MODE_READ)
if (ef->mode == EET_FILE_MODE_READ)
efn->data = NULL;
/* read-write mode - read everything into ram */
else
@ -742,6 +613,177 @@ eet_open(const char *file, Eet_File_Mode mode)
/* advance */
p += HEADER_SIZE + name_size;
}
return ef;
}
EAPI Eet_File *
eet_memopen_read(const void *data, size_t size)
{
Eet_File *ef;
if (data == NULL || size == 0)
return NULL;
ef = malloc (sizeof (Eet_File));
if (!ef)
return NULL;
ef->path = NULL;
ef->magic = EET_MAGIC_FILE;
ef->references = 1;
ef->mode = EET_FILE_MODE_READ;
ef->header = NULL;
ef->mtime = 0;
ef->delete_me_now = 1;
ef->fp = NULL;
ef->data = data;
ef->data_size = size;
return eet_internal_read(ef);
}
EAPI Eet_File *
eet_open(const char *file, Eet_File_Mode mode)
{
FILE *fp;
Eet_File *ef;
struct stat file_stat;
#ifdef _WIN32
HANDLE h;
#endif
if (!file)
return NULL;
/* find the current file handle in cache*/
ef = NULL;
if (mode == EET_FILE_MODE_READ)
{
ef = eet_cache_find((char *)file, eet_writers, eet_writers_num);
if (ef)
{
eet_flush(ef);
ef->delete_me_now = 1;
eet_close(ef);
}
ef = eet_cache_find((char *)file, eet_readers, eet_readers_num);
}
else if ((mode == EET_FILE_MODE_WRITE) ||
(mode == EET_FILE_MODE_READ_WRITE))
{
ef = eet_cache_find((char *)file, eet_readers, eet_readers_num);
if (ef)
{
ef->delete_me_now = 1;
eet_close(ef);
}
ef = eet_cache_find((char *)file, eet_writers, eet_writers_num);
}
/* try open the file based on mode */
if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
{
fp = fopen(file, "rb");
if (!fp) return NULL;
if (fstat(fileno(fp), &file_stat))
{
fclose(fp);
return NULL;
}
if ((mode == EET_FILE_MODE_READ) &&
(file_stat.st_size < (sizeof(int) * 3)))
{
fclose(fp);
return NULL;
}
}
else
{
if (mode != EET_FILE_MODE_WRITE) return NULL;
memset(&file_stat, 0, sizeof(file_stat));
/* opening for write - delete old copy of file right away */
unlink(file);
fp = fopen(file, "wb");
}
/* We found one */
if (ef && (file_stat.st_mtime != ef->mtime))
{
ef->delete_me_now = 1;
eet_close(ef);
ef = NULL;
}
if (ef)
{
/* reference it up and return it */
fclose(fp);
ef->references++;
return ef;
}
/* Allocate struct for eet file and have it zero'd out */
ef = malloc(sizeof(Eet_File) + strlen(file) + 1);
if (!ef)
return NULL;
/* fill some of the members */
ef->fp = fp;
ef->path = ((char *)ef) + sizeof(Eet_File);
strcpy(ef->path, file);
ef->magic = EET_MAGIC_FILE;
ef->references = 1;
ef->mode = mode;
ef->header = NULL;
ef->mtime = file_stat.st_mtime;
ef->delete_me_now = 0;
ef->data = NULL;
ef->data_size = 0;
/* if we can't open - bail out */
if (eet_test_close(!ef->fp, ef))
return NULL;
#ifndef _WIN32
fcntl(fileno(ef->fp), F_SETFD, FD_CLOEXEC);
#else
/* FIXME: check if that code is needed / correct */
h = (HANDLE) _get_osfhandle (fileno(ef->fp));
if (h == (HANDLE) -1)
return NULL;
SetHandleInformation (h, HANDLE_FLAG_INHERIT, 0);
#endif
/* if we opened for read or read-write */
if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
{
#ifdef _WIN32
HANDLE fm;
#endif
ef->data_size = file_stat.st_size;
#ifndef _WIN32
ef->data = mmap(NULL, ef->data_size, PROT_READ,
MAP_SHARED, fileno(ef->fp), 0);
#else
fm = CreateFileMapping((HANDLE) _get_osfhandle (fileno(ef->fp)),
NULL,
PAGE_READONLY,
0,
0,
NULL);
ef->data = MapViewOfFile(fm,
FILE_MAP_READ,
0,
0,
ef->data_size);
CloseHandle(fm);
#endif
ef = eet_internal_read(ef);
if (!ef)
return NULL;
}
/* we need to delete the original file in read-write mode and re-open for writing */
@ -848,11 +890,13 @@ eet_close(Eet_File *ef)
}
free(ef->header);
}
#ifndef _WIN32
if (ef->data) munmap(ef->data, ef->data_size);
if (ef->data) munmap((void*)ef->data, ef->data_size);
#else
if (ef->data) UnmapViewOfFile (ef->data);
#endif
if (ef->fp) fclose(ef->fp);
/* zero out ram for struct - caution tactic against stale memory use */
@ -962,10 +1006,10 @@ eet_read(Eet_File *ef, const char *name, int *size_ret)
return data;
}
EAPI void *
EAPI const void *
eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
{
void *data = NULL;
const void *data = NULL;
int size = 0;
Eet_File_Node *efn;