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 R e s o u r c e C o m p o n e n t %
272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274 % AsynchronousDestroyResourceComponent() destroys the resource environment.
275 % It differs from DestroyResourceComponent() in that it can be called from a
276 % asynchronous signal handler.
278 % The format of the DestroyResourceComponent() method is:
280 % DestroyResourceComponent(void)
283 MagickExport void AsynchronousDestroyResourceComponent(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 R e s o u r c e C o m p o n e n t %
489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
491 % DestroyResourceComponent() destroys the resource component.
493 % The format of the DestroyResourceComponent() method is:
495 % DestroyResourceComponent(void)
498 MagickExport void DestroyResourceComponent(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 s t a n t i a t e R e s o u r c e C o m p o n e n t %
664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
666 % InstantiateResourcesComponent() instantiates the resource component.
668 % The format of the InstantiateResourcesComponent method is:
670 % MagickBooleanType InstantiateResourcesComponent(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 MagickBooleanType InstantiateResourcesComponent(void)
708 Set Magick resource limits.
710 AcquireSemaphoreInfo(&resource_semaphore);
711 RelinquishSemaphoreInfo(resource_semaphore);
712 pagesize=GetMagickPageSize();
714 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
715 pages=sysconf(_SC_PHYS_PAGES);
717 memory=(MagickSizeType) pages*pagesize;
718 if ((pagesize <= 0) || (pages <= 0))
719 memory=2048UL*1024UL*1024UL;
720 #if defined(PixelCacheThreshold)
721 memory=PixelCacheThreshold;
723 (void) SetMagickResourceLimit(AreaResource,2UL*memory);
724 (void) SetMagickResourceLimit(MemoryResource,3UL*memory/2UL);
725 (void) SetMagickResourceLimit(MapResource,4UL*memory);
726 limit=GetEnvironmentValue("MAGICK_AREA_LIMIT");
727 if (limit == (char *) NULL)
728 limit=GetPolicyValue("area");
729 if (limit != (char *) NULL)
731 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
732 limit=DestroyString(limit);
734 limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT");
735 if (limit == (char *) NULL)
736 limit=GetPolicyValue("memory");
737 if (limit != (char *) NULL)
739 (void) SetMagickResourceLimit(MemoryResource,
740 StringToSizeType(limit,100.0));
741 limit=DestroyString(limit);
743 limit=GetEnvironmentValue("MAGICK_MAP_LIMIT");
744 if (limit == (char *) NULL)
745 limit=GetPolicyValue("map");
746 if (limit != (char *) NULL)
748 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
749 limit=DestroyString(limit);
751 limit=GetEnvironmentValue("MAGICK_DISK_LIMIT");
752 if (limit == (char *) NULL)
753 limit=GetPolicyValue("disk");
754 if (limit != (char *) NULL)
756 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
757 limit=DestroyString(limit);
760 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
761 files=sysconf(_SC_OPEN_MAX);
763 #if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
769 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
770 files=resources.rlim_cur;
773 #if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
775 files=getdtablesize();
779 (void) SetMagickResourceLimit(FileResource,MagickMax((unsigned long)
781 limit=GetEnvironmentValue("MAGICK_FILE_LIMIT");
782 if (limit == (char *) NULL)
783 limit=GetPolicyValue("file");
784 if (limit != (char *) NULL)
786 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
787 limit=DestroyString(limit);
789 (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads());
790 limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT");
791 if (limit == (char *) NULL)
792 limit=GetPolicyValue("thread");
793 if (limit != (char *) NULL)
795 SetOpenMPMaximumThreads((unsigned long) atol(limit));
796 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
798 limit=DestroyString(limit);
800 limit=GetEnvironmentValue("MAGICK_TIME_LIMIT");
801 if (limit == (char *) NULL)
802 limit=GetPolicyValue("time");
803 if (limit != (char *) NULL)
805 (void) SetMagickResourceLimit(TimeResource,StringToSizeType(limit,100.0));
806 limit=DestroyString(limit);
812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816 % L i s t M a g i c k R e s o u r c e I n f o %
820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822 % ListMagickResourceInfo() lists the resource info to a file.
824 % The format of the ListMagickResourceInfo method is:
826 % MagickBooleanType ListMagickResourceInfo(FILE *file,
827 % ExceptionInfo *exception)
829 % A description of each parameter follows.
831 % o file: An pointer to a FILE.
833 % o exception: return any errors or warnings in this structure.
836 MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
837 ExceptionInfo *magick_unused(exception))
840 area_limit[MaxTextExtent],
841 disk_limit[MaxTextExtent],
842 map_limit[MaxTextExtent],
843 memory_limit[MaxTextExtent],
844 time_limit[MaxTextExtent];
846 if (file == (const FILE *) NULL)
848 AcquireSemaphoreInfo(&resource_semaphore);
849 (void) FormatMagickSize(resource_info.area_limit,area_limit);
850 (void) FormatMagickSize(resource_info.memory_limit,memory_limit);
851 (void) FormatMagickSize(resource_info.map_limit,map_limit);
852 (void) FormatMagickSize(resource_info.disk_limit,disk_limit);
853 (void) CopyMagickString(time_limit,"unlimited",MaxTextExtent);
854 if (resource_info.time_limit != MagickResourceInfinity)
855 (void) FormatMagickString(time_limit,MaxTextExtent,"%lu",(unsigned long)
856 resource_info.time_limit);
857 (void) fprintf(file,"File Area Memory Map"
858 " Disk Thread Time\n");
859 (void) fprintf(file,"------------------------------------------------------"
860 "------------------\n");
861 (void) fprintf(file,"%4lu %10s %10s %10s %10s %6lu %10s\n",
862 (unsigned long) resource_info.file_limit,area_limit,memory_limit,map_limit,
863 disk_limit,(unsigned long) resource_info.thread_limit,time_limit);
865 RelinquishSemaphoreInfo(resource_semaphore);
870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
874 % R e l i n q u i s h M a g i c k R e s o u r c e %
878 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
880 % RelinquishMagickResource() relinquishes resources of the specified type.
882 % The format of the RelinquishMagickResource() method is:
884 % void RelinquishMagickResource(const ResourceType type,
885 % const MagickSizeType size)
887 % A description of each parameter follows:
889 % o type: the type of resource.
891 % o size: the size of the resource.
894 MagickExport void RelinquishMagickResource(const ResourceType type,
895 const MagickSizeType size)
898 resource_current[MaxTextExtent],
899 resource_limit[MaxTextExtent],
900 resource_request[MaxTextExtent];
902 (void) FormatMagickSize(size,resource_request);
903 AcquireSemaphoreInfo(&resource_semaphore);
908 resource_info.area=(MagickOffsetType) size;
909 (void) FormatMagickSize((MagickSizeType) resource_info.area,
911 (void) FormatMagickSize(resource_info.area_limit,resource_limit);
916 resource_info.memory-=size;
917 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
919 (void) FormatMagickSize(resource_info.memory_limit,resource_limit);
924 resource_info.map-=size;
925 (void) FormatMagickSize((MagickSizeType) resource_info.map,
927 (void) FormatMagickSize(resource_info.map_limit,resource_limit);
932 resource_info.disk-=size;
933 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
935 (void) FormatMagickSize(resource_info.disk_limit,resource_limit);
940 resource_info.file-=size;
941 (void) FormatMagickSize((MagickSizeType) resource_info.file,
943 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
949 resource_info.thread-=size;
950 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
952 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
958 resource_info.time-=size;
959 (void) FormatMagickSize((MagickSizeType) resource_info.time,
961 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
968 RelinquishSemaphoreInfo(resource_semaphore);
969 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
970 MagickOptionToMnemonic(MagickResourceOptions,(long) type),resource_request,
971 resource_current,resource_limit);
975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
979 % 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 %
983 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
985 % RelinquishUniqueFileResource() relinquishes a unique file resource.
987 % The format of the RelinquishUniqueFileResource() method is:
989 % MagickBooleanType RelinquishUniqueFileResource(const char *path)
991 % A description of each parameter follows:
993 % o name: the name of the temporary resource.
996 MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
999 cache_path[MaxTextExtent];
1001 assert(path != (const char *) NULL);
1002 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
1003 if (temporary_resources != (SplayTreeInfo *) NULL)
1008 ResetSplayTreeIterator(temporary_resources);
1009 p=(char *) GetNextKeyInSplayTree(temporary_resources);
1010 while (p != (char *) NULL)
1012 if (LocaleCompare(p,path) == 0)
1014 p=(char *) GetNextKeyInSplayTree(temporary_resources);
1016 if (p != (char *) NULL)
1017 (void) DeleteNodeFromSplayTree(temporary_resources,p);
1019 (void) CopyMagickString(cache_path,path,MaxTextExtent);
1020 AppendImageFormat("cache",cache_path);
1021 (void) remove(cache_path);
1022 return(remove(path) == 0 ? MagickTrue : MagickFalse);
1026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1030 % S e t M a g i c k R e s o u r c e L i m i t %
1034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1036 % SetMagickResourceLimit() sets the limit for a particular resource.
1038 % The format of the SetMagickResourceLimit() method is:
1040 % MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1041 % const MagickSizeType limit)
1043 % A description of each parameter follows:
1045 % o type: the type of resource.
1047 % o limit: the maximum limit for the resource.
1050 MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1051 const MagickSizeType limit)
1053 AcquireSemaphoreInfo(&resource_semaphore);
1058 resource_info.area_limit=limit;
1061 case MemoryResource:
1063 resource_info.memory_limit=limit;
1068 resource_info.map_limit=limit;
1073 resource_info.disk_limit=limit;
1078 resource_info.file_limit=limit;
1081 case ThreadResource:
1083 SetOpenMPMaximumThreads((unsigned long) limit);
1084 resource_info.thread_limit=GetOpenMPMaximumThreads();
1089 resource_info.time_limit=limit;
1095 RelinquishSemaphoreInfo(resource_semaphore);