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-2011 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/string-private.h"
60 #include "magick/splay-tree.h"
61 #include "magick/thread-private.h"
62 #include "magick/token.h"
63 #include "magick/utility.h"
68 typedef struct _ResourceInfo
93 *random_info = (RandomInfo *) NULL;
100 MagickULLConstant(0),
101 MagickULLConstant(0),
102 MagickULLConstant(0),
103 MagickULLConstant(0),
104 MagickULLConstant(0),
105 MagickULLConstant(3072)*1024*1024/sizeof(PixelPacket),
106 MagickULLConstant(1536)*1024*1024,
107 MagickULLConstant(3072)*1024*1024,
108 MagickResourceInfinity,
109 MagickULLConstant(768),
110 MagickULLConstant(4),
111 MagickResourceInfinity
115 *resource_semaphore = (SemaphoreInfo *) NULL;
118 *temporary_resources = (SplayTreeInfo *) NULL;
121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
125 % A c q u i r e M a g i c k R e s o u r c e %
129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
131 % AcquireMagickResource() acquires resources of the specified type.
132 % MagickFalse is returned if the specified resource is exhausted otherwise
135 % The format of the AcquireMagickResource() method is:
137 % MagickBooleanType AcquireMagickResource(const ResourceType type,
138 % const MagickSizeType size)
140 % A description of each parameter follows:
142 % o type: the type of resource.
144 % o size: the number of bytes needed from for this resource.
147 MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
148 const MagickSizeType size)
151 resource_current[MaxTextExtent],
152 resource_limit[MaxTextExtent],
153 resource_request[MaxTextExtent];
162 (void) FormatMagickSize(size,MagickFalse,resource_request);
163 if (resource_semaphore == (SemaphoreInfo *) NULL)
164 AcquireSemaphoreInfo(&resource_semaphore);
165 LockSemaphoreInfo(resource_semaphore);
170 resource_info.area=(MagickOffsetType) size;
171 limit=resource_info.area_limit;
172 status=(resource_info.area_limit == MagickResourceInfinity) ||
173 (size < limit) ? MagickTrue : MagickFalse;
174 (void) FormatMagickSize((MagickSizeType) resource_info.area,MagickFalse,
176 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
182 resource_info.memory+=size;
183 limit=resource_info.memory_limit;
184 status=(resource_info.memory_limit == MagickResourceInfinity) ||
185 ((MagickSizeType) resource_info.memory < limit) ?
186 MagickTrue : MagickFalse;
187 (void) FormatMagickSize((MagickSizeType) resource_info.memory,MagickTrue,
189 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
195 resource_info.map+=size;
196 limit=resource_info.map_limit;
197 status=(resource_info.map_limit == MagickResourceInfinity) ||
198 ((MagickSizeType) resource_info.map < limit) ?
199 MagickTrue : MagickFalse;
200 (void) FormatMagickSize((MagickSizeType) resource_info.map,MagickTrue,
202 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
208 resource_info.disk+=size;
209 limit=resource_info.disk_limit;
210 status=(resource_info.disk_limit == MagickResourceInfinity) ||
211 ((MagickSizeType) resource_info.disk < limit) ?
212 MagickTrue : MagickFalse;
213 (void) FormatMagickSize((MagickSizeType) resource_info.disk,MagickTrue,
215 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
221 resource_info.file+=size;
222 limit=resource_info.file_limit;
223 status=(resource_info.file_limit == MagickResourceInfinity) ||
224 ((MagickSizeType) resource_info.file < limit) ?
225 MagickTrue : MagickFalse;
226 (void) FormatMagickSize((MagickSizeType) resource_info.file,MagickFalse,
228 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
229 MagickFalse,resource_limit);
234 resource_info.thread+=size;
235 limit=resource_info.thread_limit;
236 status=(resource_info.thread_limit == MagickResourceInfinity) ||
237 ((MagickSizeType) resource_info.thread < limit) ?
238 MagickTrue : MagickFalse;
239 (void) FormatMagickSize((MagickSizeType) resource_info.thread,MagickFalse,
241 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
242 MagickFalse,resource_limit);
247 resource_info.time+=size;
248 limit=resource_info.time_limit;
249 status=(resource_info.time_limit == MagickResourceInfinity) ||
250 ((MagickSizeType) resource_info.time < limit) ?
251 MagickTrue : MagickFalse;
252 (void) FormatMagickSize((MagickSizeType) resource_info.time,MagickFalse,
254 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
255 MagickFalse,resource_limit);
261 UnlockSemaphoreInfo(resource_semaphore);
262 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
263 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
264 resource_request,resource_current,resource_limit);
269 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
273 + A s y n c h r o n o u s R e s o u r c e C o m p o n e n t T e r m i n u s %
277 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279 % AsynchronousResourceComponentTerminus() destroys the resource environment.
280 % It differs from ResourceComponentTerminus() in that it can be called from a
281 % asynchronous signal handler.
283 % The format of the ResourceComponentTerminus() method is:
285 % ResourceComponentTerminus(void)
288 MagickExport void AsynchronousResourceComponentTerminus(void)
293 if (temporary_resources == (SplayTreeInfo *) NULL)
296 Remove any lingering temporary files.
298 ResetSplayTreeIterator(temporary_resources);
299 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
300 while (path != (const char *) NULL)
303 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
312 % 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 %
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318 % AcquireUniqueFileResource() returns a unique file name, and returns a file
319 % descriptor for the file open for reading and writing.
321 % The format of the AcquireUniqueFileResource() method is:
323 % int AcquireUniqueFileResource(char *path)
325 % A description of each parameter follows:
327 % o path: Specifies a pointer to an array of characters. The unique path
328 % name is returned in this array.
332 static void *DestroyTemporaryResources(void *temporary_resource)
334 (void) remove((char *) temporary_resource);
335 temporary_resource=DestroyString((char *) temporary_resource);
336 return((void *) NULL);
339 static MagickBooleanType GetPathTemplate(char *path)
356 (void) CopyMagickString(path,"magick-XXXXXXXX",MaxTextExtent);
357 exception=AcquireExceptionInfo();
358 directory=(char *) GetImageRegistry(StringRegistryType,"temporary-path",
360 exception=DestroyExceptionInfo(exception);
361 if (directory == (char *) NULL)
362 directory=GetEnvironmentValue("MAGICK_TEMPORARY_PATH");
363 if (directory == (char *) NULL)
364 directory=GetEnvironmentValue("MAGICK_TMPDIR");
365 if (directory == (char *) NULL)
366 directory=GetPolicyValue("temporary-path");
367 if (directory == (char *) NULL)
368 directory=GetEnvironmentValue("TMPDIR");
369 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
370 if (directory == (char *) NULL)
371 directory=GetEnvironmentValue("TMP");
372 if (directory == (char *) NULL)
373 directory=GetEnvironmentValue("TEMP");
376 if (directory == (char *) NULL)
377 directory=GetEnvironmentValue("MTMPDIR");
379 #if defined(P_tmpdir)
380 if (directory == (char *) NULL)
381 directory=ConstantString(P_tmpdir);
383 if (directory == (char *) NULL)
385 if (strlen(directory) > (MaxTextExtent-15))
387 directory=DestroyString(directory);
390 status=GetPathAttributes(directory,&attributes);
391 if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
393 directory=DestroyString(directory);
396 if (directory[strlen(directory)-1] == *DirectorySeparator)
397 (void) FormatLocaleString(path,MaxTextExtent,"%smagick-XXXXXXXX",directory);
399 (void) FormatLocaleString(path,MaxTextExtent,"%s%smagick-XXXXXXXX",
400 directory,DirectorySeparator);
401 directory=DestroyString(directory);
402 if (*DirectorySeparator != '/')
403 for (p=path; *p != '\0'; p++)
404 if (*p == *DirectorySeparator)
409 MagickExport int AcquireUniqueFileResource(char *path)
411 #if !defined(O_NOFOLLOW)
414 #if !defined(TMP_MAX)
415 # define TMP_MAX 238328
429 portable_filename[65] =
430 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
438 assert(path != (char *) NULL);
439 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
440 if (random_info == (RandomInfo *) NULL)
441 random_info=AcquireRandomInfo();
443 for (i=0; i < (ssize_t) TMP_MAX; i++)
446 Get temporary pathname.
448 (void) GetPathTemplate(path);
449 key=GetRandomKey(random_info,2);
450 p=path+strlen(path)-8;
451 datum=GetStringInfoDatum(key);
452 for (i=0; i < (ssize_t) GetStringInfoLength(key); i++)
454 c=(int) (datum[i] & 0x3f);
455 *p++=portable_filename[c];
457 key=DestroyStringInfo(key);
458 #if defined(MAGICKCORE_HAVE_MKSTEMP)
461 setmode(file,O_BINARY);
466 key=GetRandomKey(random_info,6);
467 p=path+strlen(path)-6;
468 datum=GetStringInfoDatum(key);
469 for (i=0; i < (ssize_t) GetStringInfoLength(key); i++)
471 c=(int) (datum[i] & 0x3f);
472 *p++=portable_filename[c];
474 key=DestroyStringInfo(key);
475 file=open(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,S_MODE);
476 if ((file >= 0) || (errno != EEXIST))
479 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
482 if (resource_semaphore == (SemaphoreInfo *) NULL)
483 AcquireSemaphoreInfo(&resource_semaphore);
484 LockSemaphoreInfo(resource_semaphore);
485 if (temporary_resources == (SplayTreeInfo *) NULL)
486 temporary_resources=NewSplayTree(CompareSplayTreeString,
487 DestroyTemporaryResources,(void *(*)(void *)) NULL);
488 UnlockSemaphoreInfo(resource_semaphore);
489 (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
490 (const void *) NULL);
495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499 % G e t M a g i c k R e s o u r c e %
503 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
505 % GetMagickResource() returns the specified resource.
507 % The format of the GetMagickResource() method is:
509 % MagickSizeType GetMagickResource(const ResourceType type)
511 % A description of each parameter follows:
513 % o type: the type of resource.
516 MagickExport MagickSizeType GetMagickResource(const ResourceType type)
522 LockSemaphoreInfo(resource_semaphore);
527 resource=(MagickSizeType) resource_info.area;
532 resource=(MagickSizeType) resource_info.memory;
537 resource=(MagickSizeType) resource_info.map;
542 resource=(MagickSizeType) resource_info.disk;
547 resource=(MagickSizeType) resource_info.file;
552 resource=(MagickSizeType) resource_info.thread;
557 resource=(MagickSizeType) resource_info.time;
563 UnlockSemaphoreInfo(resource_semaphore);
568 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
572 % G e t M a g i c k R e s o u r c e L i m i t %
576 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
578 % GetMagickResourceLimit() returns the specified resource limit.
580 % The format of the GetMagickResourceLimit() method is:
582 % MagickSizeType GetMagickResourceLimit(const ResourceType type)
584 % A description of each parameter follows:
586 % o type: the type of resource.
589 MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
595 if (resource_semaphore == (SemaphoreInfo *) NULL)
596 AcquireSemaphoreInfo(&resource_semaphore);
597 LockSemaphoreInfo(resource_semaphore);
602 resource=resource_info.area_limit;
607 resource=resource_info.memory_limit;
612 resource=resource_info.map_limit;
617 resource=resource_info.disk_limit;
622 resource=resource_info.file_limit;
627 resource=resource_info.thread_limit;
632 resource=resource_info.time_limit;
638 UnlockSemaphoreInfo(resource_semaphore);
643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
647 % L i s t M a g i c k R e s o u r c e I n f o %
651 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
653 % ListMagickResourceInfo() lists the resource info to a file.
655 % The format of the ListMagickResourceInfo method is:
657 % MagickBooleanType ListMagickResourceInfo(FILE *file,
658 % ExceptionInfo *exception)
660 % A description of each parameter follows.
662 % o file: An pointer to a FILE.
664 % o exception: return any errors or warnings in this structure.
667 MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
668 ExceptionInfo *magick_unused(exception))
671 area_limit[MaxTextExtent],
672 disk_limit[MaxTextExtent],
673 map_limit[MaxTextExtent],
674 memory_limit[MaxTextExtent],
675 time_limit[MaxTextExtent];
677 if (file == (const FILE *) NULL)
679 if (resource_semaphore == (SemaphoreInfo *) NULL)
680 AcquireSemaphoreInfo(&resource_semaphore);
681 LockSemaphoreInfo(resource_semaphore);
682 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,area_limit);
683 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
684 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,map_limit);
685 (void) CopyMagickString(disk_limit,"unlimited",MaxTextExtent);
686 if (resource_info.disk_limit != MagickResourceInfinity)
687 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,disk_limit);
688 (void) CopyMagickString(time_limit,"unlimited",MaxTextExtent);
689 if (resource_info.time_limit != MagickResourceInfinity)
690 (void) FormatLocaleString(time_limit,MaxTextExtent,"%.20g",(double)
691 resource_info.time_limit);
692 (void) FormatLocaleFile(file,"File Area Memory Map"
693 " Disk Thread Time\n");
694 (void) FormatLocaleFile(file,
695 "--------------------------------------------------------"
696 "-----------------------\n");
697 (void) FormatLocaleFile(file,"%4g %10s %10s %10s %10s %6g %11s\n",
698 (double) resource_info.file_limit,area_limit,memory_limit,map_limit,
699 disk_limit,(double) resource_info.thread_limit,time_limit);
701 UnlockSemaphoreInfo(resource_semaphore);
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710 % R e l i n q u i s h M a g i c k R e s o u r c e %
714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716 % RelinquishMagickResource() relinquishes resources of the specified type.
718 % The format of the RelinquishMagickResource() method is:
720 % void RelinquishMagickResource(const ResourceType type,
721 % const MagickSizeType size)
723 % A description of each parameter follows:
725 % o type: the type of resource.
727 % o size: the size of the resource.
730 MagickExport void RelinquishMagickResource(const ResourceType type,
731 const MagickSizeType size)
734 resource_current[MaxTextExtent],
735 resource_limit[MaxTextExtent],
736 resource_request[MaxTextExtent];
738 (void) FormatMagickSize(size,MagickFalse,resource_request);
739 if (resource_semaphore == (SemaphoreInfo *) NULL)
740 AcquireSemaphoreInfo(&resource_semaphore);
741 LockSemaphoreInfo(resource_semaphore);
746 resource_info.area=(MagickOffsetType) size;
747 (void) FormatMagickSize((MagickSizeType) resource_info.area,MagickFalse,
749 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
755 resource_info.memory-=size;
756 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
757 MagickTrue,resource_current);
758 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
764 resource_info.map-=size;
765 (void) FormatMagickSize((MagickSizeType) resource_info.map,MagickTrue,
767 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
773 resource_info.disk-=size;
774 (void) FormatMagickSize((MagickSizeType) resource_info.disk,MagickTrue,
776 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
782 resource_info.file-=size;
783 (void) FormatMagickSize((MagickSizeType) resource_info.file,MagickFalse,
785 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
786 MagickFalse,resource_limit);
791 resource_info.thread-=size;
792 (void) FormatMagickSize((MagickSizeType) resource_info.thread,MagickFalse,
794 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
795 MagickFalse,resource_limit);
800 resource_info.time-=size;
801 (void) FormatMagickSize((MagickSizeType) resource_info.time,MagickFalse,
803 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
804 MagickFalse,resource_limit);
810 UnlockSemaphoreInfo(resource_semaphore);
811 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
812 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
813 resource_request,resource_current,resource_limit);
817 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
821 % 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 %
825 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
827 % RelinquishUniqueFileResource() relinquishes a unique file resource.
829 % The format of the RelinquishUniqueFileResource() method is:
831 % MagickBooleanType RelinquishUniqueFileResource(const char *path)
833 % A description of each parameter follows:
835 % o name: the name of the temporary resource.
838 MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
841 cache_path[MaxTextExtent];
843 assert(path != (const char *) NULL);
844 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
845 if (temporary_resources != (SplayTreeInfo *) NULL)
850 ResetSplayTreeIterator(temporary_resources);
851 p=(char *) GetNextKeyInSplayTree(temporary_resources);
852 while (p != (char *) NULL)
854 if (LocaleCompare(p,path) == 0)
856 p=(char *) GetNextKeyInSplayTree(temporary_resources);
858 if (p != (char *) NULL)
859 (void) DeleteNodeFromSplayTree(temporary_resources,p);
861 (void) CopyMagickString(cache_path,path,MaxTextExtent);
862 AppendImageFormat("cache",cache_path);
863 (void) remove(cache_path);
864 return(remove(path) == 0 ? MagickTrue : MagickFalse);
868 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872 + R e s o u r c e C o m p o n e n t G e n e s i s %
876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
878 % ResourceComponentGenesis() instantiates the resource component.
880 % The format of the ResourceComponentGenesis method is:
882 % MagickBooleanType ResourceComponentGenesis(void)
886 static inline size_t MagickMax(const size_t x,const size_t y)
893 static inline MagickSizeType StringToSizeType(const char *string,
894 const double interval)
899 value=SiPrefixToDouble(string,interval);
900 if (value >= (double) MagickULLConstant(~0))
901 return(MagickULLConstant(~0));
902 return((MagickSizeType) value);
905 MagickExport MagickBooleanType ResourceComponentGenesis(void)
919 Set Magick resource limits.
921 AcquireSemaphoreInfo(&resource_semaphore);
922 pagesize=GetMagickPageSize();
924 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
925 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
927 memory=(MagickSizeType) pages*pagesize;
928 if ((pagesize <= 0) || (pages <= 0))
929 memory=2048UL*1024UL*1024UL;
930 #if defined(PixelCacheThreshold)
931 memory=PixelCacheThreshold;
933 (void) SetMagickResourceLimit(AreaResource,2*memory/sizeof(PixelPacket));
934 (void) SetMagickResourceLimit(MemoryResource,memory);
935 (void) SetMagickResourceLimit(MapResource,2*memory);
936 limit=GetEnvironmentValue("MAGICK_AREA_LIMIT");
937 if (limit == (char *) NULL)
938 limit=GetPolicyValue("area");
939 if (limit != (char *) NULL)
941 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
942 limit=DestroyString(limit);
944 limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT");
945 if (limit == (char *) NULL)
946 limit=GetPolicyValue("memory");
947 if (limit != (char *) NULL)
949 (void) SetMagickResourceLimit(MemoryResource,
950 StringToSizeType(limit,100.0));
951 limit=DestroyString(limit);
953 limit=GetEnvironmentValue("MAGICK_MAP_LIMIT");
954 if (limit == (char *) NULL)
955 limit=GetPolicyValue("map");
956 if (limit != (char *) NULL)
958 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
959 limit=DestroyString(limit);
961 limit=GetEnvironmentValue("MAGICK_DISK_LIMIT");
962 if (limit == (char *) NULL)
963 limit=GetPolicyValue("disk");
964 if (limit != (char *) NULL)
966 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
967 limit=DestroyString(limit);
970 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
971 files=(ssize_t) sysconf(_SC_OPEN_MAX);
973 #if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
979 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
980 files=(ssize_t) resources.rlim_cur;
983 #if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
985 files=(ssize_t) getdtablesize();
989 (void) SetMagickResourceLimit(FileResource,MagickMax((size_t)
991 limit=GetEnvironmentValue("MAGICK_FILE_LIMIT");
992 if (limit == (char *) NULL)
993 limit=GetPolicyValue("file");
994 if (limit != (char *) NULL)
996 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
997 limit=DestroyString(limit);
999 (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads());
1000 limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT");
1001 if (limit == (char *) NULL)
1002 limit=GetPolicyValue("thread");
1003 if (limit != (char *) NULL)
1005 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
1007 limit=DestroyString(limit);
1009 limit=GetEnvironmentValue("MAGICK_TIME_LIMIT");
1010 if (limit == (char *) NULL)
1011 limit=GetPolicyValue("time");
1012 if (limit != (char *) NULL)
1014 (void) SetMagickResourceLimit(TimeResource,StringToSizeType(limit,100.0));
1015 limit=DestroyString(limit);
1021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1025 + R e s o u r c e C o m p o n e n t T e r m i n u s %
1029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031 % ResourceComponentTerminus() destroys the resource component.
1033 % The format of the ResourceComponentTerminus() method is:
1035 % ResourceComponentTerminus(void)
1038 MagickExport void ResourceComponentTerminus(void)
1040 if (resource_semaphore == (SemaphoreInfo *) NULL)
1041 AcquireSemaphoreInfo(&resource_semaphore);
1042 LockSemaphoreInfo(resource_semaphore);
1043 if (temporary_resources != (SplayTreeInfo *) NULL)
1044 temporary_resources=DestroySplayTree(temporary_resources);
1045 if (random_info != (RandomInfo *) NULL)
1046 random_info=DestroyRandomInfo(random_info);
1047 UnlockSemaphoreInfo(resource_semaphore);
1048 DestroySemaphoreInfo(&resource_semaphore);
1052 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1056 % S e t M a g i c k R e s o u r c e L i m i t %
1060 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1062 % SetMagickResourceLimit() sets the limit for a particular resource.
1064 % The format of the SetMagickResourceLimit() method is:
1066 % MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1067 % const MagickSizeType limit)
1069 % A description of each parameter follows:
1071 % o type: the type of resource.
1073 % o limit: the maximum limit for the resource.
1077 static inline MagickSizeType MagickMin(const MagickSizeType x,
1078 const MagickSizeType y)
1085 MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1086 const MagickSizeType limit)
1091 if (resource_semaphore == (SemaphoreInfo *) NULL)
1092 AcquireSemaphoreInfo(&resource_semaphore);
1093 LockSemaphoreInfo(resource_semaphore);
1098 resource_info.area_limit=limit;
1099 value=GetPolicyValue("area");
1100 if (value != (char *) NULL)
1101 resource_info.area_limit=MagickMin(limit,StringToSizeType(value,100.0));
1104 case MemoryResource:
1106 resource_info.memory_limit=limit;
1107 value=GetPolicyValue("memory");
1108 if (value != (char *) NULL)
1109 resource_info.memory_limit=MagickMin(limit,StringToSizeType(value,
1115 resource_info.map_limit=limit;
1116 value=GetPolicyValue("map");
1117 if (value != (char *) NULL)
1118 resource_info.map_limit=MagickMin(limit,StringToSizeType(value,100.0));
1123 resource_info.disk_limit=limit;
1124 value=GetPolicyValue("disk");
1125 if (value != (char *) NULL)
1126 resource_info.disk_limit=MagickMin(limit,StringToSizeType(value,100.0));
1131 resource_info.file_limit=limit;
1132 value=GetPolicyValue("file");
1133 if (value != (char *) NULL)
1134 resource_info.file_limit=MagickMin(limit,StringToSizeType(value,100.0));
1137 case ThreadResource:
1139 resource_info.thread_limit=limit;
1140 value=GetPolicyValue("thread");
1141 if (value != (char *) NULL)
1142 resource_info.thread_limit=MagickMin(limit,StringToSizeType(value,
1144 SetOpenMPMaximumThreads((int) resource_info.thread_limit);
1149 resource_info.time_limit=limit;
1150 value=GetPolicyValue("time");
1151 if (value != (char *) NULL)
1152 resource_info.time_limit=MagickMin(limit,StringToSizeType(value,100.0));
1158 UnlockSemaphoreInfo(resource_semaphore);