42 #include "MagickCore/studio.h"
43 #include "MagickCore/cache.h"
44 #include "MagickCore/cache-private.h"
45 #include "MagickCore/configure.h"
46 #include "MagickCore/exception.h"
47 #include "MagickCore/exception-private.h"
48 #include "MagickCore/linked-list.h"
49 #include "MagickCore/log.h"
50 #include "MagickCore/image.h"
51 #include "MagickCore/image-private.h"
52 #include "MagickCore/memory_.h"
53 #include "MagickCore/nt-base-private.h"
54 #include "MagickCore/option.h"
55 #include "MagickCore/policy.h"
56 #include "MagickCore/random_.h"
57 #include "MagickCore/registry.h"
58 #include "MagickCore/resource_.h"
59 #include "MagickCore/resource-private.h"
60 #include "MagickCore/semaphore.h"
61 #include "MagickCore/signature-private.h"
62 #include "MagickCore/string_.h"
63 #include "MagickCore/string-private.h"
64 #include "MagickCore/splay-tree.h"
65 #include "MagickCore/thread-private.h"
66 #include "MagickCore/token.h"
67 #include "MagickCore/utility.h"
68 #include "MagickCore/utility-private.h"
73 #define MagickPathTemplate "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
74 #define NumberOfResourceTypes \
75 (sizeof(resource_semaphore)/sizeof(*resource_semaphore))
118 MagickULLConstant(0),
119 MagickULLConstant(0),
120 MagickULLConstant(0),
121 MagickULLConstant(0),
122 MagickULLConstant(0),
123 MagickULLConstant(0),
124 MagickULLConstant(0),
125 MagickULLConstant(0),
126 MagickULLConstant(0),
127 MagickULLConstant(0),
128 MagickULLConstant(0),
129 (MagickSizeType) MAGICK_SSIZE_MAX/
sizeof(Quantum)/5,
130 (MagickSizeType) MAGICK_SSIZE_MAX/
sizeof(Quantum)/5,
131 MagickResourceInfinity,
132 MagickULLConstant(3072)*1024*1024,
133 MagickULLConstant(1536)*1024*1024,
134 MagickULLConstant(3072)*1024*1024,
135 MagickResourceInfinity,
136 MagickULLConstant(768),
137 MagickULLConstant(1),
138 MagickULLConstant(0),
139 MagickResourceInfinity
143 *resource_semaphore[] = {
188 MagickExport MagickBooleanType AcquireMagickResource(
const ResourceType type,
189 const MagickSizeType size)
202 request=(MagickOffsetType) size;
218 ActivateSemaphoreInfo(&resource_semaphore[type]);
219 LockSemaphoreInfo(resource_semaphore[type]);
229 resource_info.area=request;
230 limit=resource_info.area_limit;
231 if ((limit == MagickResourceInfinity) || (size < limit))
238 limit=resource_info.disk_limit;
239 if (((MagickSizeType) resource_info.disk+request) >
240 (MagickSizeType) resource_info.disk)
242 resource_info.disk+=request;
243 if ((limit == MagickResourceInfinity) ||
244 (resource_info.disk < (MagickOffsetType) limit))
247 resource_info.disk-=request;
249 current=resource_info.disk;
254 limit=resource_info.file_limit;
255 if (((MagickSizeType) resource_info.file+request) >
256 (MagickSizeType) resource_info.file)
258 resource_info.file+=request;
259 if ((limit == MagickResourceInfinity) ||
260 (resource_info.file < (MagickOffsetType) limit))
263 current=resource_info.file;
269 resource_info.height=request;
270 limit=resource_info.height_limit;
271 if ((limit == MagickResourceInfinity) || (size < limit))
275 case ListLengthResource:
277 resource_info.list_length=request;
278 limit=resource_info.list_length_limit;
279 if ((limit == MagickResourceInfinity) || (size < limit))
286 limit=resource_info.map_limit;
287 if (((MagickSizeType) resource_info.map+request) >
288 (MagickSizeType) resource_info.map)
290 resource_info.map+=request;
291 if ((limit == MagickResourceInfinity) ||
292 (resource_info.map < (MagickOffsetType) limit))
295 resource_info.map-=request;
297 current=resource_info.map;
303 limit=resource_info.memory_limit;
304 if (((MagickSizeType) resource_info.memory+request) >
305 (MagickSizeType) resource_info.memory)
307 resource_info.memory+=request;
308 if ((limit == MagickResourceInfinity) ||
309 (resource_info.memory < (MagickOffsetType) limit))
312 resource_info.memory-=request;
314 current=resource_info.memory;
319 limit=resource_info.thread_limit;
320 if ((limit == MagickResourceInfinity) ||
321 (resource_info.thread < (MagickOffsetType) limit))
325 case ThrottleResource:
327 limit=resource_info.throttle_limit;
328 if ((limit == MagickResourceInfinity) ||
329 (resource_info.throttle < (MagickOffsetType) limit))
335 limit=resource_info.time_limit;
336 if (((MagickSizeType) resource_info.time+request) >
337 (MagickSizeType) resource_info.time)
339 resource_info.time+=request;
340 if ((limit == MagickResourceInfinity) ||
341 (resource_info.time < (MagickOffsetType) limit))
344 resource_info.time-=request;
346 current=resource_info.time;
352 resource_info.width=request;
353 limit=resource_info.width_limit;
354 if ((limit == MagickResourceInfinity) || (size < limit))
372 UnlockSemaphoreInfo(resource_semaphore[type]);
377 if ((GetLogEventMask() & ResourceEvent) != 0)
380 resource_current[MagickFormatExtent],
381 resource_limit[MagickFormatExtent],
382 resource_request[MagickFormatExtent];
384 (void) FormatMagickSize(size,bi,(bi != MagickFalse) ?
"B" :
385 (
const char *) NULL,MagickFormatExtent,resource_request);
386 (void) FormatMagickSize((MagickSizeType) current,bi,(bi != MagickFalse) ?
387 "B" : (
const char *) NULL,MagickFormatExtent,resource_current);
388 (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ?
"B" :
389 (
const char *) NULL,MagickFormatExtent,resource_limit);
390 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
391 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
392 resource_request,resource_current,resource_limit);
417 MagickPrivate
void AsynchronousResourceComponentTerminus(
void)
427 ResetSplayTreeIterator(temporary_resources);
428 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
429 while (path != (
const char *) NULL)
431 (void) ShredFile(path);
432 (void) remove_utf8(path);
433 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
462 static void *DestroyTemporaryResources(
void *temporary_resource)
464 (void) ShredFile((
char *) temporary_resource);
465 (void) remove_utf8((
char *) temporary_resource);
466 temporary_resource=DestroyString((
char *) temporary_resource);
467 return((
void *) NULL);
470 MagickExport MagickBooleanType GetPathTemplate(
char *path)
485 (void) FormatLocaleString(path,MagickPathExtent,
"magick-" MagickPathTemplate);
486 exception=AcquireExceptionInfo();
487 directory=(
char *) GetImageRegistry(StringRegistryType,
"temporary-path",
489 exception=DestroyExceptionInfo(exception);
490 if (directory == (
char *) NULL)
491 directory=GetEnvironmentValue(
"MAGICK_TEMPORARY_PATH");
492 if (directory == (
char *) NULL)
493 directory=GetEnvironmentValue(
"MAGICK_TMPDIR");
494 if (directory == (
char *) NULL)
495 directory=GetEnvironmentValue(
"TMPDIR");
496 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) || defined(__CYGWIN__)
497 if (directory == (
char *) NULL)
498 directory=GetEnvironmentValue(
"TMP");
499 if (directory == (
char *) NULL)
500 directory=GetEnvironmentValue(
"TEMP");
503 if (directory == (
char *) NULL)
504 directory=GetEnvironmentValue(
"MTMPDIR");
506 #if defined(P_tmpdir)
507 if (directory == (
char *) NULL)
508 directory=ConstantString(P_tmpdir);
510 if (directory == (
char *) NULL)
512 value=GetPolicyValue(
"resource:temporary-path");
513 if (value != (
char *) NULL)
515 (void) CloneString(&directory,value);
516 value=DestroyString(value);
518 if (strlen(directory) > (MagickPathExtent-25))
520 directory=DestroyString(directory);
523 status=GetPathAttributes(directory,&attributes);
524 if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
526 directory=DestroyString(directory);
529 if (directory[strlen(directory)-1] == *DirectorySeparator)
530 (void) FormatLocaleString(path,MagickPathExtent,
"%smagick-"
531 MagickPathTemplate,directory);
533 (
void) FormatLocaleString(path,MagickPathExtent,
534 "%s%smagick-" MagickPathTemplate,directory,DirectorySeparator);
535 directory=DestroyString(directory);
536 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
545 for (p=(path[1] == *DirectorySeparator ? path+2 : path); *p !=
'\0'; p++)
546 if (*p == *DirectorySeparator)
553 MagickExport
int AcquireUniqueFileResource(
char *path)
555 #if !defined(O_NOFOLLOW)
558 #if !defined(TMP_MAX)
559 # define TMP_MAX 238328
573 portable_filename[65] =
574 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
582 assert(path != (
char *) NULL);
583 if ((GetLogEventMask() & ResourceEvent) != 0)
584 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"...");
587 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
588 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
589 LockSemaphoreInfo(resource_semaphore[FileResource]);
591 random_info=AcquireRandomInfo();
592 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
595 for (i=0; i < (ssize_t) TMP_MAX; i++)
603 (void) GetPathTemplate(path);
604 key=GetRandomKey(random_info,strlen(MagickPathTemplate)-6);
605 p=path+strlen(path)-strlen(MagickPathTemplate);
606 datum=GetStringInfoDatum(key);
607 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
609 c=(int) (datum[j] & 0x3f);
610 *p++=portable_filename[c];
612 key=DestroyStringInfo(key);
613 #if defined(MAGICKCORE_HAVE_MKSTEMP)
617 #if defined(MAGICKCORE_HAVE_FCHMOD)
618 (void) fchmod(file,0600);
621 setmode(file,O_BINARY);
626 key=GetRandomKey(random_info,strlen(MagickPathTemplate));
627 p=path+strlen(path)-strlen(MagickPathTemplate);
628 datum=GetStringInfoDatum(key);
629 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
631 c=(int) (datum[j] & 0x3f);
632 *p++=portable_filename[c];
634 key=DestroyStringInfo(key);
635 file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
637 if ((file >= 0) || (errno != EEXIST))
640 if ((GetLogEventMask() & ResourceEvent) != 0)
641 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s",path);
644 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
645 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
646 LockSemaphoreInfo(resource_semaphore[FileResource]);
648 temporary_resources=NewSplayTree(CompareSplayTreeString,
649 DestroyTemporaryResources,(
void *(*)(
void *)) NULL);
650 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
651 (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
652 (
const void *) NULL);
678 MagickExport MagickSizeType GetMagickResource(
const ResourceType type)
693 ActivateSemaphoreInfo(&resource_semaphore[type]);
694 LockSemaphoreInfo(resource_semaphore[type]);
703 resource=(MagickSizeType) resource_info.area;
708 resource=(MagickSizeType) resource_info.disk;
713 resource=(MagickSizeType) resource_info.file;
718 resource=(MagickSizeType) resource_info.height;
721 case ListLengthResource:
723 resource=(MagickSizeType) resource_info.list_length;
728 resource=(MagickSizeType) resource_info.map;
733 resource=(MagickSizeType) resource_info.memory;
738 resource=(MagickSizeType) resource_info.time;
743 resource=(MagickSizeType) resource_info.thread;
746 case ThrottleResource:
748 resource=(MagickSizeType) resource_info.throttle;
753 resource=(MagickSizeType) resource_info.width;
767 UnlockSemaphoreInfo(resource_semaphore[type]);
797 MagickExport MagickSizeType GetMagickResourceLimit(
const ResourceType type)
805 return(resource_info.area_limit);
807 return(resource_info.height_limit);
808 case ListLengthResource:
809 return(resource_info.list_length_limit);
811 return(resource_info.thread_limit);
812 case ThrottleResource:
813 return(resource_info.throttle_limit);
815 return(resource_info.width_limit);
820 ActivateSemaphoreInfo(&resource_semaphore[type]);
821 LockSemaphoreInfo(resource_semaphore[type]);
826 resource=resource_info.disk_limit;
831 resource=resource_info.file_limit;
836 resource=resource_info.map_limit;
841 resource=resource_info.memory_limit;
846 resource=resource_info.time_limit;
852 UnlockSemaphoreInfo(resource_semaphore[type]);
881 MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
885 area_limit[MagickFormatExtent],
886 disk_limit[MagickFormatExtent],
887 height_limit[MagickFormatExtent],
888 list_length_limit[MagickFormatExtent],
889 map_limit[MagickFormatExtent],
890 memory_limit[MagickFormatExtent],
891 time_limit[MagickFormatExtent],
892 width_limit[MagickFormatExtent];
894 magick_unreferenced(exception);
896 if (file == (
const FILE *) NULL)
898 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
899 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
900 LockSemaphoreInfo(resource_semaphore[FileResource]);
901 (void) FormatMagickSize(resource_info.width_limit,MagickFalse,
"P",
902 MagickFormatExtent,width_limit);
903 (void) FormatMagickSize(resource_info.height_limit,MagickFalse,
"P",
904 MagickFormatExtent,height_limit);
905 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
"P",
906 MagickFormatExtent,area_limit);
907 (void) CopyMagickString(list_length_limit,
"unlimited",MagickFormatExtent);
908 if (resource_info.list_length_limit != MagickResourceInfinity)
909 (void) FormatMagickSize(resource_info.list_length_limit,MagickTrue,
"B",
910 MagickFormatExtent,list_length_limit);
911 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
"B",
912 MagickFormatExtent,memory_limit);
913 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
"B",
914 MagickFormatExtent,map_limit);
915 (void) CopyMagickString(disk_limit,
"unlimited",MagickFormatExtent);
916 if (resource_info.disk_limit != MagickResourceInfinity)
917 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
"B",
918 MagickFormatExtent,disk_limit);
919 (void) CopyMagickString(time_limit,
"unlimited",MagickFormatExtent);
920 if (resource_info.time_limit != MagickResourceInfinity)
921 (void) FormatLocaleString(time_limit,MagickFormatExtent,
"%.20g",(
double)
922 ((MagickOffsetType) resource_info.time_limit));
923 (void) FormatLocaleFile(file,
"Resource limits:\n");
924 (void) FormatLocaleFile(file,
" Width: %s\n",width_limit);
925 (void) FormatLocaleFile(file,
" Height: %s\n",height_limit);
926 (void) FormatLocaleFile(file,
" Area: %s\n",area_limit);
927 (void) FormatLocaleFile(file,
" List length: %s\n",list_length_limit);
928 (void) FormatLocaleFile(file,
" Memory: %s\n",memory_limit);
929 (void) FormatLocaleFile(file,
" Map: %s\n",map_limit);
930 (void) FormatLocaleFile(file,
" Disk: %s\n",disk_limit);
931 (void) FormatLocaleFile(file,
" File: %.20g\n",(
double) ((MagickOffsetType)
932 resource_info.file_limit));
933 (void) FormatLocaleFile(file,
" Thread: %.20g\n",(
double) ((MagickOffsetType)
934 resource_info.thread_limit));
935 (void) FormatLocaleFile(file,
" Throttle: %.20g\n",(
double)
936 ((MagickOffsetType) resource_info.throttle_limit));
937 (void) FormatLocaleFile(file,
" Time: %s\n",time_limit);
939 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
968 MagickExport
void RelinquishMagickResource(
const ResourceType type,
969 const MagickSizeType size)
990 ActivateSemaphoreInfo(&resource_semaphore[type]);
991 LockSemaphoreInfo(resource_semaphore[type]);
1001 resource_info.disk-=size;
1002 current=(MagickSizeType) resource_info.disk;
1003 limit=resource_info.disk_limit;
1004 assert(resource_info.disk >= 0);
1009 resource_info.file-=size;
1010 current=(MagickSizeType) resource_info.file;
1011 limit=resource_info.file_limit;
1012 assert(resource_info.file >= 0);
1018 resource_info.map-=size;
1019 current=(MagickSizeType) resource_info.map;
1020 limit=resource_info.map_limit;
1021 assert(resource_info.map >= 0);
1024 case MemoryResource:
1027 resource_info.memory-=size;
1028 current=(MagickSizeType) resource_info.memory;
1029 limit=resource_info.memory_limit;
1030 assert(resource_info.memory >= 0);
1036 resource_info.time-=size;
1037 current=(MagickSizeType) resource_info.time;
1038 limit=resource_info.time_limit;
1039 assert(resource_info.time >= 0);
1053 case MemoryResource:
1056 UnlockSemaphoreInfo(resource_semaphore[type]);
1061 if ((GetLogEventMask() & ResourceEvent) != 0)
1064 resource_current[MagickFormatExtent],
1065 resource_limit[MagickFormatExtent],
1066 resource_request[MagickFormatExtent];
1068 (void) FormatMagickSize(size,bi,(bi != MagickFalse) ?
"B" :
1069 (
const char *) NULL,MagickFormatExtent,resource_request);
1070 (void) FormatMagickSize(current,bi,(bi != MagickFalse) ?
"B" :
1071 (
const char *) NULL,MagickFormatExtent,resource_current);
1072 (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ?
"B" :
1073 (
const char *) NULL,MagickFormatExtent,resource_limit);
1074 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
1075 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
1076 resource_request,resource_current,resource_limit);
1102 MagickExport MagickBooleanType RelinquishUniqueFileResource(
const char *path)
1105 cache_path[MagickPathExtent];
1110 assert(path != (
const char *) NULL);
1112 if ((GetLogEventMask() & ResourceEvent) != 0)
1113 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s",path);
1114 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1115 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1116 LockSemaphoreInfo(resource_semaphore[FileResource]);
1118 status=DeleteNodeFromSplayTree(temporary_resources,(
const void *) path);
1119 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1120 (void) CopyMagickString(cache_path,path,MagickPathExtent);
1121 AppendImageFormat(
"cache",cache_path);
1122 if (access_utf8(cache_path,F_OK) == 0)
1124 status=ShredFile(cache_path);
1125 status|=remove_utf8(cache_path);
1127 if (status == MagickFalse)
1129 status=ShredFile(path);
1130 status|=remove_utf8(path);
1132 return(status == 0 ? MagickFalse : MagickTrue);
1154 MagickPrivate MagickBooleanType ResourceComponentGenesis(
void)
1173 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1175 resource_semaphore[i]=AcquireSemaphoreInfo();
1176 (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
1177 limit=GetEnvironmentValue(
"MAGICK_WIDTH_LIMIT");
1178 if (limit != (
char *) NULL)
1180 (void) SetMagickResourceLimit(WidthResource,StringToMagickSizeType(limit,
1182 limit=DestroyString(limit);
1184 (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
1185 limit=GetEnvironmentValue(
"MAGICK_HEIGHT_LIMIT");
1186 if (limit != (
char *) NULL)
1188 (void) SetMagickResourceLimit(HeightResource,StringToMagickSizeType(
1190 limit=DestroyString(limit);
1192 pagesize=GetMagickPageSize();
1194 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1195 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1196 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1200 memory=(MagickSizeType) pages*pagesize;
1201 if ((pagesize <= 0) || (pages <= 0))
1202 memory=2048UL*1024UL*1024UL;
1203 #if defined(PixelCacheThreshold)
1204 memory=PixelCacheThreshold;
1206 (void) SetMagickResourceLimit(AreaResource,2*memory);
1207 limit=GetEnvironmentValue(
"MAGICK_AREA_LIMIT");
1208 if (limit != (
char *) NULL)
1210 (void) SetMagickResourceLimit(AreaResource,StringToMagickSizeType(limit,
1212 limit=DestroyString(limit);
1214 (void) SetMagickResourceLimit(MemoryResource,memory);
1215 limit=GetEnvironmentValue(
"MAGICK_MEMORY_LIMIT");
1216 if (limit != (
char *) NULL)
1218 (void) SetMagickResourceLimit(MemoryResource,StringToMagickSizeType(
1220 limit=DestroyString(limit);
1222 (void) SetMagickResourceLimit(MapResource,2*memory);
1223 limit=GetEnvironmentValue(
"MAGICK_MAP_LIMIT");
1224 if (limit != (
char *) NULL)
1226 (void) SetMagickResourceLimit(MapResource,StringToMagickSizeType(limit,
1228 limit=DestroyString(limit);
1230 (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
1231 limit=GetEnvironmentValue(
"MAGICK_DISK_LIMIT");
1232 if (limit != (
char *) NULL)
1234 (void) SetMagickResourceLimit(DiskResource,StringToMagickSizeType(limit,
1236 limit=DestroyString(limit);
1239 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1240 files=(ssize_t) sysconf(_SC_OPEN_MAX);
1242 #if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1248 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1249 files=(ssize_t) resources.rlim_cur;
1252 #if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1254 files=(ssize_t) getdtablesize();
1258 (void) SetMagickResourceLimit(FileResource,MagickMax((
size_t)
1260 limit=GetEnvironmentValue(
"MAGICK_FILE_LIMIT");
1261 if (limit != (
char *) NULL)
1263 (void) SetMagickResourceLimit(FileResource,StringToMagickSizeType(limit,
1265 limit=DestroyString(limit);
1267 (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads());
1268 limit=GetEnvironmentValue(
"MAGICK_THREAD_LIMIT");
1269 if (limit != (
char *) NULL)
1271 (void) SetMagickResourceLimit(ThreadResource,StringToMagickSizeType(
1273 limit=DestroyString(limit);
1275 (void) SetMagickResourceLimit(ThrottleResource,0);
1276 limit=GetEnvironmentValue(
"MAGICK_THROTTLE_LIMIT");
1277 if (limit != (
char *) NULL)
1279 (void) SetMagickResourceLimit(ThrottleResource,StringToMagickSizeType(
1281 limit=DestroyString(limit);
1283 (void) SetMagickResourceLimit(TimeResource,MagickResourceInfinity);
1284 limit=GetEnvironmentValue(
"MAGICK_TIME_LIMIT");
1285 if (limit != (
char *) NULL)
1287 (void) SetMagickResourceLimit(TimeResource,StringToMagickSizeType(limit,
1289 limit=DestroyString(limit);
1291 (void) SetMagickResourceLimit(ListLengthResource,MagickResourceInfinity);
1292 limit=GetEnvironmentValue(
"MAGICK_LIST_LENGTH_LIMIT");
1293 if (limit != (
char *) NULL)
1295 (void) SetMagickResourceLimit(ListLengthResource,
1296 StringToMagickSizeType(limit,100.0));
1297 limit=DestroyString(limit);
1320 MagickPrivate
void ResourceComponentTerminus(
void)
1325 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1327 resource_semaphore[i]=AcquireSemaphoreInfo();
1328 LockSemaphoreInfo(resource_semaphore[FileResource]);
1330 temporary_resources=DestroySplayTree(temporary_resources);
1332 random_info=DestroyRandomInfo(random_info);
1333 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1334 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1335 RelinquishSemaphoreInfo(&resource_semaphore[i]);
1363 MagickExport MagickBooleanType SetMagickResourceLimit(
const ResourceType type,
1364 const MagickSizeType limit)
1373 value=(
char *) NULL;
1379 case MemoryResource:
1383 ActivateSemaphoreInfo(&resource_semaphore[type]);
1384 LockSemaphoreInfo(resource_semaphore[type]);
1393 value=GetPolicyValue(
"resource:area");
1394 if (value == (
char *) NULL)
1395 resource_info.area_limit=limit;
1397 resource_info.area_limit=MagickMin(limit,StringToMagickSizeType(value,
1403 value=GetPolicyValue(
"resource:disk");
1404 if (value == (
char *) NULL)
1405 resource_info.disk_limit=limit;
1407 resource_info.disk_limit=MagickMin(limit,StringToMagickSizeType(value,
1413 value=GetPolicyValue(
"resource:file");
1414 if (value == (
char *) NULL)
1415 resource_info.file_limit=limit;
1417 resource_info.file_limit=MagickMin(limit,StringToMagickSizeType(value,
1421 case HeightResource:
1423 value=GetPolicyValue(
"resource:height");
1424 if (value == (
char *) NULL)
1425 resource_info.height_limit=limit;
1427 resource_info.height_limit=MagickMin(limit,StringToMagickSizeType(
1429 resource_info.height_limit=MagickMin(resource_info.height_limit,
1430 (MagickSizeType) MAGICK_SSIZE_MAX);
1433 case ListLengthResource:
1435 value=GetPolicyValue(
"resource:list-length");
1436 if (value == (
char *) NULL)
1437 resource_info.list_length_limit=limit;
1439 resource_info.list_length_limit=MagickMin(limit,
1440 StringToMagickSizeType(value,100.0));
1445 value=GetPolicyValue(
"resource:map");
1446 if (value == (
char *) NULL)
1447 resource_info.map_limit=limit;
1449 resource_info.map_limit=MagickMin(limit,StringToMagickSizeType(
1453 case MemoryResource:
1455 value=GetPolicyValue(
"resource:memory");
1456 if (value == (
char *) NULL)
1457 resource_info.memory_limit=limit;
1459 resource_info.memory_limit=MagickMin(limit,StringToMagickSizeType(
1463 case ThreadResource:
1465 value=GetPolicyValue(
"resource:thread");
1466 if (value == (
char *) NULL)
1467 resource_info.thread_limit=limit;
1469 resource_info.thread_limit=MagickMin(limit,StringToMagickSizeType(
1471 if (resource_info.thread_limit > GetOpenMPMaximumThreads())
1472 resource_info.thread_limit=GetOpenMPMaximumThreads();
1474 if (resource_info.thread_limit == 0)
1475 resource_info.thread_limit=1;
1478 case ThrottleResource:
1480 value=GetPolicyValue(
"resource:throttle");
1481 if (value == (
char *) NULL)
1482 resource_info.throttle_limit=limit;
1484 resource_info.throttle_limit=MagickMax(limit,StringToMagickSizeType(
1490 value=GetPolicyValue(
"resource:time");
1491 if (value == (
char *) NULL)
1492 resource_info.time_limit=limit;
1494 resource_info.time_limit=MagickMin(limit,StringToMagickSizeType(value,
1496 ResetPixelCacheEpoch();
1501 value=GetPolicyValue(
"resource:width");
1502 if (value == (
char *) NULL)
1503 resource_info.width_limit=limit;
1505 resource_info.width_limit=MagickMin(limit,StringToMagickSizeType(value,
1507 resource_info.width_limit=MagickMin(resource_info.width_limit,
1508 (MagickSizeType) MAGICK_SSIZE_MAX);
1522 case MemoryResource:
1525 UnlockSemaphoreInfo(resource_semaphore[type]);
1530 if (value != (
char *) NULL)
1531 value=DestroyString(value);