Define declarations.
*/
#define CacheTick(offset,extent) QuantumTick((MagickOffsetType) offset,extent)
+#define IsFileDescriptorLimitExceeded() (GetMagickResource(FileResource) > \
+ GetMagickResourceLimit(FileResource) ? MagickTrue : MagickFalse)
\f
/*
Typedef declarations.
static SemaphoreInfo
*cache_semaphore = (SemaphoreInfo *) NULL;
-
-static SplayTreeInfo
- *cache_resources = (SplayTreeInfo *) NULL;
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cache_info->disk_semaphore=AllocateSemaphoreInfo();
cache_info->debug=IsEventLogging();
cache_info->signature=MagickSignature;
- if ((cache_resources == (SplayTreeInfo *) NULL) &&
- (instantiate_cache == MagickFalse))
- {
- if (cache_semaphore == (SemaphoreInfo *) NULL)
- AcquireSemaphoreInfo(&cache_semaphore);
- LockSemaphoreInfo(cache_semaphore);
- if ((cache_resources == (SplayTreeInfo *) NULL) &&
- (instantiate_cache == MagickFalse))
- {
- cache_resources=NewSplayTree((int (*)(const void *,const void *))
- NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
- instantiate_cache=MagickTrue;
- }
- UnlockSemaphoreInfo(cache_semaphore);
- }
- (void) AddValueToSplayTree(cache_resources,cache_info,cache_info);
return((Cache ) cache_info);
}
\f
if (cache_semaphore == (SemaphoreInfo *) NULL)
AcquireSemaphoreInfo(&cache_semaphore);
LockSemaphoreInfo(cache_semaphore);
- if (cache_resources != (SplayTreeInfo *) NULL)
- cache_resources=DestroySplayTree(cache_resources);
instantiate_cache=MagickFalse;
UnlockSemaphoreInfo(cache_semaphore);
DestroySemaphoreInfo(&cache_semaphore);
return(status == -1 ? MagickFalse : MagickTrue);
}
-static void LimitPixelCacheDescriptors(void)
-{
- register CacheInfo
- *p,
- *q;
-
- /*
- Limit # of open file descriptors.
- */
- if (GetMagickResource(FileResource) < GetMagickResourceLimit(FileResource))
- return;
- LockSemaphoreInfo(cache_semaphore);
- if (cache_resources == (SplayTreeInfo *) NULL)
- {
- UnlockSemaphoreInfo(cache_semaphore);
- return;
- }
- ResetSplayTreeIterator(cache_resources);
- p=(CacheInfo *) GetNextKeyInSplayTree(cache_resources);
- while (p != (CacheInfo *) NULL)
- {
- if ((p->type == DiskCache) && (p->file != -1))
- break;
- p=(CacheInfo *) GetNextKeyInSplayTree(cache_resources);
- }
- for (q=p; p != (CacheInfo *) NULL; )
- {
- if ((p->type == DiskCache) && (p->file != -1) &&
- (p->timestamp < q->timestamp))
- q=p;
- p=(CacheInfo *) GetNextKeyInSplayTree(cache_resources);
- }
- if (q != (CacheInfo *) NULL)
- {
- /*
- Close least recently used cache.
- */
- (void) close(q->file);
- q->file=(-1);
- }
- UnlockSemaphoreInfo(cache_semaphore);
-}
-
static inline MagickSizeType MagickMax(const MagickSizeType x,
const MagickSizeType y)
{
UnlockSemaphoreInfo(cache_info->disk_semaphore);
return(MagickTrue); /* cache already open */
}
- LimitPixelCacheDescriptors();
if (*cache_info->cache_filename == '\0')
file=AcquireUniqueFileResource(cache_info->cache_filename);
else
return((Cache) NULL);
}
UnlockSemaphoreInfo(cache_info->semaphore);
- if (cache_resources != (SplayTreeInfo *) NULL)
- (void) DeleteNodeByValueFromSplayTree(cache_resources,cache_info);
if (cache_info->debug != MagickFalse)
{
char
*/
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
- q=QueueAuthenticNexus(image,x,y,columns,rows,MagickTrue,nexus_info,exception);
+ q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickTrue,nexus_info,
+ exception);
if (q == (Quantum *) NULL)
return((Quantum *) NULL);
cache_info=(CacheInfo *) image->cache;
image->taint=MagickTrue;
image->type=UndefinedType;
if (ValidatePixelCacheMorphology(image) == MagickFalse)
- status=OpenPixelCache(image,IOMode,exception);
+ {
+ status=OpenPixelCache(image,IOMode,exception);
+ cache_info=(CacheInfo *) image->cache;
+ if (cache_info->type == DiskCache)
+ (void) ClosePixelCacheOnDisk(cache_info);
+ }
}
UnlockSemaphoreInfo(image->semaphore);
if (status == MagickFalse)
% %
% %
% %
-+ Q u e u e A u t h e n t i c N e x u s %
++ Q u e u e A u t h e n t i c P i x e l C a c h e N e x u s %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% QueueAuthenticNexus() allocates an region to store image pixels as defined
-% by the region rectangle and returns a pointer to the region. This region is
-% subsequently transferred from the pixel cache with
+% QueueAuthenticPixelCacheNexus() allocates an region to store image pixels as
+% defined by the region rectangle and returns a pointer to the region. This
+% region is subsequently transferred from the pixel cache with
% SyncAuthenticPixelsCache(). A pointer to the pixels is returned if the
% pixels are transferred, otherwise a NULL is returned.
%
-% The format of the QueueAuthenticNexus() method is:
+% The format of the QueueAuthenticPixelCacheNexus() method is:
%
-% Quantum *QueueAuthenticNexus(Image *image,const ssize_t x,
+% Quantum *QueueAuthenticPixelCacheNexus(Image *image,const ssize_t x,
% const ssize_t y,const size_t columns,const size_t rows,
% const MagickBooleanType clone,NexusInfo *nexus_info,
% ExceptionInfo *exception)
% o exception: return any errors or warnings in this structure.
%
*/
-MagickPrivate Quantum *QueueAuthenticNexus(Image *image,const ssize_t x,
- const ssize_t y,const size_t columns,const size_t rows,
+MagickPrivate Quantum *QueueAuthenticPixelCacheNexus(Image *image,
+ const ssize_t x,const ssize_t y,const size_t columns,const size_t rows,
const MagickBooleanType clone,NexusInfo *nexus_info,ExceptionInfo *exception)
{
CacheInfo
cache_info=(CacheInfo *) image->cache;
assert(cache_info->signature == MagickSignature);
assert(id < (int) cache_info->number_threads);
- q=QueueAuthenticNexus(image,x,y,columns,rows,MagickFalse,
+ q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
cache_info->nexus_info[id],exception);
return(q);
}
return(q);
}
assert(id < (int) cache_info->number_threads);
- q=QueueAuthenticNexus(image,x,y,columns,rows,MagickFalse,
+ q=QueueAuthenticPixelCacheNexus(image,x,y,columns,rows,MagickFalse,
cache_info->nexus_info[id],exception);
return(q);
}
offset+=cache_info->columns;
q+=cache_info->metacontent_extent*nexus_info->region.width;
}
+ if (IsFileDescriptorLimitExceeded() != MagickFalse)
+ (void) ClosePixelCacheOnDisk(cache_info);
if (y < (ssize_t) rows)
{
ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
offset+=cache_info->columns;
q+=cache_info->number_channels*nexus_info->region.width;
}
+ if (IsFileDescriptorLimitExceeded() != MagickFalse)
+ (void) ClosePixelCacheOnDisk(cache_info);
if (y < (ssize_t) rows)
{
ThrowFileException(exception,CacheError,"UnableToReadPixelCache",
p+=nexus_info->region.width*cache_info->metacontent_extent;
offset+=cache_info->columns;
}
+ if (IsFileDescriptorLimitExceeded() != MagickFalse)
+ (void) ClosePixelCacheOnDisk(cache_info);
if (y < (ssize_t) rows)
{
ThrowFileException(exception,CacheError,"UnableToWritePixelCache",
p+=nexus_info->region.width*cache_info->number_channels;
offset+=cache_info->columns;
}
+ if (IsFileDescriptorLimitExceeded() != MagickFalse)
+ (void) ClosePixelCacheOnDisk(cache_info);
if (y < (ssize_t) rows)
{
ThrowFileException(exception,CacheError,"UnableToWritePixelCache",