#include "imageri.h"
#include <stdio.h>
-static im_slot_t slot_count;
-static im_slot_destroy_t *slot_destructors;
-static i_mutex_t slot_mutex;
+static volatile im_slot_t slot_count = 1;
+static im_slot_destroy_t *volatile slot_destructors;
+static volatile i_mutex_t slot_mutex;
/*
=item im_context_new()
ctx->max_height = 0;
ctx->max_bytes = DEF_BYTES_LIMIT;
- ctx->slots = calloc(sizeof(void *), slot_count);
+ ctx->slot_alloc = slot_count;
+ ctx->slots = calloc(sizeof(void *), ctx->slot_alloc);
if (!ctx->slots) {
free(ctx);
return NULL;
if (ctx->refcount != 0)
return;
+ /* lock here to avoid slot_destructors from being moved under us */
+ i_mutex_lock(slot_mutex);
for (slot = 0; slot < ctx->slot_alloc; ++slot) {
if (ctx->slots[slot] && slot_destructors[slot])
slot_destructors[slot](ctx->slots[slot]);
}
+ i_mutex_unlock(slot_mutex);
free(ctx->slots);
Clone an Imager context object, returning the result.
+The error stack is not copied from the original context.
+
=cut
*/
if (!nctx)
return NULL;
- nctx->slots = calloc(sizeof(void *), slot_count);
+ nctx->slot_alloc = slot_count;
+ nctx->slots = calloc(sizeof(void *), nctx->slot_alloc);
if (!nctx->slots) {
free(nctx);
return NULL;
}
- nctx->slot_alloc = slot_count;
- nctx->error_sp = ctx->error_sp;
+ nctx->error_sp = IM_ERROR_COUNT-1;
for (i = 0; i < IM_ERROR_COUNT; ++i) {
- if (ctx->error_stack[i].msg) {
- size_t sz = ctx->error_alloc[i];
- nctx->error_alloc[i] = sz;
- nctx->error_stack[i].msg = mymalloc(sz);
- memcpy(nctx->error_stack[i].msg, ctx->error_stack[i].msg, sz);
- }
- else {
- nctx->error_alloc[i] = 0;
- nctx->error_stack[i].msg = NULL;
- }
- nctx->error_stack[i].code = ctx->error_stack[i].code;
+ nctx->error_alloc[i] = 0;
+ nctx->error_stack[i].msg = NULL;
}
#ifdef IMAGER_LOG
nctx->log_level = ctx->log_level;
if (ctx->lg_file) {
if (ctx->own_log) {
int newfd = dup(fileno(ctx->lg_file));
- nctx->own_log = 1;
- nctx->lg_file = fdopen(newfd, "w");
- if (nctx->lg_file)
- setvbuf(nctx->lg_file, NULL, _IONBF, BUFSIZ);
+ if (newfd >= 0) {
+ nctx->own_log = 1;
+ nctx->lg_file = fdopen(newfd, "w");
+ if (nctx->lg_file)
+ setvbuf(nctx->lg_file, NULL, _IONBF, BUFSIZ);
+ }
+ else {
+#ifdef IMAGER_TRACE_CONTEXT
+ perror("im_context:failed to clone log");
+#endif
+ free(nctx->slots);
+ free(nctx);
+ return NULL;
+ }
}
else {
/* stderr */
Allocate a new context-local-storage slot.
+C<desctructor> will be called when the context is destroyed if the
+corresponding slot is non-NULL.
+
=cut
*/