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))
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 MagickULLConstant(0),
143 *resource_semaphore[] = {
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 == 0) || (resource_info.time < (MagickOffsetType) limit))
338 resource_info.time-=request;
340 current=resource_info.time;
346 resource_info.width=request;
347 limit=resource_info.width_limit;
348 if ((limit == MagickResourceInfinity) || (size < limit))
366 UnlockSemaphoreInfo(resource_semaphore[type]);
371 if ((GetLogEventMask() & ResourceEvent) != 0)
374 resource_current[MagickFormatExtent],
375 resource_limit[MagickFormatExtent],
376 resource_request[MagickFormatExtent];
378 (void) FormatMagickSize(size,bi,(bi != MagickFalse) ?
"B" :
379 (
const char *) NULL,MagickFormatExtent,resource_request);
380 (void) FormatMagickSize((MagickSizeType) current,bi,(bi != MagickFalse) ?
381 "B" : (
const char *) NULL,MagickFormatExtent,resource_current);
382 (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ?
"B" :
383 (
const char *) NULL,MagickFormatExtent,resource_limit);
384 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
385 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
386 resource_request,resource_current,resource_limit);
411MagickExport
void AsynchronousResourceComponentTerminus(
void)
421 ResetSplayTreeIterator(temporary_resources);
422 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
423 while (path != (
const char *) NULL)
425 (void) ShredFile(path);
426 (void) remove_utf8(path);
427 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
456static void *DestroyTemporaryResources(
void *temporary_resource)
458 (void) ShredFile((
char *) temporary_resource);
459 (void) remove_utf8((
char *) temporary_resource);
460 temporary_resource=DestroyString((
char *) temporary_resource);
461 return((
void *) NULL);
464MagickExport MagickBooleanType GetPathTemplate(
char *path)
479 (void) FormatLocaleString(path,MagickPathExtent,
"magick-" MagickPathTemplate);
480 exception=AcquireExceptionInfo();
481 directory=(
char *) GetImageRegistry(StringRegistryType,
"temporary-path",
483 exception=DestroyExceptionInfo(exception);
484 if (directory == (
char *) NULL)
485 directory=GetEnvironmentValue(
"MAGICK_TEMPORARY_PATH");
486 if (directory == (
char *) NULL)
487 directory=GetEnvironmentValue(
"MAGICK_TMPDIR");
488 if (directory == (
char *) NULL)
489 directory=GetEnvironmentValue(
"TMPDIR");
490#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) || defined(__CYGWIN__)
491 if (directory == (
char *) NULL)
492 directory=GetEnvironmentValue(
"TMP");
493 if (directory == (
char *) NULL)
494 directory=GetEnvironmentValue(
"TEMP");
497 if (directory == (
char *) NULL)
498 directory=GetEnvironmentValue(
"MTMPDIR");
501 if (directory == (
char *) NULL)
502 directory=ConstantString(P_tmpdir);
504 if (directory == (
char *) NULL)
506 value=GetPolicyValue(
"resource:temporary-path");
507 if (value != (
char *) NULL)
509 (void) CloneString(&directory,value);
510 value=DestroyString(value);
512 if (strlen(directory) > (MagickPathExtent-25))
514 directory=DestroyString(directory);
517 status=GetPathAttributes(directory,&attributes);
518 if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
520 directory=DestroyString(directory);
523 if (directory[strlen(directory)-1] == *DirectorySeparator)
524 (void) FormatLocaleString(path,MagickPathExtent,
"%smagick-"
525 MagickPathTemplate,directory);
527 (
void) FormatLocaleString(path,MagickPathExtent,
528 "%s%smagick-" MagickPathTemplate,directory,DirectorySeparator);
529 directory=DestroyString(directory);
530#if defined(MAGICKCORE_WINDOWS_SUPPORT)
539 for (p=(path[1] == *DirectorySeparator ? path+2 : path); *p !=
'\0'; p++)
540 if (*p == *DirectorySeparator)
547MagickExport
int AcquireUniqueFileResource(
char *path)
549#if !defined(O_NOFOLLOW)
553# define TMP_MAX 238328
567 portable_filename[65] =
568 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
576 assert(path != (
char *) NULL);
577 if ((GetLogEventMask() & ResourceEvent) != 0)
578 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"...");
581 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
582 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
583 LockSemaphoreInfo(resource_semaphore[FileResource]);
585 random_info=AcquireRandomInfo();
586 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
589 for (i=0; i < (ssize_t) TMP_MAX; i++)
597 (void) GetPathTemplate(path);
598 key=GetRandomKey(random_info,strlen(MagickPathTemplate)-6);
599 p=path+strlen(path)-strlen(MagickPathTemplate);
600 datum=GetStringInfoDatum(key);
601 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
603 c=(int) (datum[j] & 0x3f);
604 *p++=portable_filename[c];
606 key=DestroyStringInfo(key);
607#if defined(MAGICKCORE_HAVE_MKSTEMP)
611#if defined(MAGICKCORE_HAVE_FCHMOD)
612 (void) fchmod(file,0600);
615 setmode(file,O_BINARY);
620 key=GetRandomKey(random_info,strlen(MagickPathTemplate));
621 p=path+strlen(path)-strlen(MagickPathTemplate);
622 datum=GetStringInfoDatum(key);
623 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
625 c=(int) (datum[j] & 0x3f);
626 *p++=portable_filename[c];
628 key=DestroyStringInfo(key);
629 file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
631 if ((file >= 0) || (errno != EEXIST))
634 if ((GetLogEventMask() & ResourceEvent) != 0)
635 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s",path);
638 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
639 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
640 LockSemaphoreInfo(resource_semaphore[FileResource]);
642 temporary_resources=NewSplayTree(CompareSplayTreeString,
643 DestroyTemporaryResources,(
void *(*)(
void *)) NULL);
644 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
645 (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
646 (
const void *) NULL);
672MagickExport MagickSizeType GetMagickResource(
const ResourceType type)
687 ActivateSemaphoreInfo(&resource_semaphore[type]);
688 LockSemaphoreInfo(resource_semaphore[type]);
697 resource=(MagickSizeType) resource_info.area;
702 resource=(MagickSizeType) resource_info.disk;
707 resource=(MagickSizeType) resource_info.file;
712 resource=(MagickSizeType) resource_info.height;
715 case ListLengthResource:
717 resource=(MagickSizeType) resource_info.list_length;
722 resource=(MagickSizeType) resource_info.map;
727 resource=(MagickSizeType) resource_info.memory;
732 resource=(MagickSizeType) resource_info.time;
737 resource=(MagickSizeType) resource_info.thread;
740 case ThrottleResource:
742 resource=(MagickSizeType) resource_info.throttle;
747 resource=(MagickSizeType) resource_info.width;
761 UnlockSemaphoreInfo(resource_semaphore[type]);
791MagickExport MagickSizeType GetMagickResourceLimit(
const ResourceType type)
799 return(resource_info.area_limit);
801 return(resource_info.height_limit);
802 case ListLengthResource:
803 return(resource_info.list_length_limit);
805 return(resource_info.thread_limit);
806 case ThrottleResource:
807 return(resource_info.throttle_limit);
809 return(resource_info.width_limit);
814 ActivateSemaphoreInfo(&resource_semaphore[type]);
815 LockSemaphoreInfo(resource_semaphore[type]);
820 resource=resource_info.disk_limit;
825 resource=resource_info.file_limit;
830 resource=resource_info.map_limit;
835 resource=resource_info.memory_limit;
840 resource=resource_info.time_limit;
846 UnlockSemaphoreInfo(resource_semaphore[type]);
876static void FormatTimeToLive(
const MagickSizeType ttl,
char *timeString)
888 seconds=ttl % 31536000;
891 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld years",years);
895 seconds=ttl % 2628000;
898 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld months",
903 seconds=ttl % 604800;
906 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld weeks",weeks);
913 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld days",days);
920 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld hours",hours);
927 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld minutes",
931 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld seconds",ttl);
934MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
938 area_limit[MagickFormatExtent],
939 disk_limit[MagickFormatExtent],
940 height_limit[MagickFormatExtent],
941 list_length_limit[MagickFormatExtent],
942 map_limit[MagickFormatExtent],
943 memory_limit[MagickFormatExtent],
944 time_limit[MagickFormatExtent],
945 width_limit[MagickFormatExtent];
947 magick_unreferenced(exception);
949 if (file == (
const FILE *) NULL)
951 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
952 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
953 LockSemaphoreInfo(resource_semaphore[FileResource]);
954 (void) FormatMagickSize(resource_info.width_limit,MagickFalse,
"P",
955 MagickFormatExtent,width_limit);
956 (void) FormatMagickSize(resource_info.height_limit,MagickFalse,
"P",
957 MagickFormatExtent,height_limit);
958 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
"P",
959 MagickFormatExtent,area_limit);
960 (void) CopyMagickString(list_length_limit,
"unlimited",MagickFormatExtent);
961 if (resource_info.list_length_limit != MagickResourceInfinity)
962 (void) FormatMagickSize(resource_info.list_length_limit,MagickTrue,
"B",
963 MagickFormatExtent,list_length_limit);
964 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
"B",
965 MagickFormatExtent,memory_limit);
966 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
"B",
967 MagickFormatExtent,map_limit);
968 (void) CopyMagickString(disk_limit,
"unlimited",MagickFormatExtent);
969 if (resource_info.disk_limit != MagickResourceInfinity)
970 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
"B",
971 MagickFormatExtent,disk_limit);
972 (void) CopyMagickString(time_limit,
"unlimited",MagickFormatExtent);
973 if (resource_info.time_limit != 0)
974 FormatTimeToLive(resource_info.time_limit,time_limit);
975 (void) FormatLocaleFile(file,
"Resource limits:\n");
976 (void) FormatLocaleFile(file,
" Width: %s\n",width_limit);
977 (void) FormatLocaleFile(file,
" Height: %s\n",height_limit);
978 (void) FormatLocaleFile(file,
" Area: %s\n",area_limit);
979 (void) FormatLocaleFile(file,
" List length: %s\n",list_length_limit);
980 (void) FormatLocaleFile(file,
" Memory: %s\n",memory_limit);
981 (void) FormatLocaleFile(file,
" Map: %s\n",map_limit);
982 (void) FormatLocaleFile(file,
" Disk: %s\n",disk_limit);
983 (void) FormatLocaleFile(file,
" File: %.20g\n",(
double) ((MagickOffsetType)
984 resource_info.file_limit));
985 (void) FormatLocaleFile(file,
" Thread: %.20g\n",(
double) ((MagickOffsetType)
986 resource_info.thread_limit));
987 (void) FormatLocaleFile(file,
" Throttle: %.20g\n",(
double)
988 ((MagickOffsetType) resource_info.throttle_limit));
989 (void) FormatLocaleFile(file,
" Time: %s\n",time_limit);
991 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1020MagickExport
void RelinquishMagickResource(
const ResourceType type,
1021 const MagickSizeType size)
1038 case MemoryResource:
1042 ActivateSemaphoreInfo(&resource_semaphore[type]);
1043 LockSemaphoreInfo(resource_semaphore[type]);
1053 resource_info.disk-=(MagickOffsetType) size;
1054 current=(MagickSizeType) resource_info.disk;
1055 limit=resource_info.disk_limit;
1056 assert(resource_info.disk >= 0);
1061 resource_info.file-=(MagickOffsetType) size;
1062 current=(MagickSizeType) resource_info.file;
1063 limit=resource_info.file_limit;
1064 assert(resource_info.file >= 0);
1070 resource_info.map-=(MagickOffsetType) size;
1071 current=(MagickSizeType) resource_info.map;
1072 limit=resource_info.map_limit;
1073 assert(resource_info.map >= 0);
1076 case MemoryResource:
1079 resource_info.memory-=(MagickOffsetType) size;
1080 current=(MagickSizeType) resource_info.memory;
1081 limit=resource_info.memory_limit;
1082 assert(resource_info.memory >= 0);
1088 resource_info.time-=(MagickOffsetType) size;
1089 current=(MagickSizeType) resource_info.time;
1090 limit=resource_info.time_limit;
1091 assert(resource_info.time >= 0);
1105 case MemoryResource:
1108 UnlockSemaphoreInfo(resource_semaphore[type]);
1113 if ((GetLogEventMask() & ResourceEvent) != 0)
1116 resource_current[MagickFormatExtent],
1117 resource_limit[MagickFormatExtent],
1118 resource_request[MagickFormatExtent];
1120 (void) FormatMagickSize(size,bi,(bi != MagickFalse) ?
"B" :
1121 (
const char *) NULL,MagickFormatExtent,resource_request);
1122 (void) FormatMagickSize(current,bi,(bi != MagickFalse) ?
"B" :
1123 (
const char *) NULL,MagickFormatExtent,resource_current);
1124 (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ?
"B" :
1125 (
const char *) NULL,MagickFormatExtent,resource_limit);
1126 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
1127 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
1128 resource_request,resource_current,resource_limit);
1154MagickExport MagickBooleanType RelinquishUniqueFileResource(
const char *path)
1157 cache_path[MagickPathExtent];
1162 assert(path != (
const char *) NULL);
1164 if ((GetLogEventMask() & ResourceEvent) != 0)
1165 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s",path);
1166 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1167 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1168 LockSemaphoreInfo(resource_semaphore[FileResource]);
1170 status=DeleteNodeFromSplayTree(temporary_resources,(
const void *) path);
1171 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1172 (void) CopyMagickString(cache_path,path,MagickPathExtent);
1173 AppendImageFormat(
"cache",cache_path);
1174 if (access_utf8(cache_path,F_OK) == 0)
1176 status=ShredFile(cache_path);
1177 status|=(MagickStatusType) remove_utf8(cache_path);
1179 if (status == MagickFalse)
1181 status=ShredFile(path);
1182 status|=(MagickStatusType) remove_utf8(path);
1184 return(status == 0 ? MagickFalse : MagickTrue);
1206MagickPrivate MagickBooleanType ResourceComponentGenesis(
void)
1224 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1226 resource_semaphore[i]=AcquireSemaphoreInfo();
1227 (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
1228 limit=GetEnvironmentValue(
"MAGICK_WIDTH_LIMIT");
1229 if (limit != (
char *) NULL)
1231 (void) SetMagickResourceLimit(WidthResource,StringToMagickSizeType(limit,
1233 limit=DestroyString(limit);
1235 (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
1236 limit=GetEnvironmentValue(
"MAGICK_HEIGHT_LIMIT");
1237 if (limit != (
char *) NULL)
1239 (void) SetMagickResourceLimit(HeightResource,StringToMagickSizeType(
1241 limit=DestroyString(limit);
1243 pagesize=GetMagickPageSize();
1245#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1246 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1247#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1251 memory=(MagickSizeType) ((MagickOffsetType) pages*pagesize);
1252 if ((pagesize <= 0) || (pages <= 0))
1253 memory=2048UL*1024UL*1024UL;
1254#if defined(MAGICKCORE_PixelCacheThreshold)
1255 memory=MAGICKCORE_PixelCacheThreshold;
1257 (void) SetMagickResourceLimit(AreaResource,4*memory);
1258 limit=GetEnvironmentValue(
"MAGICK_AREA_LIMIT");
1259 if (limit != (
char *) NULL)
1261 (void) SetMagickResourceLimit(AreaResource,StringToMagickSizeType(limit,
1263 limit=DestroyString(limit);
1265 (void) SetMagickResourceLimit(MemoryResource,memory);
1266 limit=GetEnvironmentValue(
"MAGICK_MEMORY_LIMIT");
1267 if (limit != (
char *) NULL)
1269 (void) SetMagickResourceLimit(MemoryResource,StringToMagickSizeType(
1271 limit=DestroyString(limit);
1273 (void) SetMagickResourceLimit(MapResource,2*memory);
1274 limit=GetEnvironmentValue(
"MAGICK_MAP_LIMIT");
1275 if (limit != (
char *) NULL)
1277 (void) SetMagickResourceLimit(MapResource,StringToMagickSizeType(limit,
1279 limit=DestroyString(limit);
1281 (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
1282 limit=GetEnvironmentValue(
"MAGICK_DISK_LIMIT");
1283 if (limit != (
char *) NULL)
1285 (void) SetMagickResourceLimit(DiskResource,StringToMagickSizeType(limit,
1287 limit=DestroyString(limit);
1290#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1291 files=(ssize_t) sysconf(_SC_OPEN_MAX);
1293#if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1299 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1300 files=(ssize_t) resources.rlim_cur;
1303#if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1305 files=(ssize_t) getdtablesize();
1309 (void) SetMagickResourceLimit(FileResource,MagickMax((
size_t)
1311 limit=GetEnvironmentValue(
"MAGICK_FILE_LIMIT");
1312 if (limit != (
char *) NULL)
1314 (void) SetMagickResourceLimit(FileResource,StringToMagickSizeType(limit,
1316 limit=DestroyString(limit);
1318 number_threads=(ssize_t) GetOpenMPMaximumThreads();
1319 if (number_threads > 1)
1321 (void) SetMagickResourceLimit(ThreadResource,(
size_t) number_threads);
1322 limit=GetEnvironmentValue(
"MAGICK_THREAD_LIMIT");
1323 if (limit != (
char *) NULL)
1325 (void) SetMagickResourceLimit(ThreadResource,StringToMagickSizeType(
1327 limit=DestroyString(limit);
1329 (void) SetMagickResourceLimit(ThrottleResource,0);
1330 limit=GetEnvironmentValue(
"MAGICK_THROTTLE_LIMIT");
1331 if (limit != (
char *) NULL)
1333 (void) SetMagickResourceLimit(ThrottleResource,StringToMagickSizeType(
1335 limit=DestroyString(limit);
1337 (void) SetMagickResourceLimit(TimeResource,0);
1338 limit=GetEnvironmentValue(
"MAGICK_TIME_LIMIT");
1339 if (limit != (
char *) NULL)
1341 (void) SetMagickResourceLimit(TimeResource,(MagickSizeType)
1342 ParseMagickTimeToLive(limit));
1343 limit=DestroyString(limit);
1345 (void) SetMagickResourceLimit(ListLengthResource,MagickResourceInfinity);
1346 limit=GetEnvironmentValue(
"MAGICK_LIST_LENGTH_LIMIT");
1347 if (limit != (
char *) NULL)
1349 (void) SetMagickResourceLimit(ListLengthResource,
1350 StringToMagickSizeType(limit,100.0));
1351 limit=DestroyString(limit);
1374MagickPrivate
void ResourceComponentTerminus(
void)
1379 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1381 resource_semaphore[i]=AcquireSemaphoreInfo();
1382 LockSemaphoreInfo(resource_semaphore[FileResource]);
1384 temporary_resources=DestroySplayTree(temporary_resources);
1386 random_info=DestroyRandomInfo(random_info);
1387 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1388 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1389 RelinquishSemaphoreInfo(&resource_semaphore[i]);
1417MagickExport MagickBooleanType SetMagickResourceLimit(
const ResourceType type,
1418 const MagickSizeType limit)
1427 value=(
char *) NULL;
1433 case MemoryResource:
1437 ActivateSemaphoreInfo(&resource_semaphore[type]);
1438 LockSemaphoreInfo(resource_semaphore[type]);
1447 value=GetPolicyValue(
"resource:area");
1448 if (value == (
char *) NULL)
1449 resource_info.area_limit=limit;
1451 resource_info.area_limit=MagickMin(limit,StringToMagickSizeType(value,
1457 value=GetPolicyValue(
"resource:disk");
1458 if (value == (
char *) NULL)
1459 resource_info.disk_limit=limit;
1461 resource_info.disk_limit=MagickMin(limit,StringToMagickSizeType(value,
1467 value=GetPolicyValue(
"resource:file");
1468 if (value == (
char *) NULL)
1469 resource_info.file_limit=limit;
1471 resource_info.file_limit=MagickMin(limit,StringToMagickSizeType(value,
1475 case HeightResource:
1477 value=GetPolicyValue(
"resource:height");
1478 if (value == (
char *) NULL)
1479 resource_info.height_limit=limit;
1481 resource_info.height_limit=MagickMin(limit,StringToMagickSizeType(
1483 resource_info.height_limit=MagickMin(resource_info.height_limit,
1484 (MagickSizeType) MAGICK_SSIZE_MAX);
1487 case ListLengthResource:
1489 value=GetPolicyValue(
"resource:list-length");
1490 if (value == (
char *) NULL)
1491 resource_info.list_length_limit=limit;
1493 resource_info.list_length_limit=MagickMin(limit,
1494 StringToMagickSizeType(value,100.0));
1499 value=GetPolicyValue(
"resource:map");
1500 if (value == (
char *) NULL)
1501 resource_info.map_limit=limit;
1503 resource_info.map_limit=MagickMin(limit,StringToMagickSizeType(
1507 case MemoryResource:
1509 value=GetPolicyValue(
"resource:memory");
1510 if (value == (
char *) NULL)
1511 resource_info.memory_limit=limit;
1513 resource_info.memory_limit=MagickMin(limit,StringToMagickSizeType(
1517 case ThreadResource:
1519 value=GetPolicyValue(
"resource:thread");
1520 if (value == (
char *) NULL)
1521 resource_info.thread_limit=limit;
1523 resource_info.thread_limit=MagickMin(limit,StringToMagickSizeType(
1525 if (resource_info.thread_limit > GetOpenMPMaximumThreads())
1526 resource_info.thread_limit=GetOpenMPMaximumThreads();
1528 if (resource_info.thread_limit == 0)
1529 resource_info.thread_limit=1;
1532 case ThrottleResource:
1534 value=GetPolicyValue(
"resource:throttle");
1535 if (value == (
char *) NULL)
1536 resource_info.throttle_limit=limit;
1538 resource_info.throttle_limit=MagickMax(limit,StringToMagickSizeType(
1544 value=GetPolicyValue(
"resource:time");
1545 if (value == (
char *) NULL)
1546 resource_info.time_limit=limit;
1548 resource_info.time_limit=MagickMin(limit,(MagickSizeType)
1549 ParseMagickTimeToLive(value));
1554 value=GetPolicyValue(
"resource:width");
1555 if (value == (
char *) NULL)
1556 resource_info.width_limit=limit;
1558 resource_info.width_limit=MagickMin(limit,StringToMagickSizeType(value,
1560 resource_info.width_limit=MagickMin(resource_info.width_limit,
1561 (MagickSizeType) MAGICK_SSIZE_MAX);
1575 case MemoryResource:
1578 UnlockSemaphoreInfo(resource_semaphore[type]);
1583 if (value != (
char *) NULL)
1584 value=DestroyString(value);