Eet_Node_Data data;
};
+typedef struct _Eet_File_Header Eet_File_Header;
+typedef struct _Eet_File_Node Eet_File_Node;
+typedef struct _Eet_File_Directory Eet_File_Directory;
+
+struct _Eet_File
+{
+ const char *path;
+ Eina_File *readfp;
+ Eet_File_Header *header;
+ Eet_Dictionary *ed;
+ Eet_Key *key;
+ const unsigned char *data;
+ const void *x509_der;
+ const void *signature;
+ void *sha1;
+
+ Eet_File_Mode mode;
+
+ int magic;
+ int references;
+
+ unsigned long int data_size;
+ int x509_length;
+ unsigned int signature_length;
+ int sha1_length;
+
+ Eina_Lock file_lock;
+
+ unsigned char writes_pending : 1;
+ unsigned char delete_me_now : 1;
+};
+
+struct _Eet_File_Header
+{
+ int magic;
+ Eet_File_Directory *directory;
+};
+
+struct _Eet_File_Directory
+{
+ int size;
+ Eet_File_Node **nodes;
+};
+
+struct _Eet_File_Node
+{
+ char *name;
+ void *data;
+ Eet_File_Node *next; /* FIXME: make buckets linked lists */
+
+ unsigned long int offset;
+ unsigned long int dictionary_offset;
+ unsigned long int name_offset;
+
+ unsigned int name_size;
+ unsigned int size;
+ unsigned int data_size;
+
+ unsigned char free_name : 1;
+ unsigned char compression : 1;
+ unsigned char ciphered : 1;
+ unsigned char alias : 1;
+};
+
+#if 0
+/* Version 2 */
+/* NB: all int's are stored in network byte order on disk */
+/* file format: */
+int magic; /* magic number ie 0x1ee7ff00 */
+int num_directory_entries; /* number of directory entries to follow */
+int bytes_directory_entries; /* bytes of directory entries to follow */
+struct
+{
+ int offset; /* bytes offset into file for data chunk */
+ int flags; /* flags - for now 0 = uncompressed and clear, 1 = compressed and clear, 2 = uncompressed and ciphered, 3 = compressed and ciphered */
+ int size; /* size of the data chunk */
+ int data_size; /* size of the (uncompressed) data chunk */
+ int name_size; /* length in bytes of the name field */
+ char name[name_size]; /* name string (variable length) and \0 terminated */
+} directory[num_directory_entries];
+/* and now startes the data stream... */
+#endif /* if 0 */
+
+#if 0
+/* Version 3 */
+/* NB: all int's are stored in network byte order on disk */
+/* file format: */
+int magic; /* magic number ie 0x1ee70f42 */
+int num_directory_entries; /* number of directory entries to follow */
+int num_dictionary_entries; /* number of dictionary entries to follow */
+struct
+{
+ int data_offset; /* bytes offset into file for data chunk */
+ int size; /* size of the data chunk */
+ int data_size; /* size of the (uncompressed) data chunk */
+ int name_offset; /* bytes offset into file for name string */
+ int name_size; /* length in bytes of the name field */
+ int flags; /* bit flags - for now:
+ bit 0 => compresion on/off
+ bit 1 => ciphered on/off
+ bit 2 => alias
+ */
+} directory[num_directory_entries];
+struct
+{
+ int hash;
+ int offset;
+ int size;
+ int prev;
+ int next;
+} dictionary[num_dictionary_entries];
+/* now start the string stream. */
+/* and right after them the data stream. */
+int magic_sign; /* Optional, only if the eet file is signed. */
+int signature_length; /* Signature length. */
+int x509_length; /* Public certificate that signed the file. */
+char signature[signature_length]; /* The signature. */
+char x509[x509_length]; /* The public certificate. */
+#endif /* if 0 */
+
/*
* variable and macros used for the eina_log module
*/
void
eet_node_free(Eet_Node *node);
+
+#define GENERIC_ALLOC_FREE_HEADER(TYPE, Type) \
+ TYPE *Type##_malloc(unsigned int); \
+ TYPE *Type##_calloc(unsigned int); \
+ void Type##_mp_free(TYPE *e);
+
+GENERIC_ALLOC_FREE_HEADER(Eet_File_Directory, eet_file_directory);
+GENERIC_ALLOC_FREE_HEADER(Eet_File_Node, eet_file_node);
+GENERIC_ALLOC_FREE_HEADER(Eet_File_Header, eet_file_header);
+GENERIC_ALLOC_FREE_HEADER(Eet_Dictionary, eet_dictionary);
+GENERIC_ALLOC_FREE_HEADER(Eet_File, eet_file);
+GENERIC_ALLOC_FREE_HEADER(Eet_String, eet_string);
+
+Eina_Bool eet_mempool_init(void);
+void eet_mempool_shutdown(void);
+
#ifndef PATH_MAX
# define PATH_MAX 4096
#endif /* ifndef PATH_MAX */
--- /dev/null
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <Eina.h>
+#include "Eet.h"
+#include "Eet_private.h"
+
+typedef struct _Eet_Mempool Eet_Mempool;
+struct _Eet_Mempool
+{
+ const char *name;
+ Eina_Mempool *mp;
+ size_t size;
+};
+
+#define GENERIC_ALLOC_FREE(TYPE, Type) \
+ Eet_Mempool Type##_mp = { #TYPE, NULL, sizeof (TYPE) }; \
+ \
+ TYPE * \
+ Type##_malloc(unsigned int num) \
+ { \
+ return eina_mempool_malloc(Type##_mp.mp, num * sizeof (TYPE)); \
+ } \
+ TYPE * \
+ Type##_calloc(unsigned int num) \
+ { \
+ return eina_mempool_calloc(Type##_mp.mp, num * sizeof (TYPE)); \
+ } \
+ void \
+ Type##_mp_free(TYPE *e) \
+ { \
+ eina_mempool_free(Type##_mp.mp, e); \
+ }
+
+GENERIC_ALLOC_FREE(Eet_File_Directory, eet_file_directory);
+GENERIC_ALLOC_FREE(Eet_File_Node, eet_file_node);
+GENERIC_ALLOC_FREE(Eet_File_Header, eet_file_header);
+GENERIC_ALLOC_FREE(Eet_Dictionary, eet_dictionary);
+GENERIC_ALLOC_FREE(Eet_File, eet_file);
+GENERIC_ALLOC_FREE(Eet_String, eet_string);
+
+static Eet_Mempool *mempool_array[] = {
+ &eet_file_directory_mp,
+ &eet_file_node_mp,
+ &eet_file_header_mp,
+ &eet_dictionary_mp,
+ &eet_file_mp,
+ &eet_string_mp
+};
+
+Eina_Bool
+eet_mempool_init(void)
+{
+ const char *choice;
+ unsigned int i;
+
+ choice = getenv("EINA_MEMPOOL");
+ if ((!choice) || (!choice[0]))
+ choice = "chained_mempool";
+
+ for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i)
+ {
+ retry:
+ mempool_array[i]->mp = eina_mempool_add(choice, mempool_array[i]->name, NULL, mempool_array[i]->size, 64);
+ if (!mempool_array[i]->mp)
+ {
+ if (!strcmp(choice, "pass_through"))
+ {
+ ERR("Falling back to pass through ! Previously tried '%s' mempool.", choice);
+ choice = "pass_through";
+ goto retry;
+ }
+ else
+ {
+ ERR("Impossible to allocate mempool '%s' !", choice);
+ return EINA_FALSE;
+ }
+ }
+ }
+ return EINA_TRUE;
+}
+
+void
+eet_mempool_shutdown(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < sizeof (mempool_array) / sizeof (mempool_array[0]); ++i)
+ {
+ eina_mempool_del(mempool_array[i]->mp);
+ mempool_array[i]->mp = NULL;
+ }
+}
+
#define EET_MAGIC_FILE2 0x1ee70f42
-typedef struct _Eet_File_Header Eet_File_Header;
-typedef struct _Eet_File_Node Eet_File_Node;
-typedef struct _Eet_File_Directory Eet_File_Directory;
-
-struct _Eet_File
-{
- const char *path;
- Eina_File *readfp;
- Eet_File_Header *header;
- Eet_Dictionary *ed;
- Eet_Key *key;
- const unsigned char *data;
- const void *x509_der;
- const void *signature;
- void *sha1;
-
- Eet_File_Mode mode;
-
- int magic;
- int references;
-
- unsigned long int data_size;
- int x509_length;
- unsigned int signature_length;
- int sha1_length;
-
- Eina_Lock file_lock;
-
- unsigned char writes_pending : 1;
- unsigned char delete_me_now : 1;
-};
-
-struct _Eet_File_Header
-{
- int magic;
- Eet_File_Directory *directory;
-};
-
-struct _Eet_File_Directory
-{
- int size;
- Eet_File_Node **nodes;
-};
-
-struct _Eet_File_Node
-{
- char *name;
- void *data;
- Eet_File_Node *next; /* FIXME: make buckets linked lists */
-
- unsigned long int offset;
- unsigned long int dictionary_offset;
- unsigned long int name_offset;
-
- unsigned int name_size;
- unsigned int size;
- unsigned int data_size;
-
- unsigned char free_name : 1;
- unsigned char compression : 1;
- unsigned char ciphered : 1;
- unsigned char alias : 1;
-};
-
-#if 0
-/* Version 2 */
-/* NB: all int's are stored in network byte order on disk */
-/* file format: */
-int magic; /* magic number ie 0x1ee7ff00 */
-int num_directory_entries; /* number of directory entries to follow */
-int bytes_directory_entries; /* bytes of directory entries to follow */
-struct
-{
- int offset; /* bytes offset into file for data chunk */
- int flags; /* flags - for now 0 = uncompressed and clear, 1 = compressed and clear, 2 = uncompressed and ciphered, 3 = compressed and ciphered */
- int size; /* size of the data chunk */
- int data_size; /* size of the (uncompressed) data chunk */
- int name_size; /* length in bytes of the name field */
- char name[name_size]; /* name string (variable length) and \0 terminated */
-} directory[num_directory_entries];
-/* and now startes the data stream... */
-#endif /* if 0 */
-
-#if 0
-/* Version 3 */
-/* NB: all int's are stored in network byte order on disk */
-/* file format: */
-int magic; /* magic number ie 0x1ee70f42 */
-int num_directory_entries; /* number of directory entries to follow */
-int num_dictionary_entries; /* number of dictionary entries to follow */
-struct
-{
- int data_offset; /* bytes offset into file for data chunk */
- int size; /* size of the data chunk */
- int data_size; /* size of the (uncompressed) data chunk */
- int name_offset; /* bytes offset into file for name string */
- int name_size; /* length in bytes of the name field */
- int flags; /* bit flags - for now:
- bit 0 => compresion on/off
- bit 1 => ciphered on/off
- bit 2 => alias
- */
-} directory[num_directory_entries];
-struct
-{
- int hash;
- int offset;
- int size;
- int prev;
- int next;
-} dictionary[num_dictionary_entries];
-/* now start the string stream. */
-/* and right after them the data stream. */
-int magic_sign; /* Optional, only if the eet file is signed. */
-int signature_length; /* Signature length. */
-int x509_length; /* Public certificate that signed the file. */
-char signature[signature_length]; /* The signature. */
-char x509[x509_length]; /* The public certificate. */
-#endif /* if 0 */
-
#define EET_FILE2_HEADER_COUNT 3
#define EET_FILE2_DIRECTORY_ENTRY_COUNT 6
#define EET_FILE2_DICTIONARY_ENTRY_COUNT 5
eina_lock_new(&eet_cache_lock);
- if (!eet_node_init())
+ if (!eet_mempool_init())
{
EINA_LOG_ERR("Eet: Eet_Node mempool creation failed");
goto unregister_log_domain;
}
+ if (!eet_node_init())
+ {
+ EINA_LOG_ERR("Eet: Eet_Node mempool creation failed");
+ goto shutdown_mempool;
+ }
+
#ifdef HAVE_GNUTLS
/* Before the library can be used, it must initialize itself if needed. */
if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
shutdown_eet:
#endif
eet_node_shutdown();
+shutdown_mempool:
+ eet_mempool_shutdown();
unregister_log_domain:
eina_log_domain_unregister(_eet_log_dom_global);
_eet_log_dom_global = -1;
eet_clearcache();
eet_node_shutdown();
+ eet_mempool_shutdown();
eina_lock_free(&eet_cache_lock);
return NULL;
/* allocate header */
- ef->header = calloc(1, sizeof(Eet_File_Header));
+ ef->header = eet_file_header_calloc(1);
if (eet_test_close(!ef->header, ef))
return NULL;
ef->header->magic = EET_MAGIC_FILE_HEADER;
/* allocate directory block in ram */
- ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
+ ef->header->directory = eet_file_directory_calloc(1);
if (eet_test_close(!ef->header->directory, ef))
return NULL;
/* out directory block is inconsistent - we have overrun our */
/* dynamic block buffer before we finished scanning dir entries */
- efn = malloc(sizeof(Eet_File_Node));
+ efn = eet_file_node_malloc(1);
if (eet_test_close(!efn, ef))
{
- if (efn) free(efn); /* yes i know - we only get here if
+ if (efn) eet_file_node_mp_free(efn); /* yes i know - we only get here if
* efn is null/0 -> trying to shut up
* warning tools like cppcheck */
return NULL;
ef))
return NULL;
- ef->ed = calloc(1, sizeof (Eet_Dictionary));
+ ef->ed = eet_dictionary_calloc(1);
if (eet_test_close(!ef->ed, ef))
return NULL;
- ef->ed->all = calloc(num_dictionary_entries, sizeof (Eet_String));
+ ef->ed->all = eet_string_calloc(num_dictionary_entries);
if (eet_test_close(!ef->ed->all, ef))
return NULL;
return NULL;
/* allocate header */
- ef->header = calloc(1, sizeof(Eet_File_Header));
+ ef->header = eet_file_header_calloc(1);
if (eet_test_close(!ef->header, ef))
return NULL;
ef->header->magic = EET_MAGIC_FILE_HEADER;
/* allocate directory block in ram */
- ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
+ ef->header->directory = eet_file_directory_calloc(1);
if (eet_test_close(!ef->header->directory, ef))
return NULL;
efn = malloc (sizeof(Eet_File_Node));
if (eet_test_close(!efn, ef))
{
- if (efn) free(efn); /* yes i know - we only get here if
+ if (efn) eet_file_node_mp_free(efn); /* yes i know - we only get here if
* efn is null/0 -> trying to shut up
* warning tools like cppcheck */
return NULL;
/* invalid size */
if (eet_test_close(efn->size <= 0, ef))
{
- free(efn);
+ eet_file_node_mp_free(efn);
return NULL;
}
/* invalid name_size */
if (eet_test_close(name_size <= 0, ef))
{
- free(efn);
+ eet_file_node_mp_free(efn);
return NULL;
}
/* reading name would mean falling off end of dyn_buf - invalid */
if (eet_test_close((p + 16 + name_size) > (dyn_buf + byte_entries), ef))
{
- free(efn);
+ eet_file_node_mp_free(efn);
return NULL;
}
efn->name = malloc(sizeof(char) * name_size + 1);
if (eet_test_close(!efn->name, ef))
{
- free(efn);
+ eet_file_node_mp_free(efn);
return NULL;
}
if (efn->free_name)
free(efn->name);
- free(efn);
+ eet_file_node_mp_free(efn);
}
}
free(ef->header->directory->nodes);
}
- free(ef->header->directory);
+ eet_file_directory_mp_free(ef->header->directory);
}
- free(ef->header);
+ eet_file_header_mp_free(ef->header);
}
eet_dictionary_free(ef->ed);
/* free it */
eina_stringshare_del(ef->path);
- free(ef);
+ eet_file_mp_free(ef);
return err;
on_error:
file_len = strlen(file) + 1;
/* Allocate struct for eet file and have it zero'd out */
- ef = malloc(sizeof(Eet_File));
+ ef = eet_file_malloc(1);
if (!ef)
goto on_error;
ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
if (!ef->header->directory)
{
- free(ef->header);
+ eet_file_header_mp_free(ef->header);
ef->header = NULL;
goto on_error;
}
(1 << ef->header->directory->size));
if (!ef->header->directory->nodes)
{
- free(ef->header->directory);
+ eet_file_directory_mp_free(ef->header->directory);
ef->header = NULL;
goto on_error;
}
ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
if (!ef->header->directory)
{
- free(ef->header);
+ eet_file_header_mp_free(ef->header);
ef->header = NULL;
goto on_error;
}
(1 << ef->header->directory->size));
if (!ef->header->directory->nodes)
{
- free(ef->header->directory);
+ eet_file_directory_mp_free(ef->header->directory);
ef->header = NULL;
goto on_error;
}
if (efn->free_name)
free(efn->name);
- free(efn);
+ eet_file_node_mp_free(efn);
exists_already = 1;
break;
}