From: dirk Date: Fri, 19 Sep 2014 20:58:22 +0000 (+0000) Subject: Fixed multi-threading issue in WriteImage. X-Git-Tag: 7.0.1-0~1995 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=54fae5148e7cfd62c753f0c36d2ce0d601bc50fb;p=imagemagick Fixed multi-threading issue in WriteImage. --- diff --git a/MagickCore/blob-private.h b/MagickCore/blob-private.h index 12b12ff3f..d4f63f1fe 100644 --- a/MagickCore/blob-private.h +++ b/MagickCore/blob-private.h @@ -58,6 +58,7 @@ extern MagickPrivate StreamHandler extern MagickPrivate void GetBlobInfo(BlobInfo *), + GetBlobPrivate(Image *), SetBlobExempt(Image *,const MagickBooleanType); #if defined(__cplusplus) || defined(c_plusplus) diff --git a/MagickCore/blob.c b/MagickCore/blob.c index 6fcc154a9..5ef8e8552 100644 --- a/MagickCore/blob.c +++ b/MagickCore/blob.c @@ -1194,7 +1194,8 @@ MagickExport MagickBooleanType FileToImage(Image *image,const char *filename, blob=(unsigned char *) RelinquishMagickMemory(blob); return(MagickTrue); } - + + /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % @@ -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; +} /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/MagickCore/constitute.c b/MagickCore/constitute.c index 567ee086f..42c9eaebe 100644 --- a/MagickCore/constitute.c +++ b/MagickCore/constitute.c @@ -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);