]> git.imager.perl.org - imager.git/blobdiff - context.c
avoid an unneeded check in the FT1 has_chars() method implementation
[imager.git] / context.c
index 4645ebf5dd83414615be1a8189e8b587e5615d12..0598a6abf3669bc67aac931fde873d99cdff302f 100644 (file)
--- a/context.c
+++ b/context.c
@@ -1,9 +1,9 @@
 #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()
@@ -38,7 +38,8 @@ im_context_new(void) {
   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;
@@ -104,10 +105,13 @@ im_context_refdec(im_context_t ctx, const char *where) {
   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);
 
@@ -128,6 +132,8 @@ im_context_refdec(im_context_t ctx, const char *where) {
 
 Clone an Imager context object, returning the result.
 
+The error stack is not copied from the original context.
+
 =cut
 */
 
@@ -139,26 +145,17 @@ im_context_clone(im_context_t ctx, const char *where) {
   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;
@@ -198,6 +195,9 @@ im_context_clone(im_context_t ctx, const char *where) {
 
 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
 */