42#include "MagickCore/studio.h"
43#include "MagickCore/cache.h"
44#include "MagickCore/configure.h"
45#include "MagickCore/exception.h"
46#include "MagickCore/exception-private.h"
47#include "MagickCore/linked-list.h"
48#include "MagickCore/log.h"
49#include "MagickCore/image.h"
50#include "MagickCore/image-private.h"
51#include "MagickCore/memory_.h"
52#include "MagickCore/nt-base-private.h"
53#include "MagickCore/option.h"
54#include "MagickCore/policy.h"
55#include "MagickCore/random_.h"
56#include "MagickCore/registry.h"
57#include "MagickCore/resource_.h"
58#include "MagickCore/resource-private.h"
59#include "MagickCore/semaphore.h"
60#include "MagickCore/signature-private.h"
61#include "MagickCore/string_.h"
62#include "MagickCore/string-private.h"
63#include "MagickCore/splay-tree.h"
64#include "MagickCore/thread-private.h"
65#include "MagickCore/timer-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))
113 *random_info = (RandomInfo *) NULL;
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)/MaxPixelChannels),
130 (MagickSizeType) (MAGICK_SSIZE_MAX/
sizeof(Quantum)/MaxPixelChannels),
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[] = {
159 *temporary_resources = (SplayTreeInfo *) NULL;
188MagickExport 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+(MagickSizeType) request) > (MagickSizeType) resource_info.disk)
241 resource_info.disk+=request;
242 if ((limit == MagickResourceInfinity) ||
243 (resource_info.disk < (MagickOffsetType) limit))
246 resource_info.disk-=request;
248 current=resource_info.disk;
253 limit=resource_info.file_limit;
254 if (((MagickSizeType) resource_info.file+(MagickSizeType) request) > (MagickSizeType) resource_info.file)
256 resource_info.file+=request;
257 if ((limit == MagickResourceInfinity) ||
258 (resource_info.file < (MagickOffsetType) limit))
261 current=resource_info.file;
267 resource_info.height=request;
268 limit=resource_info.height_limit;
269 if ((limit == MagickResourceInfinity) || (size < limit))
273 case ListLengthResource:
275 resource_info.list_length=request;
276 limit=resource_info.list_length_limit;
277 if ((limit == MagickResourceInfinity) || (size < limit))
284 limit=resource_info.map_limit;
285 if (((MagickSizeType) resource_info.map+(MagickSizeType) request) > (MagickSizeType) resource_info.map)
287 resource_info.map+=request;
288 if ((limit == MagickResourceInfinity) ||
289 (resource_info.map < (MagickOffsetType) limit))
292 resource_info.map-=request;
294 current=resource_info.map;
300 limit=resource_info.memory_limit;
301 if (((MagickSizeType) resource_info.memory+(MagickSizeType) request) > (MagickSizeType) resource_info.memory)
303 resource_info.memory+=request;
304 if ((limit == MagickResourceInfinity) ||
305 (resource_info.memory < (MagickOffsetType) limit))
308 resource_info.memory-=request;
310 current=resource_info.memory;
315 limit=resource_info.thread_limit;
316 if ((limit == MagickResourceInfinity) ||
317 (resource_info.thread < (MagickOffsetType) limit))
321 case ThrottleResource:
323 limit=resource_info.throttle_limit;
324 if ((limit == MagickResourceInfinity) ||
325 (resource_info.throttle < (MagickOffsetType) limit))
331 limit=resource_info.time_limit;
332 if (((MagickSizeType) resource_info.time+(MagickSizeType) request) > (MagickSizeType) resource_info.time)
334 resource_info.time+=request;
335 if ((limit == MagickResourceInfinity) ||
336 (resource_info.time < (MagickOffsetType) limit))
339 resource_info.time-=request;
341 current=resource_info.time;
347 resource_info.width=request;
348 limit=resource_info.width_limit;
349 if ((limit == MagickResourceInfinity) || (size < limit))
367 UnlockSemaphoreInfo(resource_semaphore[type]);
372 if ((GetLogEventMask() & ResourceEvent) != 0)
375 resource_current[MagickFormatExtent],
376 resource_limit[MagickFormatExtent],
377 resource_request[MagickFormatExtent];
379 (void) FormatMagickSize(size,bi,(bi != MagickFalse) ?
"B" :
380 (
const char *) NULL,MagickFormatExtent,resource_request);
381 (void) FormatMagickSize((MagickSizeType) current,bi,(bi != MagickFalse) ?
382 "B" : (
const char *) NULL,MagickFormatExtent,resource_current);
383 (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ?
"B" :
384 (
const char *) NULL,MagickFormatExtent,resource_limit);
385 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
386 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
387 resource_request,resource_current,resource_limit);
412MagickExport
void AsynchronousResourceComponentTerminus(
void)
417 if (temporary_resources == (SplayTreeInfo *) NULL)
422 ResetSplayTreeIterator(temporary_resources);
423 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
424 while (path != (
const char *) NULL)
426 (void) ShredFile(path);
427 (void) remove_utf8(path);
428 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
457static void *DestroyTemporaryResources(
void *temporary_resource)
459 (void) ShredFile((
char *) temporary_resource);
460 (void) remove_utf8((
char *) temporary_resource);
461 temporary_resource=DestroyString((
char *) temporary_resource);
462 return((
void *) NULL);
465MagickExport MagickBooleanType GetPathTemplate(
char *path)
480 (void) FormatLocaleString(path,MagickPathExtent,
"magick-" MagickPathTemplate);
481 exception=AcquireExceptionInfo();
482 directory=(
char *) GetImageRegistry(StringRegistryType,
"temporary-path",
484 exception=DestroyExceptionInfo(exception);
485 if (directory == (
char *) NULL)
486 directory=GetEnvironmentValue(
"MAGICK_TEMPORARY_PATH");
487 if (directory == (
char *) NULL)
488 directory=GetEnvironmentValue(
"MAGICK_TMPDIR");
489 if (directory == (
char *) NULL)
490 directory=GetEnvironmentValue(
"TMPDIR");
491#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) || defined(__CYGWIN__)
492 if (directory == (
char *) NULL)
493 directory=GetEnvironmentValue(
"TMP");
494 if (directory == (
char *) NULL)
495 directory=GetEnvironmentValue(
"TEMP");
498 if (directory == (
char *) NULL)
499 directory=GetEnvironmentValue(
"MTMPDIR");
502 if (directory == (
char *) NULL)
503 directory=ConstantString(P_tmpdir);
505 if (directory == (
char *) NULL)
507 value=GetPolicyValue(
"resource:temporary-path");
508 if (value != (
char *) NULL)
510 (void) CloneString(&directory,value);
511 value=DestroyString(value);
513 if (strlen(directory) > (MagickPathExtent-25))
515 directory=DestroyString(directory);
518 status=GetPathAttributes(directory,&attributes);
519 if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
521 directory=DestroyString(directory);
524 if (directory[strlen(directory)-1] == *DirectorySeparator)
525 (void) FormatLocaleString(path,MagickPathExtent,
"%smagick-"
526 MagickPathTemplate,directory);
528 (
void) FormatLocaleString(path,MagickPathExtent,
529 "%s%smagick-" MagickPathTemplate,directory,DirectorySeparator);
530 directory=DestroyString(directory);
531#if defined(MAGICKCORE_WINDOWS_SUPPORT)
540 for (p=(path[1] == *DirectorySeparator ? path+2 : path); *p !=
'\0'; p++)
541 if (*p == *DirectorySeparator)
548MagickExport
int AcquireUniqueFileResource(
char *path)
550#if !defined(O_NOFOLLOW)
554# define TMP_MAX 238328
568 portable_filename[65] =
569 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
577 assert(path != (
char *) NULL);
578 if ((GetLogEventMask() & ResourceEvent) != 0)
579 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"...");
580 if (random_info == (RandomInfo *) NULL)
582 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
583 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
584 LockSemaphoreInfo(resource_semaphore[FileResource]);
585 if (random_info == (RandomInfo *) NULL)
586 random_info=AcquireRandomInfo();
587 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
590 for (i=0; i < (ssize_t) TMP_MAX; i++)
598 (void) GetPathTemplate(path);
599 key=GetRandomKey(random_info,strlen(MagickPathTemplate)-6);
600 p=path+strlen(path)-strlen(MagickPathTemplate);
601 datum=GetStringInfoDatum(key);
602 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
604 c=(int) (datum[j] & 0x3f);
605 *p++=portable_filename[c];
607 key=DestroyStringInfo(key);
608#if defined(MAGICKCORE_HAVE_MKSTEMP)
612#if defined(MAGICKCORE_HAVE_FCHMOD)
613 (void) fchmod(file,0600);
616 setmode(file,O_BINARY);
621 key=GetRandomKey(random_info,strlen(MagickPathTemplate));
622 p=path+strlen(path)-strlen(MagickPathTemplate);
623 datum=GetStringInfoDatum(key);
624 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
626 c=(int) (datum[j] & 0x3f);
627 *p++=portable_filename[c];
629 key=DestroyStringInfo(key);
630 file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
632 if ((file >= 0) || (errno != EEXIST))
635 if ((GetLogEventMask() & ResourceEvent) != 0)
636 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s",path);
639 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
640 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
641 LockSemaphoreInfo(resource_semaphore[FileResource]);
642 if (temporary_resources == (SplayTreeInfo *) NULL)
643 temporary_resources=NewSplayTree(CompareSplayTreeString,
644 DestroyTemporaryResources,(
void *(*)(
void *)) NULL);
645 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
646 (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
647 (
const void *) NULL);
673MagickExport MagickSizeType GetMagickResource(
const ResourceType type)
688 ActivateSemaphoreInfo(&resource_semaphore[type]);
689 LockSemaphoreInfo(resource_semaphore[type]);
698 resource=(MagickSizeType) resource_info.area;
703 resource=(MagickSizeType) resource_info.disk;
708 resource=(MagickSizeType) resource_info.file;
713 resource=(MagickSizeType) resource_info.height;
716 case ListLengthResource:
718 resource=(MagickSizeType) resource_info.list_length;
723 resource=(MagickSizeType) resource_info.map;
728 resource=(MagickSizeType) resource_info.memory;
733 resource=(MagickSizeType) resource_info.time;
738 resource=(MagickSizeType) resource_info.thread;
741 case ThrottleResource:
743 resource=(MagickSizeType) resource_info.throttle;
748 resource=(MagickSizeType) resource_info.width;
762 UnlockSemaphoreInfo(resource_semaphore[type]);
792MagickExport MagickSizeType GetMagickResourceLimit(
const ResourceType type)
800 return(resource_info.area_limit);
802 return(resource_info.height_limit);
803 case ListLengthResource:
804 return(resource_info.list_length_limit);
806 return(resource_info.thread_limit);
807 case ThrottleResource:
808 return(resource_info.throttle_limit);
810 return(resource_info.width_limit);
815 ActivateSemaphoreInfo(&resource_semaphore[type]);
816 LockSemaphoreInfo(resource_semaphore[type]);
821 resource=resource_info.disk_limit;
826 resource=resource_info.file_limit;
831 resource=resource_info.map_limit;
836 resource=resource_info.memory_limit;
841 resource=resource_info.time_limit;
847 UnlockSemaphoreInfo(resource_semaphore[type]);
877static void FormatTimeToLive(
const MagickSizeType ttl,
char *timeString)
889 seconds=ttl % 31536000;
892 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld years",years);
896 seconds=ttl % 2628000;
899 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld months",
904 seconds=ttl % 604800;
907 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld weeks",weeks);
914 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld days",days);
921 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld hours",hours);
928 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld minutes",
932 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld seconds",ttl);
935MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
936 ExceptionInfo *magick_unused(exception))
939 area_limit[MagickFormatExtent],
940 disk_limit[MagickFormatExtent],
941 height_limit[MagickFormatExtent],
942 list_length_limit[MagickFormatExtent],
943 map_limit[MagickFormatExtent],
944 memory_limit[MagickFormatExtent],
945 time_limit[MagickFormatExtent],
946 width_limit[MagickFormatExtent];
948 magick_unreferenced(exception);
950 if (file == (
const FILE *) NULL)
952 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
953 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
954 LockSemaphoreInfo(resource_semaphore[FileResource]);
955 (void) FormatMagickSize(resource_info.width_limit,MagickFalse,
"P",
956 MagickFormatExtent,width_limit);
957 (void) FormatMagickSize(resource_info.height_limit,MagickFalse,
"P",
958 MagickFormatExtent,height_limit);
959 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
"P",
960 MagickFormatExtent,area_limit);
961 (void) CopyMagickString(list_length_limit,
"unlimited",MagickFormatExtent);
962 if (resource_info.list_length_limit != MagickResourceInfinity)
963 (void) FormatMagickSize(resource_info.list_length_limit,MagickTrue,
"B",
964 MagickFormatExtent,list_length_limit);
965 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
"B",
966 MagickFormatExtent,memory_limit);
967 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
"B",
968 MagickFormatExtent,map_limit);
969 (void) CopyMagickString(disk_limit,
"unlimited",MagickFormatExtent);
970 if (resource_info.disk_limit != MagickResourceInfinity)
971 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
"B",
972 MagickFormatExtent,disk_limit);
973 (void) CopyMagickString(time_limit,
"unlimited",MagickFormatExtent);
974 if (resource_info.time_limit != MagickResourceInfinity)
975 FormatTimeToLive(resource_info.time_limit,time_limit);
976 (void) FormatLocaleFile(file,
"Resource limits:\n");
977 (void) FormatLocaleFile(file,
" Width: %s\n",width_limit);
978 (void) FormatLocaleFile(file,
" Height: %s\n",height_limit);
979 (void) FormatLocaleFile(file,
" Area: %s\n",area_limit);
980 (void) FormatLocaleFile(file,
" List length: %s\n",list_length_limit);
981 (void) FormatLocaleFile(file,
" Memory: %s\n",memory_limit);
982 (void) FormatLocaleFile(file,
" Map: %s\n",map_limit);
983 (void) FormatLocaleFile(file,
" Disk: %s\n",disk_limit);
984 (void) FormatLocaleFile(file,
" File: %.20g\n",(
double) ((MagickOffsetType)
985 resource_info.file_limit));
986 (void) FormatLocaleFile(file,
" Thread: %.20g\n",(
double) ((MagickOffsetType)
987 resource_info.thread_limit));
988 (void) FormatLocaleFile(file,
" Throttle: %.20g\n",(
double)
989 ((MagickOffsetType) resource_info.throttle_limit));
990 (void) FormatLocaleFile(file,
" Time: %s\n",time_limit);
992 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1021MagickExport
void RelinquishMagickResource(
const ResourceType type,
1022 const MagickSizeType size)
1039 case MemoryResource:
1043 ActivateSemaphoreInfo(&resource_semaphore[type]);
1044 LockSemaphoreInfo(resource_semaphore[type]);
1054 resource_info.disk-=(MagickOffsetType) size;
1055 current=(MagickSizeType) resource_info.disk;
1056 limit=resource_info.disk_limit;
1057 assert(resource_info.disk >= 0);
1062 resource_info.file-=(MagickOffsetType) size;
1063 current=(MagickSizeType) resource_info.file;
1064 limit=resource_info.file_limit;
1065 assert(resource_info.file >= 0);
1071 resource_info.map-=(MagickOffsetType) size;
1072 current=(MagickSizeType) resource_info.map;
1073 limit=resource_info.map_limit;
1074 assert(resource_info.map >= 0);
1077 case MemoryResource:
1080 resource_info.memory-=(MagickOffsetType) size;
1081 current=(MagickSizeType) resource_info.memory;
1082 limit=resource_info.memory_limit;
1083 assert(resource_info.memory >= 0);
1089 resource_info.time-=(MagickOffsetType) size;
1090 current=(MagickSizeType) resource_info.time;
1091 limit=resource_info.time_limit;
1092 assert(resource_info.time >= 0);
1106 case MemoryResource:
1109 UnlockSemaphoreInfo(resource_semaphore[type]);
1114 if ((GetLogEventMask() & ResourceEvent) != 0)
1117 resource_current[MagickFormatExtent],
1118 resource_limit[MagickFormatExtent],
1119 resource_request[MagickFormatExtent];
1121 (void) FormatMagickSize(size,bi,(bi != MagickFalse) ?
"B" :
1122 (
const char *) NULL,MagickFormatExtent,resource_request);
1123 (void) FormatMagickSize(current,bi,(bi != MagickFalse) ?
"B" :
1124 (
const char *) NULL,MagickFormatExtent,resource_current);
1125 (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ?
"B" :
1126 (
const char *) NULL,MagickFormatExtent,resource_limit);
1127 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
1128 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
1129 resource_request,resource_current,resource_limit);
1155MagickExport MagickBooleanType RelinquishUniqueFileResource(
const char *path)
1158 cache_path[MagickPathExtent];
1163 assert(path != (
const char *) NULL);
1165 if ((GetLogEventMask() & ResourceEvent) != 0)
1166 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s",path);
1167 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1168 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1169 LockSemaphoreInfo(resource_semaphore[FileResource]);
1170 if (temporary_resources != (SplayTreeInfo *) NULL)
1171 status=DeleteNodeFromSplayTree(temporary_resources,(
const void *) path);
1172 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1173 (void) CopyMagickString(cache_path,path,MagickPathExtent);
1174 AppendImageFormat(
"cache",cache_path);
1175 if (access_utf8(cache_path,F_OK) == 0)
1177 status=ShredFile(cache_path);
1178 status|=(MagickStatusType) remove_utf8(cache_path);
1180 if (status == MagickFalse)
1182 status=ShredFile(path);
1183 status|=(MagickStatusType) remove_utf8(path);
1185 return(status == 0 ? MagickFalse : MagickTrue);
1207MagickPrivate MagickBooleanType ResourceComponentGenesis(
void)
1225 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1227 resource_semaphore[i]=AcquireSemaphoreInfo();
1228 (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
1229 limit=GetEnvironmentValue(
"MAGICK_WIDTH_LIMIT");
1230 if (limit != (
char *) NULL)
1232 (void) SetMagickResourceLimit(WidthResource,StringToMagickSizeType(limit,
1234 limit=DestroyString(limit);
1236 (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
1237 limit=GetEnvironmentValue(
"MAGICK_HEIGHT_LIMIT");
1238 if (limit != (
char *) NULL)
1240 (void) SetMagickResourceLimit(HeightResource,StringToMagickSizeType(
1242 limit=DestroyString(limit);
1244 pagesize=GetMagickPageSize();
1246#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1247 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1248#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1252 memory=(MagickSizeType) ((MagickOffsetType) pages*pagesize);
1253 if ((pagesize <= 0) || (pages <= 0))
1254 memory=2048UL*1024UL*1024UL;
1255#if defined(MAGICKCORE_PixelCacheThreshold)
1256 memory=StringToMagickSizeType(MAGICKCORE_PixelCacheThreshold,100.0);
1258 (void) SetMagickResourceLimit(AreaResource,4*memory);
1259 limit=GetEnvironmentValue(
"MAGICK_AREA_LIMIT");
1260 if (limit != (
char *) NULL)
1262 (void) SetMagickResourceLimit(AreaResource,StringToMagickSizeType(limit,
1264 limit=DestroyString(limit);
1266 (void) SetMagickResourceLimit(MemoryResource,memory);
1267 limit=GetEnvironmentValue(
"MAGICK_MEMORY_LIMIT");
1268 if (limit != (
char *) NULL)
1270 (void) SetMagickResourceLimit(MemoryResource,StringToMagickSizeType(
1272 limit=DestroyString(limit);
1274 (void) SetMagickResourceLimit(MapResource,2*memory);
1275 limit=GetEnvironmentValue(
"MAGICK_MAP_LIMIT");
1276 if (limit != (
char *) NULL)
1278 (void) SetMagickResourceLimit(MapResource,StringToMagickSizeType(limit,
1280 limit=DestroyString(limit);
1282 (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
1283 limit=GetEnvironmentValue(
"MAGICK_DISK_LIMIT");
1284 if (limit != (
char *) NULL)
1286 (void) SetMagickResourceLimit(DiskResource,StringToMagickSizeType(limit,
1288 limit=DestroyString(limit);
1291#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1292 files=(ssize_t) sysconf(_SC_OPEN_MAX);
1294#if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1300 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1301 files=(ssize_t) resources.rlim_cur;
1304#if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1306 files=(ssize_t) getdtablesize();
1310 (void) SetMagickResourceLimit(FileResource,MagickMax((
size_t)
1312 limit=GetEnvironmentValue(
"MAGICK_FILE_LIMIT");
1313 if (limit != (
char *) NULL)
1315 (void) SetMagickResourceLimit(FileResource,StringToMagickSizeType(limit,
1317 limit=DestroyString(limit);
1319 number_threads=(ssize_t) GetOpenMPMaximumThreads();
1320 if (number_threads > 1)
1322 (void) SetMagickResourceLimit(ThreadResource,(
size_t) number_threads);
1323 limit=GetEnvironmentValue(
"MAGICK_THREAD_LIMIT");
1324 if (limit != (
char *) NULL)
1326 (void) SetMagickResourceLimit(ThreadResource,StringToMagickSizeType(
1328 limit=DestroyString(limit);
1330 (void) SetMagickResourceLimit(ThrottleResource,0);
1331 limit=GetEnvironmentValue(
"MAGICK_THROTTLE_LIMIT");
1332 if (limit != (
char *) NULL)
1334 (void) SetMagickResourceLimit(ThrottleResource,StringToMagickSizeType(
1336 limit=DestroyString(limit);
1338 (void) SetMagickResourceLimit(TimeResource,MagickResourceInfinity);
1339 limit=GetEnvironmentValue(
"MAGICK_TIME_LIMIT");
1340 if (limit != (
char *) NULL)
1342 (void) SetMagickResourceLimit(TimeResource,(MagickSizeType)
1343 ParseMagickTimeToLive(limit));
1344 limit=DestroyString(limit);
1346 (void) SetMagickResourceLimit(ListLengthResource,MagickResourceInfinity);
1347 limit=GetEnvironmentValue(
"MAGICK_LIST_LENGTH_LIMIT");
1348 if (limit != (
char *) NULL)
1350 (void) SetMagickResourceLimit(ListLengthResource,
1351 StringToMagickSizeType(limit,100.0));
1352 limit=DestroyString(limit);
1375MagickPrivate
void ResourceComponentTerminus(
void)
1380 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1382 resource_semaphore[i]=AcquireSemaphoreInfo();
1383 LockSemaphoreInfo(resource_semaphore[FileResource]);
1384 if (temporary_resources != (SplayTreeInfo *) NULL)
1385 temporary_resources=DestroySplayTree(temporary_resources);
1386 if (random_info != (RandomInfo *) NULL)
1387 random_info=DestroyRandomInfo(random_info);
1388 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1389 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1390 RelinquishSemaphoreInfo(&resource_semaphore[i]);
1418MagickExport MagickBooleanType SetMagickResourceLimit(
const ResourceType type,
1419 const MagickSizeType limit)
1428 value=(
char *) NULL;
1434 case MemoryResource:
1438 ActivateSemaphoreInfo(&resource_semaphore[type]);
1439 LockSemaphoreInfo(resource_semaphore[type]);
1448 value=GetPolicyValue(
"resource:area");
1449 if (value == (
char *) NULL)
1450 resource_info.area_limit=limit;
1452 resource_info.area_limit=MagickMin(limit,StringToMagickSizeType(value,
1458 value=GetPolicyValue(
"resource:disk");
1459 if (value == (
char *) NULL)
1460 resource_info.disk_limit=limit;
1462 resource_info.disk_limit=MagickMin(limit,StringToMagickSizeType(value,
1468 value=GetPolicyValue(
"resource:file");
1469 if (value == (
char *) NULL)
1470 resource_info.file_limit=limit;
1472 resource_info.file_limit=MagickMin(limit,StringToMagickSizeType(value,
1476 case HeightResource:
1478 value=GetPolicyValue(
"resource:height");
1479 if (value == (
char *) NULL)
1480 resource_info.height_limit=limit;
1482 resource_info.height_limit=MagickMin(limit,StringToMagickSizeType(
1484 resource_info.height_limit=MagickMin(resource_info.height_limit,
1485 (MagickSizeType) MAGICK_SSIZE_MAX);
1488 case ListLengthResource:
1490 value=GetPolicyValue(
"resource:list-length");
1491 if (value == (
char *) NULL)
1492 resource_info.list_length_limit=limit;
1494 resource_info.list_length_limit=MagickMin(limit,
1495 StringToMagickSizeType(value,100.0));
1500 value=GetPolicyValue(
"resource:map");
1501 if (value == (
char *) NULL)
1502 resource_info.map_limit=limit;
1504 resource_info.map_limit=MagickMin(limit,StringToMagickSizeType(
1508 case MemoryResource:
1510 value=GetPolicyValue(
"resource:memory");
1511 if (value == (
char *) NULL)
1512 resource_info.memory_limit=limit;
1514 resource_info.memory_limit=MagickMin(limit,StringToMagickSizeType(
1518 case ThreadResource:
1520 value=GetPolicyValue(
"resource:thread");
1521 if (value == (
char *) NULL)
1522 resource_info.thread_limit=limit;
1524 resource_info.thread_limit=MagickMin(limit,StringToMagickSizeType(
1526 if (resource_info.thread_limit > GetOpenMPMaximumThreads())
1527 resource_info.thread_limit=GetOpenMPMaximumThreads();
1529 if (resource_info.thread_limit == 0)
1530 resource_info.thread_limit=1;
1533 case ThrottleResource:
1535 value=GetPolicyValue(
"resource:throttle");
1536 if (value == (
char *) NULL)
1537 resource_info.throttle_limit=limit;
1539 resource_info.throttle_limit=MagickMax(limit,StringToMagickSizeType(
1545 value=GetPolicyValue(
"resource:time");
1546 if (value == (
char *) NULL)
1547 resource_info.time_limit=limit;
1549 resource_info.time_limit=MagickMin(limit,(MagickSizeType)
1550 ParseMagickTimeToLive(value));
1555 value=GetPolicyValue(
"resource:width");
1556 if (value == (
char *) NULL)
1557 resource_info.width_limit=limit;
1559 resource_info.width_limit=MagickMin(limit,StringToMagickSizeType(value,
1561 resource_info.width_limit=MagickMin(resource_info.width_limit,
1562 (MagickSizeType) MAGICK_SSIZE_MAX);
1576 case MemoryResource:
1579 UnlockSemaphoreInfo(resource_semaphore[type]);
1584 if (value != (
char *) NULL)
1585 value=DestroyString(value);