]> granicus.if.org Git - imagemagick/commitdiff
Fixed multi-threading issue in WriteImage.
authordirk <dirk@git.imagemagick.org>
Fri, 19 Sep 2014 20:58:22 +0000 (20:58 +0000)
committerdirk <dirk@git.imagemagick.org>
Fri, 19 Sep 2014 20:58:22 +0000 (20:58 +0000)
MagickCore/blob-private.h
MagickCore/blob.c
MagickCore/constitute.c

index 12b12ff3f8c149b962ec7b0552556e2b5b989b2f..d4f63f1fed6b4fb96e7131498efe90681d8afd62 100644 (file)
@@ -58,6 +58,7 @@ extern MagickPrivate StreamHandler
 
 extern MagickPrivate void
   GetBlobInfo(BlobInfo *),
+  GetBlobPrivate(Image *),
   SetBlobExempt(Image *,const MagickBooleanType);
 
 #if defined(__cplusplus) || defined(c_plusplus)
index 6fcc154a9e4bcf1127a10c505bf93cb4f5641153..5ef8e85523eff350259023b11581178c5773bc57 100644 (file)
@@ -1194,7 +1194,8 @@ MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
   blob=(unsigned char *) RelinquishMagickMemory(blob);
   return(MagickTrue);
 }
-\f
+
+
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -1291,6 +1292,57 @@ MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
   blob_info->semaphore=AcquireSemaphoreInfo();
   blob_info->signature=MagickSignature;
 }
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
++   G e t B l o b P r i v a t e                                               %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  GetBlobPrivate() checks if the blob of the specified image is referenced by
+%  other images. If the reference_count is higher then 1 a new blob is assigned
+%  to the specified image.
+%
+%  The format of the GetBlobError method is:
+%
+%       void GetBlobPrivate(Image *image)
+%
+%  A description of each parameter follows:
+%
+%    o image: the image.
+%
+*/
+MagickPrivate void GetBlobPrivate(Image *image)
+{
+  BlobInfo
+    *blob;
+
+  MagickBooleanType
+    clone;
+
+  assert(image != (Image *) NULL);
+  assert(image->signature == MagickSignature);
+  if (image->debug != MagickFalse)
+    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
+  assert(image->blob != (BlobInfo *) NULL);
+  assert(image->blob->signature == MagickSignature);
+  clone=MagickFalse;
+  LockSemaphoreInfo(image->blob->semaphore);
+  assert(image->blob->reference_count >= 0);
+  if (image->blob->reference_count > 1)
+    clone=MagickTrue;
+  UnlockSemaphoreInfo(image->blob->semaphore);
+  if (clone == MagickFalse)
+    return;
+  blob=CloneBlobInfo(image->blob);
+  DestroyBlob(image);
+  image->blob=blob;
+}
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
index 567ee086f06a3291266227abd6bfd77337e1ab89..42c9eaebe7c6ef47f678ac07dcace79650c1ef06 100644 (file)
@@ -1000,6 +1000,7 @@ MagickExport MagickBooleanType WriteImage(const ImageInfo *image_info,
   assert(exception != (ExceptionInfo *) NULL);
   sans_exception=AcquireExceptionInfo();
   write_info=CloneImageInfo(image_info);
+  GetBlobPrivate(image);
   (void) CopyMagickString(write_info->filename,image->filename,MaxTextExtent);
   if (*write_info->magick == '\0')
     (void) CopyMagickString(write_info->magick,image->magick,MaxTextExtent);
@@ -1238,9 +1239,6 @@ MagickExport MagickBooleanType WriteImages(const ImageInfo *image_info,
 {
 #define WriteImageTag  "Write/Image"
 
-  BlobInfo
-    *blob;
-
   ExceptionInfo
     *sans_exception;
 
@@ -1274,9 +1272,7 @@ MagickExport MagickBooleanType WriteImages(const ImageInfo *image_info,
   assert(exception != (ExceptionInfo *) NULL);
   write_info=CloneImageInfo(image_info);
   images=GetFirstImageInList(images);
-  blob=CloneBlobInfo(images->blob);  /* thread specific I/O handler */
-  DestroyBlob(images);
-  images->blob=blob;
+  GetBlobPrivate(images);
   if (filename != (const char *) NULL)
     for (p=images; p != (Image *) NULL; p=GetNextImageInList(p))
       (void) CopyMagickString(p->filename,filename,MaxTextExtent);