42#include "magick/studio.h"
43#include "magick/cache.h"
44#include "magick/cache-private.h"
45#include "magick/configure.h"
46#include "magick/exception.h"
47#include "magick/exception-private.h"
48#include "magick/hashmap.h"
49#include "magick/log.h"
50#include "magick/image.h"
51#include "magick/image-private.h"
52#include "magick/memory_.h"
53#include "magick/nt-base-private.h"
54#include "magick/option.h"
55#include "magick/policy.h"
56#include "magick/random_.h"
57#include "magick/registry.h"
58#include "magick/resource_.h"
59#include "magick/semaphore.h"
60#include "magick/signature-private.h"
61#include "magick/string_.h"
62#include "magick/string-private.h"
63#include "magick/splay-tree.h"
64#include "magick/thread-private.h"
65#include "magick/timer-private.h"
66#include "magick/token.h"
67#include "magick/timer-private.h"
68#include "magick/utility.h"
69#include "magick/utility-private.h"
74#define MagickPathTemplate "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
75#define NumberOfResourceTypes \
76 (sizeof(resource_semaphore)/sizeof(*resource_semaphore))
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 MagickULLConstant(0),
130 (MagickSizeType) (MAGICK_SSIZE_MAX/
sizeof(
PixelPacket)/5),
131 (MagickSizeType) (MAGICK_SSIZE_MAX/
sizeof(
PixelPacket)/5),
132 MagickResourceInfinity,
133 MagickULLConstant(3072)*1024*1024,
134 MagickULLConstant(1536)*1024*1024,
135 MagickULLConstant(3072)*1024*1024,
136 MagickResourceInfinity,
137 MagickULLConstant(768),
138 MagickULLConstant(1),
139 MagickULLConstant(0),
140 MagickULLConstant(0),
144 *resource_semaphore[] = {
189MagickExport MagickBooleanType AcquireMagickResource(
const ResourceType type,
190 const MagickSizeType size)
193 resource_current[MaxTextExtent] =
"",
194 resource_limit[MaxTextExtent] =
"",
195 resource_request[MaxTextExtent] =
"";
207 request=(MagickOffsetType) size;
211 logging=(GetLogEventMask() & ResourceEvent) != 0 ? MagickTrue : MagickFalse;
221 ActivateSemaphoreInfo(&resource_semaphore[type]);
222 LockSemaphoreInfo(resource_semaphore[type]);
231 resource_info.area=(MagickOffsetType) size;
232 limit=resource_info.area_limit;
233 if ((limit == MagickResourceInfinity) || (size < limit))
235 if (logging != MagickFalse)
237 (void) FormatMagickSize(size,MagickFalse,resource_request);
238 (void) FormatMagickSize(size,MagickFalse,resource_current);
239 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
245 limit=resource_info.disk_limit;
246 if (((MagickSizeType) resource_info.disk+request) >
247 (MagickSizeType) resource_info.disk)
249 resource_info.disk+=request;
250 if ((limit == MagickResourceInfinity) ||
251 (resource_info.disk < (MagickOffsetType) limit))
254 resource_info.disk-=request;
256 if (logging != MagickFalse)
258 (void) FormatMagickSize(size,MagickTrue,resource_request);
259 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
260 MagickTrue,resource_current);
261 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
267 limit=resource_info.file_limit;
268 if (((MagickSizeType) resource_info.file+request) >
269 (MagickSizeType) resource_info.file)
271 resource_info.file+=request;
272 if ((limit == MagickResourceInfinity) ||
273 (resource_info.file < (MagickOffsetType) limit))
276 if (logging != MagickFalse)
278 (void) FormatMagickSize(size,MagickFalse,resource_request);
279 (void) FormatMagickSize((MagickSizeType) resource_info.file,
280 MagickFalse,resource_current);
281 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
287 resource_info.height=(MagickOffsetType) size;
288 limit=resource_info.height_limit;
289 if ((limit == MagickResourceInfinity) || (size < limit))
291 if (logging != MagickFalse)
293 (void) FormatMagickSize(size,MagickFalse,resource_request);
294 (void) FormatMagickSize(size,MagickFalse,resource_current);
295 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
299 case ListLengthResource:
301 resource_info.list_length=(MagickOffsetType) size;
302 limit=resource_info.list_length_limit;
303 if ((limit == MagickResourceInfinity) || (size < limit))
305 if (logging != MagickFalse)
307 (void) FormatMagickSize(size,MagickFalse,resource_request);
308 (void) FormatMagickSize(size,MagickFalse,resource_current);
309 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
315 limit=resource_info.map_limit;
316 if (((MagickSizeType) resource_info.map+request) >
317 (MagickSizeType) resource_info.map)
319 resource_info.map+=request;
320 if ((limit == MagickResourceInfinity) ||
321 (resource_info.map < (MagickOffsetType) limit))
324 resource_info.map-=request;
326 if (logging != MagickFalse)
328 (void) FormatMagickSize(size,MagickTrue,resource_request);
329 (void) FormatMagickSize((MagickSizeType) resource_info.map,
330 MagickTrue,resource_current);
331 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
337 limit=resource_info.memory_limit;
338 if (((MagickSizeType) resource_info.memory+request) >
339 (MagickSizeType) resource_info.memory)
341 resource_info.memory+=request;
342 if ((limit == MagickResourceInfinity) ||
343 (resource_info.memory < (MagickOffsetType) limit))
346 resource_info.memory-=request;
348 if (logging != MagickFalse)
350 (void) FormatMagickSize(size,MagickTrue,resource_request);
351 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
352 MagickTrue,resource_current);
353 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
359 limit=resource_info.thread_limit;
360 if ((limit == MagickResourceInfinity) ||
361 (resource_info.thread < (MagickOffsetType) limit))
363 if (logging != MagickFalse)
365 (void) FormatMagickSize(size,MagickFalse,resource_request);
366 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
367 MagickFalse,resource_current);
368 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
372 case ThrottleResource:
374 limit=resource_info.throttle_limit;
375 if ((limit == MagickResourceInfinity) ||
376 (resource_info.throttle < (MagickOffsetType) limit))
378 if (logging != MagickFalse)
380 (void) FormatMagickSize(size,MagickFalse,resource_request);
381 (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
382 MagickFalse,resource_current);
383 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
389 limit=resource_info.time_limit;
390 if (((MagickSizeType) resource_info.time+request) > (MagickSizeType) resource_info.time)
392 resource_info.time+=request;
393 if ((limit == 0) || ((MagickSizeType) resource_info.time < limit))
396 resource_info.time-=request;
398 if (logging != MagickFalse)
400 (void) FormatMagickSize(size,MagickFalse,resource_request);
401 (void) FormatMagickSize((MagickSizeType) resource_info.time,
402 MagickFalse,resource_current);
403 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
409 resource_info.width=(MagickOffsetType) size;
410 limit=resource_info.width_limit;
411 if ((limit == MagickResourceInfinity) || (size < limit))
413 if (logging != MagickFalse)
415 (void) FormatMagickSize(size,MagickFalse,resource_request);
416 (void) FormatMagickSize(size,MagickFalse,resource_current);
417 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
432 UnlockSemaphoreInfo(resource_semaphore[type]);
437 if (logging != MagickFalse)
439 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
440 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
441 resource_request,resource_current,resource_limit);
466MagickExport
void AsynchronousResourceComponentTerminus(
void)
476 ResetSplayTreeIterator(temporary_resources);
477 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
478 while (path != (
const char *) NULL)
480 (void) ShredFile(path);
481 (void) remove_utf8(path);
482 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
511static void *DestroyTemporaryResources(
void *temporary_resource)
513 (void) ShredFile((
char *) temporary_resource);
514 (void) remove_utf8((
char *) temporary_resource);
515 temporary_resource=DestroyString((
char *) temporary_resource);
516 return((
void *) NULL);
519MagickExport MagickBooleanType GetPathTemplate(
char *path)
534 (void) FormatLocaleString(path,MaxTextExtent,
"magick-" MagickPathTemplate);
535 exception=AcquireExceptionInfo();
536 directory=(
char *) GetImageRegistry(StringRegistryType,
"temporary-path",
538 exception=DestroyExceptionInfo(exception);
539 if (directory == (
char *) NULL)
540 directory=GetEnvironmentValue(
"MAGICK_TEMPORARY_PATH");
541 if (directory == (
char *) NULL)
542 directory=GetEnvironmentValue(
"MAGICK_TMPDIR");
543 if (directory == (
char *) NULL)
544 directory=GetEnvironmentValue(
"TMPDIR");
545#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) || defined(__CYGWIN__)
546 if (directory == (
char *) NULL)
547 directory=GetEnvironmentValue(
"TMP");
548 if (directory == (
char *) NULL)
549 directory=GetEnvironmentValue(
"TEMP");
552 if (directory == (
char *) NULL)
553 directory=GetEnvironmentValue(
"MTMPDIR");
556 if (directory == (
char *) NULL)
557 directory=ConstantString(P_tmpdir);
559 if (directory == (
char *) NULL)
561 value=GetPolicyValue(
"resource:temporary-path");
562 if (value != (
char *) NULL)
564 (void) CloneString(&directory,value);
565 value=DestroyString(value);
567 if (strlen(directory) > (MaxTextExtent-25))
569 directory=DestroyString(directory);
572 status=GetPathAttributes(directory,&attributes);
573 if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
575 directory=DestroyString(directory);
578 if (directory[strlen(directory)-1] == *DirectorySeparator)
579 (void) FormatLocaleString(path,MaxTextExtent,
"%smagick-" MagickPathTemplate,
582 (
void) FormatLocaleString(path,MaxTextExtent,
"%s%smagick-"
583 MagickPathTemplate,directory,DirectorySeparator);
584 directory=DestroyString(directory);
585#if defined(MAGICKCORE_WINDOWS_SUPPORT)
594 for (p=(path[1] == *DirectorySeparator ? path+2 : path); *p !=
'\0'; p++)
595 if (*p == *DirectorySeparator)
602MagickExport
int AcquireUniqueFileResource(
char *path)
604#if !defined(O_NOFOLLOW)
608# define TMP_MAX 238328
622 portable_filename[65] =
623 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
631 assert(path != (
char *) NULL);
632 if ((GetLogEventMask() & ResourceEvent) != 0)
633 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"...");
636 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
637 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
638 LockSemaphoreInfo(resource_semaphore[FileResource]);
640 random_info=AcquireRandomInfo();
641 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
644 for (i=0; i < (ssize_t) TMP_MAX; i++)
652 (void) GetPathTemplate(path);
653 key=GetRandomKey(random_info,strlen(MagickPathTemplate)-6);
654 p=path+strlen(path)-strlen(MagickPathTemplate);
655 datum=GetStringInfoDatum(key);
656 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
658 c=(int) (datum[j] & 0x3f);
659 *p++=portable_filename[c];
661 key=DestroyStringInfo(key);
662#if defined(MAGICKCORE_HAVE_MKSTEMP)
666#if defined(MAGICKCORE_HAVE_FCHMOD)
667 (void) fchmod(file,0600);
670 setmode(file,O_BINARY);
675 key=GetRandomKey(random_info,strlen(MagickPathTemplate));
676 p=path+strlen(path)-strlen(MagickPathTemplate);
677 datum=GetStringInfoDatum(key);
678 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
680 c=(int) (datum[j] & 0x3f);
681 *p++=portable_filename[c];
683 key=DestroyStringInfo(key);
684 file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
686 if ((file >= 0) || (errno != EEXIST))
689 if ((GetLogEventMask() & ResourceEvent) != 0)
690 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Acquire %s",path);
693 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
694 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
695 LockSemaphoreInfo(resource_semaphore[FileResource]);
697 temporary_resources=NewSplayTree(CompareSplayTreeString,
698 DestroyTemporaryResources,(
void *(*)(
void *)) NULL);
699 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
700 (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
701 (
const void *) NULL);
727MagickExport MagickSizeType GetMagickResource(
const ResourceType type)
742 ActivateSemaphoreInfo(&resource_semaphore[type]);
743 LockSemaphoreInfo(resource_semaphore[type]);
752 resource=(MagickSizeType) resource_info.area;
757 resource=(MagickSizeType) resource_info.disk;
762 resource=(MagickSizeType) resource_info.file;
767 resource=(MagickSizeType) resource_info.height;
770 case ListLengthResource:
772 resource=(MagickSizeType) resource_info.list_length;
777 resource=(MagickSizeType) resource_info.map;
782 resource=(MagickSizeType) resource_info.memory;
787 resource=(MagickSizeType) resource_info.thread;
790 case ThrottleResource:
792 resource=(MagickSizeType) resource_info.throttle;
797 resource=(MagickSizeType) resource_info.time;
802 resource=(MagickSizeType) resource_info.width;
816 UnlockSemaphoreInfo(resource_semaphore[type]);
846MagickExport MagickSizeType GetMagickResourceLimit(
const ResourceType type)
853 ActivateSemaphoreInfo(&resource_semaphore[type]);
854 LockSemaphoreInfo(resource_semaphore[type]);
859 resource=resource_info.area_limit;
864 resource=resource_info.disk_limit;
869 resource=resource_info.file_limit;
874 resource=resource_info.height_limit;
877 case ListLengthResource:
879 resource=resource_info.list_length_limit;
884 resource=resource_info.memory_limit;
889 resource=resource_info.map_limit;
894 resource=resource_info.thread_limit;
897 case ThrottleResource:
899 resource=resource_info.throttle_limit;
904 resource=resource_info.time_limit;
909 resource=resource_info.width_limit;
915 UnlockSemaphoreInfo(resource_semaphore[type]);
945static ssize_t FormatPixelSize(
const MagickSizeType size,
946 const MagickBooleanType bi,
char *format)
963 "",
"Ki",
"Mi",
"Gi",
"Ti",
"Pi",
"Ei",
"Zi",
"Yi",
"Ri",
"Qi", (
char *) NULL
965 *traditional_units[] =
967 "",
"K",
"M",
"G",
"T",
"P",
"E",
"Z",
"Y",
"R",
"Q", (
char *) NULL
971 units=traditional_units;
972 if (bi != MagickFalse)
977#if defined(_MSC_VER) && (_MSC_VER == 1200)
978 length=(double) ((MagickOffsetType) size);
980 length=(double) size;
982 for (i=0; (length >= bytes) && (units[i+1] != (
const char *) NULL); i++)
985 for (j=2; j < 12; j++)
987 count=FormatLocaleString(format,MaxTextExtent,
"%.*g%sP",(
int) (i+j),length,
989 if (strchr(format,
'+') == (
char *) NULL)
995static void FormatTimeToLive(
const MagickSizeType ttl,
char *timeString)
1007 seconds=ttl % 31536000;
1010 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld years",years);
1014 seconds=ttl % 2628000;
1017 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld months",
1022 seconds=ttl % 604800;
1025 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld weeks",weeks);
1029 seconds=ttl % 86400;
1032 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld days",days);
1039 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld hours",hours);
1046 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld minutes",
1050 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld seconds",ttl);
1053MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
1057 area_limit[MaxTextExtent],
1058 disk_limit[MaxTextExtent],
1059 height_limit[MaxTextExtent],
1060 list_length_limit[MaxTextExtent],
1061 map_limit[MaxTextExtent],
1062 memory_limit[MaxTextExtent],
1063 time_limit[MaxTextExtent],
1064 width_limit[MaxTextExtent];
1066 magick_unreferenced(exception);
1068 if (file == (
const FILE *) NULL)
1070 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1071 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1072 LockSemaphoreInfo(resource_semaphore[FileResource]);
1073 (void) FormatPixelSize(resource_info.width_limit,MagickFalse,width_limit);
1074 (void) FormatPixelSize(resource_info.height_limit,MagickFalse,height_limit);
1075 (void) FormatPixelSize(resource_info.area_limit,MagickFalse,area_limit);
1076 (void) CopyMagickString(list_length_limit,
"unlimited",MaxTextExtent);
1077 if (resource_info.list_length_limit != MagickResourceInfinity)
1078 (void) FormatMagickSize(resource_info.list_length_limit,MagickTrue,
1080 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
1081 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,map_limit);
1082 (void) CopyMagickString(disk_limit,
"unlimited",MaxTextExtent);
1083 if (resource_info.disk_limit != MagickResourceInfinity)
1084 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,disk_limit);
1085 (void) CopyMagickString(time_limit,
"unlimited",MaxTextExtent);
1086 if (resource_info.time_limit != 0)
1087 FormatTimeToLive(resource_info.time_limit,time_limit);
1088 (void) FormatLocaleFile(file,
"Resource limits:\n");
1089 (void) FormatLocaleFile(file,
" Width: %s\n",width_limit);
1090 (void) FormatLocaleFile(file,
" Height: %s\n",height_limit);
1091 (void) FormatLocaleFile(file,
" List length: %s\n",list_length_limit);
1092 (void) FormatLocaleFile(file,
" Area: %s\n",area_limit);
1093 (void) FormatLocaleFile(file,
" Memory: %s\n",memory_limit);
1094 (void) FormatLocaleFile(file,
" Map: %s\n",map_limit);
1095 (void) FormatLocaleFile(file,
" Disk: %s\n",disk_limit);
1096 (void) FormatLocaleFile(file,
" File: %.20g\n",(
double) ((MagickOffsetType)
1097 resource_info.file_limit));
1098 (void) FormatLocaleFile(file,
" Thread: %.20g\n",(
double) ((MagickOffsetType)
1099 resource_info.thread_limit));
1100 (void) FormatLocaleFile(file,
" Throttle: %.20g\n",(
double)
1101 ((MagickOffsetType) resource_info.throttle_limit));
1102 (void) FormatLocaleFile(file,
" Time: %s\n",time_limit);
1103 (void) fflush(file);
1104 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1133MagickExport
void RelinquishMagickResource(
const ResourceType type,
1134 const MagickSizeType size)
1137 resource_current[MaxTextExtent],
1138 resource_limit[MaxTextExtent],
1139 resource_request[MaxTextExtent];
1144 logging=(GetLogEventMask() & ResourceEvent) != 0 ? MagickTrue : MagickFalse;
1145 if (logging != MagickFalse)
1146 (void) FormatMagickSize(size,MagickFalse,resource_request);
1152 case MemoryResource:
1156 ActivateSemaphoreInfo(&resource_semaphore[type]);
1157 LockSemaphoreInfo(resource_semaphore[type]);
1166 resource_info.area=(MagickOffsetType) size;
1167 if (logging != MagickFalse)
1169 (void) FormatMagickSize((MagickSizeType) resource_info.area,
1170 MagickFalse,resource_current);
1171 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
1178 resource_info.disk-=size;
1179 assert(resource_info.disk >= 0);
1180 if (logging != MagickFalse)
1182 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
1183 MagickTrue,resource_current);
1184 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
1191 resource_info.file-=size;
1192 assert(resource_info.file >= 0);
1193 if (logging != MagickFalse)
1195 (void) FormatMagickSize((MagickSizeType) resource_info.file,
1196 MagickFalse,resource_current);
1197 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
1198 MagickFalse,resource_limit);
1202 case HeightResource:
1204 resource_info.height=(MagickOffsetType) size;
1205 if (logging != MagickFalse)
1207 (void) FormatMagickSize((MagickSizeType) resource_info.height,
1208 MagickFalse,resource_current);
1209 (void) FormatMagickSize(resource_info.height_limit,MagickFalse,
1214 case ListLengthResource:
1216 resource_info.list_length=(MagickOffsetType) size;
1217 if (logging != MagickFalse)
1219 (void) FormatMagickSize((MagickSizeType) resource_info.list_length,
1220 MagickFalse,resource_current);
1221 (void) FormatMagickSize(resource_info.list_length_limit,MagickFalse,
1228 resource_info.map-=size;
1229 assert(resource_info.map >= 0);
1230 if (logging != MagickFalse)
1232 (void) FormatMagickSize((MagickSizeType) resource_info.map,
1233 MagickTrue,resource_current);
1234 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
1239 case MemoryResource:
1241 resource_info.memory-=size;
1242 assert(resource_info.memory >= 0);
1243 if (logging != MagickFalse)
1245 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
1246 MagickTrue,resource_current);
1247 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
1252 case ThreadResource:
1254 if (logging != MagickFalse)
1256 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
1257 MagickFalse,resource_current);
1258 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
1259 MagickFalse,resource_limit);
1263 case ThrottleResource:
1265 if (logging != MagickFalse)
1267 (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
1268 MagickFalse,resource_current);
1269 (void) FormatMagickSize((MagickSizeType) resource_info.throttle_limit,
1270 MagickFalse,resource_limit);
1276 resource_info.time-=size;
1277 assert(resource_info.time >= 0);
1278 if (logging != MagickFalse)
1280 (void) FormatMagickSize((MagickSizeType) resource_info.time,
1281 MagickFalse,resource_current);
1282 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
1283 MagickFalse,resource_limit);
1289 resource_info.width=(MagickOffsetType) size;
1290 if (logging != MagickFalse)
1292 (void) FormatMagickSize((MagickSizeType) resource_info.width,
1293 MagickFalse,resource_current);
1294 (void) FormatMagickSize(resource_info.width_limit,MagickFalse,
1307 case MemoryResource:
1310 UnlockSemaphoreInfo(resource_semaphore[type]);
1315 if (logging != MagickFalse)
1317 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
1318 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
1319 resource_request,resource_current,resource_limit);
1345MagickExport MagickBooleanType RelinquishUniqueFileResource(
const char *path)
1348 cache_path[MaxTextExtent];
1353 assert(path != (
const char *) NULL);
1355 if ((GetLogEventMask() & ResourceEvent) != 0)
1356 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Relinquish %s",path);
1357 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1358 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1359 LockSemaphoreInfo(resource_semaphore[FileResource]);
1361 status=DeleteNodeFromSplayTree(temporary_resources, (
const void *) path);
1362 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1363 (void) CopyMagickString(cache_path,path,MaxTextExtent);
1364 AppendImageFormat(
"cache",cache_path);
1365 if (access_utf8(cache_path,F_OK) == 0)
1367 status=ShredFile(cache_path);
1368 status|=remove_utf8(cache_path);
1370 if (status == MagickFalse)
1372 status=ShredFile(path);
1373 status|=remove_utf8(path);
1375 return(status == 0 ? MagickFalse : MagickTrue);
1396MagickExport MagickBooleanType ResourceComponentGenesis(
void)
1414 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1416 ActivateSemaphoreInfo(&resource_semaphore[i]);
1417 (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
1418 limit=GetEnvironmentValue(
"MAGICK_WIDTH_LIMIT");
1419 if (limit != (
char *) NULL)
1421 (void) SetMagickResourceLimit(WidthResource,StringToSizeType(limit,
1423 limit=DestroyString(limit);
1425 (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
1426 limit=GetEnvironmentValue(
"MAGICK_HEIGHT_LIMIT");
1427 if (limit != (
char *) NULL)
1429 (void) SetMagickResourceLimit(HeightResource,StringToSizeType(limit,
1431 limit=DestroyString(limit);
1433 pagesize=GetMagickPageSize();
1435#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1436 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1437#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1441 memory=(MagickSizeType) pages*pagesize;
1442 if ((pagesize <= 0) || (pages <= 0))
1443 memory=2048UL*1024UL*1024UL;
1444#if defined(MAGICKCORE_PixelCacheThreshold)
1445 memory=StringToMagickSizeType(MAGICKCORE_PixelCacheThreshold,100.0);
1447 (void) SetMagickResourceLimit(AreaResource,4*memory);
1448 limit=GetEnvironmentValue(
"MAGICK_AREA_LIMIT");
1449 if (limit != (
char *) NULL)
1451 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
1452 limit=DestroyString(limit);
1454 (void) SetMagickResourceLimit(MemoryResource,memory);
1455 limit=GetEnvironmentValue(
"MAGICK_MEMORY_LIMIT");
1456 if (limit != (
char *) NULL)
1458 (void) SetMagickResourceLimit(MemoryResource,
1459 StringToSizeType(limit,100.0));
1460 limit=DestroyString(limit);
1462 (void) SetMagickResourceLimit(MapResource,2*memory);
1463 limit=GetEnvironmentValue(
"MAGICK_MAP_LIMIT");
1464 if (limit != (
char *) NULL)
1466 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
1467 limit=DestroyString(limit);
1469 (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
1470 limit=GetEnvironmentValue(
"MAGICK_DISK_LIMIT");
1471 if (limit != (
char *) NULL)
1473 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
1474 limit=DestroyString(limit);
1477#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1478 files=(ssize_t) sysconf(_SC_OPEN_MAX);
1480#if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1486 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1487 files=(ssize_t) resources.rlim_cur;
1490#if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1492 files=(ssize_t) getdtablesize();
1496 (void) SetMagickResourceLimit(FileResource,MagickMax((
size_t)
1498 limit=GetEnvironmentValue(
"MAGICK_FILE_LIMIT");
1499 if (limit != (
char *) NULL)
1501 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
1502 limit=DestroyString(limit);
1504 number_threads=(ssize_t) GetOpenMPMaximumThreads();
1505 if (number_threads > 1)
1507 (void) SetMagickResourceLimit(ThreadResource,(
size_t) number_threads);
1508 limit=GetEnvironmentValue(
"MAGICK_THREAD_LIMIT");
1509 if (limit != (
char *) NULL)
1511 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
1513 limit=DestroyString(limit);
1515 (void) SetMagickResourceLimit(ThrottleResource,0);
1516 limit=GetEnvironmentValue(
"MAGICK_THROTTLE_LIMIT");
1517 if (limit != (
char *) NULL)
1519 (void) SetMagickResourceLimit(ThrottleResource,StringToSizeType(limit,
1521 limit=DestroyString(limit);
1523 (void) SetMagickResourceLimit(TimeResource,0);
1524 limit=GetEnvironmentValue(
"MAGICK_TIME_LIMIT");
1525 if (limit != (
char *) NULL)
1527 (void) SetMagickResourceLimit(TimeResource,(MagickSizeType)
1528 ParseMagickTimeToLive(limit));
1529 limit=DestroyString(limit);
1531 (void) SetMagickResourceLimit(ListLengthResource,MagickResourceInfinity);
1532 limit=GetEnvironmentValue(
"MAGICK_LIST_LENGTH_LIMIT");
1533 if (limit != (
char *) NULL)
1535 (void) SetMagickResourceLimit(ListLengthResource,
1536 StringToSizeType(limit,100.0));
1537 limit=DestroyString(limit);
1560MagickExport
void ResourceComponentTerminus(
void)
1565 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1567 ActivateSemaphoreInfo(&resource_semaphore[i]);
1568 LockSemaphoreInfo(resource_semaphore[FileResource]);
1570 temporary_resources=DestroySplayTree(temporary_resources);
1572 random_info=DestroyRandomInfo(random_info);
1573 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1574 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1575 DestroySemaphoreInfo(&resource_semaphore[i]);
1604MagickExport MagickBooleanType SetMagickResourceLimit(
const ResourceType type,
1605 const MagickSizeType limit)
1615 ActivateSemaphoreInfo(&resource_semaphore[type]);
1616 LockSemaphoreInfo(resource_semaphore[type]);
1617 value=(
char *) NULL;
1622 value=GetPolicyValue(
"resource:area");
1623 if (value == (
char *) NULL)
1624 resource_info.area_limit=limit;
1626 resource_info.area_limit=MagickMin(limit,StringToSizeType(value,100.0));
1631 value=GetPolicyValue(
"resource:disk");
1632 if (value == (
char *) NULL)
1633 resource_info.disk_limit=limit;
1635 resource_info.disk_limit=MagickMin(limit,StringToSizeType(value,100.0));
1640 value=GetPolicyValue(
"resource:file");
1641 if (value == (
char *) NULL)
1642 resource_info.file_limit=limit;
1644 resource_info.file_limit=MagickMin(limit,StringToSizeType(value,100.0));
1647 case HeightResource:
1649 value=GetPolicyValue(
"resource:height");
1650 if (value == (
char *) NULL)
1651 resource_info.height_limit=limit;
1653 resource_info.height_limit=MagickMin(limit,StringToSizeType(value,
1655 resource_info.height_limit=MagickMin(resource_info.height_limit,
1656 (MagickSizeType) MAGICK_SSIZE_MAX);
1659 case ListLengthResource:
1661 value=GetPolicyValue(
"resource:list-length");
1662 if (value == (
char *) NULL)
1663 resource_info.list_length_limit=limit;
1665 resource_info.list_length_limit=MagickMin(limit,
1666 StringToSizeType(value,100.0));
1671 value=GetPolicyValue(
"resource:map");
1672 if (value == (
char *) NULL)
1673 resource_info.map_limit=limit;
1675 resource_info.map_limit=MagickMin(limit,StringToSizeType(value,100.0));
1678 case MemoryResource:
1680 value=GetPolicyValue(
"resource:memory");
1681 if (value == (
char *) NULL)
1682 resource_info.memory_limit=limit;
1684 resource_info.memory_limit=MagickMin(limit,StringToSizeType(value,
1688 case ThreadResource:
1690 value=GetPolicyValue(
"resource:thread");
1691 if (value == (
char *) NULL)
1692 resource_info.thread_limit=limit;
1694 resource_info.thread_limit=MagickMin(limit,StringToSizeType(value,
1696 if (resource_info.thread_limit > GetOpenMPMaximumThreads())
1697 resource_info.thread_limit=GetOpenMPMaximumThreads();
1699 if (resource_info.thread_limit == 0)
1700 resource_info.thread_limit=1;
1703 case ThrottleResource:
1705 value=GetPolicyValue(
"resource:throttle");
1706 if (value == (
char *) NULL)
1707 resource_info.throttle_limit=limit;
1709 resource_info.throttle_limit=MagickMax(limit,StringToSizeType(value,
1715 value=GetPolicyValue(
"resource:time");
1716 if (value == (
char *) NULL)
1717 resource_info.time_limit=limit;
1719 resource_info.time_limit=MagickMin(limit,(MagickSizeType)
1720 ParseMagickTimeToLive(value));
1725 value=GetPolicyValue(
"resource:width");
1726 if (value == (
char *) NULL)
1727 resource_info.width_limit=limit;
1729 resource_info.width_limit=MagickMin(limit,StringToSizeType(value,
1731 resource_info.width_limit=MagickMin(resource_info.width_limit,
1732 (MagickSizeType) MAGICK_SSIZE_MAX);
1741 if (value != (
char *) NULL)
1742 value=DestroyString(value);
1743 UnlockSemaphoreInfo(resource_semaphore[type]);