FILE * output_stream;
char * output_filename;
- // Prepare token pool
+ // Increment counter and prepare token pool
#ifdef kUseObjectPool
token_pool_init();
#endif
// Batch process 1 or more files
for (int i = 0; i < a_file->count; ++i)
{
- token_pool_drain();
buffer = scan_file(a_file->filename[i]);
// Don't free folder -- owned by dirname
}
+
+ // Increment counter and prepare token pool
+#ifdef kUseObjectPool
+ token_pool_init();
+#endif
if (FORMAT_MMD == format) {
result = buffer->str;
if (FORMAT_MMD != format) {
free(result);
}
+
+ // Decrement counter and drain
+ token_pool_drain();
}
} else {
if (a_file->count) {
exit:
- // Clean up token pool
+ // Decrement counter and clean up token pool
+ token_pool_drain();
+
#ifdef kUseObjectPool
token_pool_free();
#endif
#include "object_pool.h"
-static pool * token_pool = NULL;
+static pool * token_pool = NULL; //!< Pointer to our object pool
+
+/// Count number of uses of this pool to allow us know
+/// when it's safe to drain the pool
+static short token_pool_count = 0;
/// Intialize object pool for token allocation
void token_pool_init(void) {
// No pool exists
token_pool = pool_new(sizeof(token));
}
+
+ // Increment counter
+ token_pool_count++;
}
/// Drain token allocator pool to prepare for another parse
void token_pool_drain(void) {
- pool_drain(token_pool);
+ // Decrement counter
+ token_pool_count--;
+
+ if (token_pool_count == 0)
+ pool_drain(token_pool);
}
/// Free token allocator pool
void token_pool_free(void) {
- pool_free(token_pool);
- token_pool = NULL;
+ if (token_pool_count == 0) {
+ pool_free(token_pool);
+ token_pool = NULL;
+ } else {
+ fprintf(stderr, "ERROR: Attempted to drain token pool while still in use.\n");
+ }
}
#endif
#ifdef kUseObjectPool
token * t = pool_allocate_object(token_pool);
#else
- //token * t = calloc(1, sizeof(token));
token * t = malloc(sizeof(token));
#endif
#define kUseObjectPool 1 //!< Use an object pool to allocate tokens to improve
- //!< performance in memory allocation. Frees all
- //!< tokens at once, however, at end of parsing.
+ //!< performance in memory allocation. Frees all
+ //!< tokens at once, however, at end of parsing.
+/// Should call init() once per thread/use, and drain() once per thread/use.
+/// This allows us to know when the pool is no longer being used and it is safe
+/// to free.
#ifdef kUseObjectPool
void token_pool_init(void); //!< Initialize object pool for allocating tokens