2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % RRRR EEEEE SSSSS OOO U U RRRR CCCC EEEEE %
7 % R R E SS O O U U R R C E %
8 % RRRR EEE SSS O O U U RRRR C EEE %
9 % R R E SS O O U U R R C E %
10 % R R EEEEE SSSSS OOO UUU R R CCCC EEEEE %
13 % Get/Set MagickCore Resources %
20 % Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "magick/studio.h"
43 #include "magick/cache.h"
44 #include "magick/configure.h"
45 #include "magick/exception.h"
46 #include "magick/exception-private.h"
47 #include "magick/hashmap.h"
48 #include "magick/log.h"
49 #include "magick/image.h"
50 #include "magick/memory_.h"
51 #include "magick/option.h"
52 #include "magick/policy.h"
53 #include "magick/random_.h"
54 #include "magick/registry.h"
55 #include "magick/resource_.h"
56 #include "magick/semaphore.h"
57 #include "magick/signature-private.h"
58 #include "magick/string_.h"
59 #include "magick/splay-tree.h"
60 #include "magick/thread-private.h"
61 #include "magick/token.h"
62 #include "magick/utility.h"
67 typedef struct _ResourceInfo
92 *random_info = (RandomInfo *) NULL;
100 MagickULLConstant(0),
101 MagickULLConstant(0),
102 MagickULLConstant(0),
103 MagickULLConstant(0),
104 MagickULLConstant(2048)*1024*1024,
105 MagickULLConstant(1536)*1024*1024,
106 MagickULLConstant(8192)*1024*1024,
107 MagickResourceInfinity,
108 MagickULLConstant(768),
109 MagickULLConstant(8),
110 MagickResourceInfinity
114 *resource_semaphore = (SemaphoreInfo *) NULL;
117 *temporary_resources = (SplayTreeInfo *) NULL;
120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124 % A c q u i r e M a g i c k R e s o u r c e %
128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130 % AcquireMagickResource() acquires resources of the specified type.
131 % MagickFalse is returned if the specified resource is exhausted otherwise
134 % The format of the AcquireMagickResource() method is:
136 % MagickBooleanType AcquireMagickResource(const ResourceType type,
137 % const MagickSizeType size)
139 % A description of each parameter follows:
141 % o type: the type of resource.
143 % o size: the number of bytes needed from for this resource.
146 MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
147 const MagickSizeType size)
150 resource_current[MaxTextExtent],
151 resource_limit[MaxTextExtent],
152 resource_request[MaxTextExtent];
161 (void) FormatMagickSize(size,resource_request);
162 AcquireSemaphoreInfo(&resource_semaphore);
167 resource_info.area=(MagickOffsetType) size;
168 limit=resource_info.area_limit;
169 status=(resource_info.area_limit == MagickResourceInfinity) ||
170 (size < limit) ? MagickTrue : MagickFalse;
171 (void) FormatMagickSize((MagickSizeType) resource_info.area,
173 (void) FormatMagickSize(resource_info.area_limit,resource_limit);
178 resource_info.memory+=size;
179 limit=resource_info.memory_limit;
180 status=(resource_info.memory_limit == MagickResourceInfinity) ||
181 ((MagickSizeType) resource_info.memory < limit) ?
182 MagickTrue : MagickFalse;
183 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
185 (void) FormatMagickSize(resource_info.memory_limit,
191 resource_info.map+=size;
192 limit=resource_info.map_limit;
193 status=(resource_info.map_limit == MagickResourceInfinity) ||
194 ((MagickSizeType) resource_info.map < limit) ?
195 MagickTrue : MagickFalse;
196 (void) FormatMagickSize((MagickSizeType) resource_info.map,
198 (void) FormatMagickSize(resource_info.map_limit,
204 resource_info.disk+=size;
205 limit=resource_info.disk_limit;
206 status=(resource_info.disk_limit == MagickResourceInfinity) ||
207 ((MagickSizeType) resource_info.disk < limit) ?
208 MagickTrue : MagickFalse;
209 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
211 (void) FormatMagickSize(resource_info.disk_limit,resource_limit);
216 resource_info.file+=size;
217 limit=resource_info.file_limit;
218 status=(resource_info.file_limit == MagickResourceInfinity) ||
219 ((MagickSizeType) resource_info.file < limit) ?
220 MagickTrue : MagickFalse;
221 (void) FormatMagickSize((MagickSizeType) resource_info.file,
223 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
229 resource_info.thread+=size;
230 limit=resource_info.thread_limit;
231 status=(resource_info.thread_limit == MagickResourceInfinity) ||
232 ((MagickSizeType) resource_info.thread < limit) ?
233 MagickTrue : MagickFalse;
234 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
236 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
242 resource_info.time+=size;
243 limit=resource_info.time_limit;
244 status=(resource_info.time_limit == MagickResourceInfinity) ||
245 ((MagickSizeType) resource_info.time < limit) ?
246 MagickTrue : MagickFalse;
247 (void) FormatMagickSize((MagickSizeType) resource_info.time,
249 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
256 RelinquishSemaphoreInfo(resource_semaphore);
257 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
258 MagickOptionToMnemonic(MagickResourceOptions,(long) type),resource_request,
259 resource_current,resource_limit);
264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
268 + A s y n c h r o n o u s D e s t r o y M a g i c k R e s o u r c e s %
272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274 % AsynchronousDestroyMagickResources() destroys the resource environment.
275 % It differs from DestroyMagickResources() in that it can be called from a
276 % asynchronous signal handler.
278 % The format of the DestroyMagickResources() method is:
280 % DestroyMagickResources(void)
283 MagickExport void AsynchronousDestroyMagickResources(void)
288 if (temporary_resources == (SplayTreeInfo *) NULL)
291 Remove any lingering temporary files.
293 ResetSplayTreeIterator(temporary_resources);
294 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
295 while (path != (const char *) NULL)
298 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
307 % A c q u i r e U n i q u e F i l e R e s o u r c e %
311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
313 % AcquireUniqueFileResource() returns a unique file name, and returns a file
314 % descriptor for the file open for reading and writing.
316 % The format of the AcquireUniqueFileResource() method is:
318 % int AcquireUniqueFileResource(char *path)
320 % A description of each parameter follows:
322 % o path: Specifies a pointer to an array of characters. The unique path
323 % name is returned in this array.
327 static void *DestroyTemporaryResources(void *temporary_resource)
329 (void) remove((char *) temporary_resource);
330 return((void *) NULL);
333 static MagickBooleanType GetPathTemplate(char *path)
350 (void) CopyMagickString(path,"magick-XXXXXXXX",MaxTextExtent);
351 exception=AcquireExceptionInfo();
352 directory=(char *) GetImageRegistry(StringRegistryType,"temporary-path",
354 exception=DestroyExceptionInfo(exception);
355 if (directory == (char *) NULL)
356 directory=GetEnvironmentValue("MAGICK_TEMPORARY_PATH");
357 if (directory == (char *) NULL)
358 directory=GetEnvironmentValue("MAGICK_TMPDIR");
359 if (directory == (char *) NULL)
360 directory=GetPolicyValue("temporary-path");
361 if (directory == (char *) NULL)
362 directory=GetEnvironmentValue("TMPDIR");
363 #if defined(__WINDOWS__) || defined(__OS2__)
364 if (directory == (char *) NULL)
365 directory=GetEnvironmentValue("TMP");
366 if (directory == (char *) NULL)
367 directory=GetEnvironmentValue("TEMP");
370 if (directory == (char *) NULL)
371 directory=GetEnvironmentValue("MTMPDIR");
373 #if defined(P_tmpdir)
374 if (directory == (char *) NULL)
375 directory=ConstantString(P_tmpdir);
377 if (directory == (char *) NULL)
379 if (strlen(directory) > (MaxTextExtent-15))
381 directory=DestroyString(directory);
384 status=GetPathAttributes(directory,&attributes);
385 if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
387 directory=DestroyString(directory);
390 if (directory[strlen(directory)-1] == *DirectorySeparator)
391 (void) FormatMagickString(path,MaxTextExtent,"%smagick-XXXXXXXX",directory);
393 (void) FormatMagickString(path,MaxTextExtent,"%s%smagick-XXXXXXXX",
394 directory,DirectorySeparator);
395 directory=DestroyString(directory);
396 if (*DirectorySeparator != '/')
397 for (p=path; *p != '\0'; p++)
398 if (*p == *DirectorySeparator)
403 MagickExport int AcquireUniqueFileResource(char *path)
405 #if !defined(O_NOFOLLOW)
408 #if !defined(TMP_MAX)
409 # define TMP_MAX 238328
426 portable_filename[65] =
427 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
435 assert(path != (char *) NULL);
436 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
437 if (random_info == (RandomInfo *) NULL)
438 random_info=AcquireRandomInfo();
440 for (i=0; i < TMP_MAX; i++)
443 Get temporary pathname.
445 (void) GetPathTemplate(path);
446 #if defined(MAGICKCORE_HAVE_MKSTEMP)
449 setmode(file,O_BINARY);
454 key=GetRandomKey(random_info,8);
455 p=path+strlen(path)-8;
456 datum=GetStringInfoDatum(key);
457 for (i=0; i < 8; i++)
459 c=(int) (datum[i] & 0x3f);
460 *p++=portable_filename[c];
462 key=DestroyStringInfo(key);
463 file=open(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,S_MODE);
464 if ((file > 0) || (errno != EEXIST))
467 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
470 AcquireSemaphoreInfo(&resource_semaphore);
471 if (temporary_resources == (SplayTreeInfo *) NULL)
472 temporary_resources=NewSplayTree(CompareSplayTreeString,
473 RelinquishMagickMemory,DestroyTemporaryResources);
474 RelinquishSemaphoreInfo(resource_semaphore);
475 resource=ConstantString(path);
476 (void) AddValueToSplayTree(temporary_resources,resource,resource);
481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 + D e s t r o y M a g i c k R e s o u r c e s %
489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
491 % DestroyMagickResources() destroys the resource environment.
493 % The format of the DestroyMagickResources() method is:
495 % DestroyMagickResources(void)
498 MagickExport void DestroyMagickResources(void)
500 AcquireSemaphoreInfo(&resource_semaphore);
501 if (temporary_resources != (SplayTreeInfo *) NULL)
502 temporary_resources=DestroySplayTree(temporary_resources);
503 if (random_info != (RandomInfo *) NULL)
504 random_info=DestroyRandomInfo(random_info);
505 RelinquishSemaphoreInfo(resource_semaphore);
506 DestroySemaphoreInfo(&resource_semaphore);
510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514 % G e t M a g i c k R e s o u r c e %
518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
520 % GetMagickResource() returns the specified resource.
522 % The format of the GetMagickResource() method is:
524 % MagickSizeType GetMagickResource(const ResourceType type)
526 % A description of each parameter follows:
528 % o type: the type of resource.
531 MagickExport MagickSizeType GetMagickResource(const ResourceType type)
537 AcquireSemaphoreInfo(&resource_semaphore);
542 resource=(MagickSizeType) resource_info.area;
547 resource=(MagickSizeType) resource_info.memory;
552 resource=(MagickSizeType) resource_info.map;
557 resource=(MagickSizeType) resource_info.disk;
562 resource=(MagickSizeType) resource_info.file;
567 resource=(MagickSizeType) resource_info.thread;
572 resource=(MagickSizeType) resource_info.time;
578 RelinquishSemaphoreInfo(resource_semaphore);
583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587 % G e t M a g i c k R e s o u r c e L i m i t %
591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593 % GetMagickResource() returns the specified resource limit.
595 % The format of the GetMagickResourceLimit() method is:
597 % unsigned long GetMagickResourceLimit(const ResourceType type)
599 % A description of each parameter follows:
601 % o type: the type of resource.
604 MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
610 AcquireSemaphoreInfo(&resource_semaphore);
615 resource=resource_info.area_limit;
620 resource=resource_info.memory_limit;
625 resource=resource_info.map_limit;
630 resource=resource_info.disk_limit;
635 resource=resource_info.file_limit;
640 resource=resource_info.thread_limit;
645 resource=resource_info.time_limit;
651 RelinquishSemaphoreInfo(resource_semaphore);
656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
660 + I n i t i a l i z e M a g i c k R e s o u r c e s %
664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
666 % InitializeMagickResources() initializes the resource environment.
668 % The format of the InitializeMagickResources() method is:
670 % InitializeMagickResources(void)
674 static inline unsigned long MagickMax(const unsigned long x,
675 const unsigned long y)
682 static inline MagickSizeType StringToSizeType(const char *string,
683 const double interval)
688 value=StringToDouble(string,interval);
689 if (value >= (double) MagickULLConstant(~0))
690 return(MagickULLConstant(~0));
691 return((MagickSizeType) value);
694 MagickExport void InitializeMagickResources(void)
708 Set Magick resource limits.
711 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PAGESIZE)
712 pagesize=sysconf(_SC_PAGESIZE);
713 #elif defined(MAGICKCORE_HAVE_GETPAGESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
714 pagesize=getpagesize();
717 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
718 pages=sysconf(_SC_PHYS_PAGES);
720 memory=(MagickSizeType) pages*pagesize;
721 if ((pagesize <= 0) || (pages <= 0))
722 memory=2048UL*1024UL*1024UL;
723 #if defined(PixelCacheThreshold)
724 memory=PixelCacheThreshold;
726 (void) SetMagickResourceLimit(AreaResource,2UL*memory);
727 (void) SetMagickResourceLimit(MemoryResource,3UL*memory/2UL);
728 (void) SetMagickResourceLimit(MapResource,4UL*memory);
729 limit=GetEnvironmentValue("MAGICK_AREA_LIMIT");
730 if (limit == (char *) NULL)
731 limit=GetPolicyValue("area");
732 if (limit != (char *) NULL)
734 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
735 limit=DestroyString(limit);
737 limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT");
738 if (limit == (char *) NULL)
739 limit=GetPolicyValue("memory");
740 if (limit != (char *) NULL)
742 (void) SetMagickResourceLimit(MemoryResource,
743 StringToSizeType(limit,100.0));
744 limit=DestroyString(limit);
746 limit=GetEnvironmentValue("MAGICK_MAP_LIMIT");
747 if (limit == (char *) NULL)
748 limit=GetPolicyValue("map");
749 if (limit != (char *) NULL)
751 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
752 limit=DestroyString(limit);
754 limit=GetEnvironmentValue("MAGICK_DISK_LIMIT");
755 if (limit == (char *) NULL)
756 limit=GetPolicyValue("disk");
757 if (limit != (char *) NULL)
759 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
760 limit=DestroyString(limit);
763 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
764 files=sysconf(_SC_OPEN_MAX);
766 #if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
772 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
773 files=resources.rlim_cur;
776 #if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
778 files=getdtablesize();
782 (void) SetMagickResourceLimit(FileResource,MagickMax((unsigned long)
784 limit=GetEnvironmentValue("MAGICK_FILE_LIMIT");
785 if (limit == (char *) NULL)
786 limit=GetPolicyValue("file");
787 if (limit != (char *) NULL)
789 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
790 limit=DestroyString(limit);
792 (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads());
793 limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT");
794 if (limit == (char *) NULL)
795 limit=GetPolicyValue("thread");
796 if (limit != (char *) NULL)
798 SetOpenMPMaximumThreads((unsigned long) atol(limit));
799 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
801 limit=DestroyString(limit);
803 limit=GetEnvironmentValue("MAGICK_TIME_LIMIT");
804 if (limit == (char *) NULL)
805 limit=GetPolicyValue("time");
806 if (limit != (char *) NULL)
808 (void) SetMagickResourceLimit(TimeResource,StringToSizeType(limit,100.0));
809 limit=DestroyString(limit);
814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
818 % L i s t M a g i c k R e s o u r c e I n f o %
822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824 % ListMagickResourceInfo() lists the resource info to a file.
826 % The format of the ListMagickResourceInfo method is:
828 % MagickBooleanType ListMagickResourceInfo(FILE *file,
829 % ExceptionInfo *exception)
831 % A description of each parameter follows.
833 % o file: An pointer to a FILE.
835 % o exception: return any errors or warnings in this structure.
838 MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
839 ExceptionInfo *magick_unused(exception))
842 area_limit[MaxTextExtent],
843 disk_limit[MaxTextExtent],
844 map_limit[MaxTextExtent],
845 memory_limit[MaxTextExtent],
846 time_limit[MaxTextExtent];
848 if (file == (const FILE *) NULL)
850 AcquireSemaphoreInfo(&resource_semaphore);
851 (void) FormatMagickSize(resource_info.area_limit,area_limit);
852 (void) FormatMagickSize(resource_info.memory_limit,memory_limit);
853 (void) FormatMagickSize(resource_info.map_limit,map_limit);
854 (void) FormatMagickSize(resource_info.disk_limit,disk_limit);
855 (void) CopyMagickString(time_limit,"unlimited",MaxTextExtent);
856 if (resource_info.time_limit != MagickResourceInfinity)
857 (void) FormatMagickString(time_limit,MaxTextExtent,"%lu",(unsigned long)
858 resource_info.time_limit);
859 (void) fprintf(file,"File Area Memory Map"
860 " Disk Thread Time\n");
861 (void) fprintf(file,"-----------------------------------------------------"
863 (void) fprintf(file,"%4lu %9s %9s %9s %9s %6lu %9s\n",(unsigned long)
864 resource_info.file_limit,area_limit,memory_limit,map_limit,disk_limit,
865 (unsigned long) resource_info.thread_limit,time_limit);
867 RelinquishSemaphoreInfo(resource_semaphore);
872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
876 % R e l i n q u i s h M a g i c k R e s o u r c e %
880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
882 % RelinquishMagickResource() relinquishes resources of the specified type.
884 % The format of the RelinquishMagickResource() method is:
886 % void RelinquishMagickResource(const ResourceType type,
887 % const MagickSizeType size)
889 % A description of each parameter follows:
891 % o type: the type of resource.
893 % o size: the size of the resource.
896 MagickExport void RelinquishMagickResource(const ResourceType type,
897 const MagickSizeType size)
900 resource_current[MaxTextExtent],
901 resource_limit[MaxTextExtent],
902 resource_request[MaxTextExtent];
904 (void) FormatMagickSize(size,resource_request);
905 AcquireSemaphoreInfo(&resource_semaphore);
910 resource_info.area=(MagickOffsetType) size;
911 (void) FormatMagickSize((MagickSizeType) resource_info.area,
913 (void) FormatMagickSize(resource_info.area_limit,resource_limit);
918 resource_info.memory-=size;
919 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
921 (void) FormatMagickSize(resource_info.memory_limit,resource_limit);
926 resource_info.map-=size;
927 (void) FormatMagickSize((MagickSizeType) resource_info.map,
929 (void) FormatMagickSize(resource_info.map_limit,resource_limit);
934 resource_info.disk-=size;
935 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
937 (void) FormatMagickSize(resource_info.disk_limit,resource_limit);
942 resource_info.file-=size;
943 (void) FormatMagickSize((MagickSizeType) resource_info.file,
945 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
951 resource_info.thread-=size;
952 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
954 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
960 resource_info.time-=size;
961 (void) FormatMagickSize((MagickSizeType) resource_info.time,
963 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
970 RelinquishSemaphoreInfo(resource_semaphore);
971 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
972 MagickOptionToMnemonic(MagickResourceOptions,(long) type),resource_request,
973 resource_current,resource_limit);
977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
981 % R e l i n q u i s h U n i q u e F i l e R e s o u r c e %
985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
987 % RelinquishUniqueFileResource() relinquishes a unique file resource.
989 % The format of the RelinquishUniqueFileResource() method is:
991 % MagickBooleanType RelinquishUniqueFileResource(const char *path)
993 % A description of each parameter follows:
995 % o name: the name of the temporary resource.
998 MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
1001 cache_path[MaxTextExtent];
1003 assert(path != (const char *) NULL);
1004 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
1005 if (temporary_resources != (SplayTreeInfo *) NULL)
1010 ResetSplayTreeIterator(temporary_resources);
1011 p=(char *) GetNextKeyInSplayTree(temporary_resources);
1012 while (p != (char *) NULL)
1014 if (LocaleCompare(p,path) == 0)
1016 p=(char *) GetNextKeyInSplayTree(temporary_resources);
1018 if (p != (char *) NULL)
1019 (void) DeleteNodeFromSplayTree(temporary_resources,p);
1021 (void) CopyMagickString(cache_path,path,MaxTextExtent);
1022 AppendImageFormat("cache",cache_path);
1023 (void) remove(cache_path);
1024 return(remove(path) == 0 ? MagickTrue : MagickFalse);
1028 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1032 % S e t M a g i c k R e s o u r c e L i m i t %
1036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1038 % SetMagickResourceLimit() sets the limit for a particular resource.
1040 % The format of the SetMagickResourceLimit() method is:
1042 % MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1043 % const MagickSizeType limit)
1045 % A description of each parameter follows:
1047 % o type: the type of resource.
1049 % o limit: the maximum limit for the resource.
1052 MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1053 const MagickSizeType limit)
1055 AcquireSemaphoreInfo(&resource_semaphore);
1060 resource_info.area_limit=limit;
1063 case MemoryResource:
1065 resource_info.memory_limit=limit;
1070 resource_info.map_limit=limit;
1075 resource_info.disk_limit=limit;
1080 resource_info.file_limit=limit;
1083 case ThreadResource:
1085 SetOpenMPMaximumThreads((unsigned long) limit);
1086 resource_info.thread_limit=GetOpenMPMaximumThreads();
1091 resource_info.time_limit=limit;
1097 RelinquishSemaphoreInfo(resource_semaphore);