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))
77 #define TimeToLiveMax INT_MAX
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 MagickULLConstant(0),
131 (MagickSizeType) (MAGICK_SSIZE_MAX/
sizeof(
PixelPacket)/5),
132 (MagickSizeType) (MAGICK_SSIZE_MAX/
sizeof(
PixelPacket)/5),
133 MagickResourceInfinity,
134 MagickULLConstant(3072)*1024*1024,
135 MagickULLConstant(1536)*1024*1024,
136 MagickULLConstant(3072)*1024*1024,
137 MagickResourceInfinity,
138 MagickULLConstant(768),
139 MagickULLConstant(1),
140 MagickULLConstant(0),
145 *resource_semaphore[] = {
190 MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
191 const MagickSizeType size)
194 resource_current[MaxTextExtent] =
"",
195 resource_limit[MaxTextExtent] =
"",
196 resource_request[MaxTextExtent] =
"";
208 request=(MagickOffsetType) size;
212 logging=(GetLogEventMask() & ResourceEvent) != 0 ? MagickTrue : MagickFalse;
222 ActivateSemaphoreInfo(&resource_semaphore[type]);
223 LockSemaphoreInfo(resource_semaphore[type]);
232 resource_info.area=(MagickOffsetType) size;
233 limit=resource_info.area_limit;
234 if ((limit == MagickResourceInfinity) || (size < limit))
236 if (logging != MagickFalse)
238 (void) FormatMagickSize(size,MagickFalse,resource_request);
239 (void) FormatMagickSize(size,MagickFalse,resource_current);
240 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
246 limit=resource_info.disk_limit;
247 if (((MagickSizeType) resource_info.disk+request) >
248 (MagickSizeType) resource_info.disk)
250 resource_info.disk+=request;
251 if ((limit == MagickResourceInfinity) ||
252 (resource_info.disk < (MagickOffsetType) limit))
255 resource_info.disk-=request;
257 if (logging != MagickFalse)
259 (void) FormatMagickSize(size,MagickTrue,resource_request);
260 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
261 MagickTrue,resource_current);
262 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
268 limit=resource_info.file_limit;
269 if (((MagickSizeType) resource_info.file+request) >
270 (MagickSizeType) resource_info.file)
272 resource_info.file+=request;
273 if ((limit == MagickResourceInfinity) ||
274 (resource_info.file < (MagickOffsetType) limit))
277 if (logging != MagickFalse)
279 (void) FormatMagickSize(size,MagickFalse,resource_request);
280 (void) FormatMagickSize((MagickSizeType) resource_info.file,
281 MagickFalse,resource_current);
282 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
288 resource_info.height=(MagickOffsetType) size;
289 limit=resource_info.height_limit;
290 if ((limit == MagickResourceInfinity) || (size < limit))
292 if (logging != MagickFalse)
294 (void) FormatMagickSize(size,MagickFalse,resource_request);
295 (void) FormatMagickSize(size,MagickFalse,resource_current);
296 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
300 case ListLengthResource:
302 resource_info.list_length=(MagickOffsetType) size;
303 limit=resource_info.list_length_limit;
304 if ((limit == MagickResourceInfinity) || (size < limit))
306 if (logging != MagickFalse)
308 (void) FormatMagickSize(size,MagickFalse,resource_request);
309 (void) FormatMagickSize(size,MagickFalse,resource_current);
310 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
316 limit=resource_info.map_limit;
317 if (((MagickSizeType) resource_info.map+request) >
318 (MagickSizeType) resource_info.map)
320 resource_info.map+=request;
321 if ((limit == MagickResourceInfinity) ||
322 (resource_info.map < (MagickOffsetType) limit))
325 resource_info.map-=request;
327 if (logging != MagickFalse)
329 (void) FormatMagickSize(size,MagickTrue,resource_request);
330 (void) FormatMagickSize((MagickSizeType) resource_info.map,
331 MagickTrue,resource_current);
332 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
338 limit=resource_info.memory_limit;
339 if (((MagickSizeType) resource_info.memory+request) >
340 (MagickSizeType) resource_info.memory)
342 resource_info.memory+=request;
343 if ((limit == MagickResourceInfinity) ||
344 (resource_info.memory < (MagickOffsetType) limit))
347 resource_info.memory-=request;
349 if (logging != MagickFalse)
351 (void) FormatMagickSize(size,MagickTrue,resource_request);
352 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
353 MagickTrue,resource_current);
354 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
360 limit=resource_info.thread_limit;
361 if ((limit == MagickResourceInfinity) ||
362 (resource_info.thread < (MagickOffsetType) limit))
364 if (logging != MagickFalse)
366 (void) FormatMagickSize(size,MagickFalse,resource_request);
367 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
368 MagickFalse,resource_current);
369 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
373 case ThrottleResource:
375 limit=resource_info.throttle_limit;
376 if ((limit == MagickResourceInfinity) ||
377 (resource_info.throttle < (MagickOffsetType) limit))
379 if (logging != MagickFalse)
381 (void) FormatMagickSize(size,MagickFalse,resource_request);
382 (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
383 MagickFalse,resource_current);
384 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
390 limit=resource_info.time_limit;
391 if (((MagickSizeType) resource_info.time+request) > (MagickSizeType) resource_info.time)
393 resource_info.time+=request;
394 if ((limit == TimeToLiveMax) ||
395 ((MagickSizeType) resource_info.time < limit))
398 resource_info.time-=request;
400 if (logging != MagickFalse)
402 (void) FormatMagickSize(size,MagickFalse,resource_request);
403 (void) FormatMagickSize((MagickSizeType) resource_info.time,
404 MagickFalse,resource_current);
405 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
411 resource_info.width=(MagickOffsetType) size;
412 limit=resource_info.width_limit;
413 if ((limit == MagickResourceInfinity) || (size < limit))
415 if (logging != MagickFalse)
417 (void) FormatMagickSize(size,MagickFalse,resource_request);
418 (void) FormatMagickSize(size,MagickFalse,resource_current);
419 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
434 UnlockSemaphoreInfo(resource_semaphore[type]);
439 if (logging != MagickFalse)
441 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
442 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
443 resource_request,resource_current,resource_limit);
468 MagickExport
void AsynchronousResourceComponentTerminus(
void)
478 ResetSplayTreeIterator(temporary_resources);
479 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
480 while (path != (
const char *) NULL)
482 (void) ShredFile(path);
483 (void) remove_utf8(path);
484 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
513 static void *DestroyTemporaryResources(
void *temporary_resource)
515 (void) ShredFile((
char *) temporary_resource);
516 (void) remove_utf8((
char *) temporary_resource);
517 temporary_resource=DestroyString((
char *) temporary_resource);
518 return((
void *) NULL);
521 MagickExport MagickBooleanType GetPathTemplate(
char *path)
536 (void) FormatLocaleString(path,MaxTextExtent,
"magick-" MagickPathTemplate);
537 exception=AcquireExceptionInfo();
538 directory=(
char *) GetImageRegistry(StringRegistryType,
"temporary-path",
540 exception=DestroyExceptionInfo(exception);
541 if (directory == (
char *) NULL)
542 directory=GetEnvironmentValue(
"MAGICK_TEMPORARY_PATH");
543 if (directory == (
char *) NULL)
544 directory=GetEnvironmentValue(
"MAGICK_TMPDIR");
545 if (directory == (
char *) NULL)
546 directory=GetEnvironmentValue(
"TMPDIR");
547 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) || defined(__CYGWIN__)
548 if (directory == (
char *) NULL)
549 directory=GetEnvironmentValue(
"TMP");
550 if (directory == (
char *) NULL)
551 directory=GetEnvironmentValue(
"TEMP");
554 if (directory == (
char *) NULL)
555 directory=GetEnvironmentValue(
"MTMPDIR");
557 #if defined(P_tmpdir)
558 if (directory == (
char *) NULL)
559 directory=ConstantString(P_tmpdir);
561 if (directory == (
char *) NULL)
563 value=GetPolicyValue(
"resource:temporary-path");
564 if (value != (
char *) NULL)
566 (void) CloneString(&directory,value);
567 value=DestroyString(value);
569 if (strlen(directory) > (MaxTextExtent-25))
571 directory=DestroyString(directory);
574 status=GetPathAttributes(directory,&attributes);
575 if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
577 directory=DestroyString(directory);
580 if (directory[strlen(directory)-1] == *DirectorySeparator)
581 (void) FormatLocaleString(path,MaxTextExtent,
"%smagick-" MagickPathTemplate,
584 (
void) FormatLocaleString(path,MaxTextExtent,
"%s%smagick-"
585 MagickPathTemplate,directory,DirectorySeparator);
586 directory=DestroyString(directory);
587 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
596 for (p=(path[1] == *DirectorySeparator ? path+2 : path); *p !=
'\0'; p++)
597 if (*p == *DirectorySeparator)
604 MagickExport
int AcquireUniqueFileResource(
char *path)
606 #if !defined(O_NOFOLLOW)
609 #if !defined(TMP_MAX)
610 # define TMP_MAX 238328
624 portable_filename[65] =
625 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
633 assert(path != (
char *) NULL);
634 if ((GetLogEventMask() & ResourceEvent) != 0)
635 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"...");
638 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
639 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
640 LockSemaphoreInfo(resource_semaphore[FileResource]);
642 random_info=AcquireRandomInfo();
643 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
646 for (i=0; i < (ssize_t) TMP_MAX; i++)
654 (void) GetPathTemplate(path);
655 key=GetRandomKey(random_info,strlen(MagickPathTemplate)-6);
656 p=path+strlen(path)-strlen(MagickPathTemplate);
657 datum=GetStringInfoDatum(key);
658 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
660 c=(int) (datum[j] & 0x3f);
661 *p++=portable_filename[c];
663 key=DestroyStringInfo(key);
664 #if defined(MAGICKCORE_HAVE_MKSTEMP)
668 #if defined(MAGICKCORE_HAVE_FCHMOD)
669 (void) fchmod(file,0600);
672 setmode(file,O_BINARY);
677 key=GetRandomKey(random_info,strlen(MagickPathTemplate));
678 p=path+strlen(path)-strlen(MagickPathTemplate);
679 datum=GetStringInfoDatum(key);
680 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
682 c=(int) (datum[j] & 0x3f);
683 *p++=portable_filename[c];
685 key=DestroyStringInfo(key);
686 file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
688 if ((file >= 0) || (errno != EEXIST))
691 if ((GetLogEventMask() & ResourceEvent) != 0)
692 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Acquire %s",path);
695 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
696 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
697 LockSemaphoreInfo(resource_semaphore[FileResource]);
699 temporary_resources=NewSplayTree(CompareSplayTreeString,
700 DestroyTemporaryResources,(
void *(*)(
void *)) NULL);
701 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
702 (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
703 (
const void *) NULL);
729 MagickExport MagickSizeType GetMagickResource(
const ResourceType type)
744 ActivateSemaphoreInfo(&resource_semaphore[type]);
745 LockSemaphoreInfo(resource_semaphore[type]);
754 resource=(MagickSizeType) resource_info.area;
759 resource=(MagickSizeType) resource_info.disk;
764 resource=(MagickSizeType) resource_info.file;
769 resource=(MagickSizeType) resource_info.height;
772 case ListLengthResource:
774 resource=(MagickSizeType) resource_info.list_length;
779 resource=(MagickSizeType) resource_info.map;
784 resource=(MagickSizeType) resource_info.memory;
789 resource=(MagickSizeType) resource_info.thread;
792 case ThrottleResource:
794 resource=(MagickSizeType) resource_info.throttle;
799 resource=(MagickSizeType) resource_info.time;
804 resource=(MagickSizeType) resource_info.width;
818 UnlockSemaphoreInfo(resource_semaphore[type]);
848 MagickExport MagickSizeType GetMagickResourceLimit(
const ResourceType type)
855 ActivateSemaphoreInfo(&resource_semaphore[type]);
856 LockSemaphoreInfo(resource_semaphore[type]);
861 resource=resource_info.area_limit;
866 resource=resource_info.disk_limit;
871 resource=resource_info.file_limit;
876 resource=resource_info.height_limit;
879 case ListLengthResource:
881 resource=resource_info.list_length_limit;
886 resource=resource_info.memory_limit;
891 resource=resource_info.map_limit;
896 resource=resource_info.thread_limit;
899 case ThrottleResource:
901 resource=resource_info.throttle_limit;
906 resource=resource_info.time_limit;
911 resource=resource_info.width_limit;
917 UnlockSemaphoreInfo(resource_semaphore[type]);
947 static ssize_t FormatPixelSize(
const MagickSizeType size,
948 const MagickBooleanType bi,
char *format)
965 "",
"Ki",
"Mi",
"Gi",
"Ti",
"Pi",
"Ei",
"Zi",
"Yi",
"Ri",
"Qi", (
char *) NULL
967 *traditional_units[] =
969 "",
"K",
"M",
"G",
"T",
"P",
"E",
"Z",
"Y",
"R",
"Q", (
char *) NULL
973 units=traditional_units;
974 if (bi != MagickFalse)
979 #if defined(_MSC_VER) && (_MSC_VER == 1200)
980 length=(double) ((MagickOffsetType) size);
982 length=(double) size;
984 for (i=0; (length >= bytes) && (units[i+1] != (
const char *) NULL); i++)
987 for (j=2; j < 12; j++)
989 count=FormatLocaleString(format,MaxTextExtent,
"%.*g%sP",(
int) (i+j),length,
991 if (strchr(format,
'+') == (
char *) NULL)
997 static void FormatTimeToLive(
const MagickSizeType ttl,
char *timeString)
1009 seconds=ttl % 31536000;
1012 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld years",years);
1016 seconds=ttl % 2628000;
1019 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld months",
1024 seconds=ttl % 604800;
1027 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld weeks",weeks);
1031 seconds=ttl % 86400;
1034 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld days",days);
1041 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld hours",hours);
1048 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld minutes",
1052 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld seconds",ttl);
1055 MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
1059 area_limit[MaxTextExtent],
1060 disk_limit[MaxTextExtent],
1061 height_limit[MaxTextExtent],
1062 list_length_limit[MaxTextExtent],
1063 map_limit[MaxTextExtent],
1064 memory_limit[MaxTextExtent],
1065 time_limit[MaxTextExtent],
1066 width_limit[MaxTextExtent];
1068 magick_unreferenced(exception);
1070 if (file == (
const FILE *) NULL)
1072 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1073 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1074 LockSemaphoreInfo(resource_semaphore[FileResource]);
1075 (void) FormatPixelSize(resource_info.width_limit,MagickFalse,width_limit);
1076 (void) FormatPixelSize(resource_info.height_limit,MagickFalse,height_limit);
1077 (void) FormatPixelSize(resource_info.area_limit,MagickFalse,area_limit);
1078 (void) CopyMagickString(list_length_limit,
"unlimited",MaxTextExtent);
1079 if (resource_info.list_length_limit != MagickResourceInfinity)
1080 (void) FormatMagickSize(resource_info.list_length_limit,MagickTrue,
1082 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
1083 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,map_limit);
1084 (void) CopyMagickString(disk_limit,
"unlimited",MaxTextExtent);
1085 if (resource_info.disk_limit != MagickResourceInfinity)
1086 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,disk_limit);
1087 (void) CopyMagickString(time_limit,
"unlimited",MaxTextExtent);
1088 if (resource_info.time_limit != TimeToLiveMax)
1089 FormatTimeToLive(resource_info.time_limit,time_limit);
1090 (void) FormatLocaleFile(file,
"Resource limits:\n");
1091 (void) FormatLocaleFile(file,
" Width: %s\n",width_limit);
1092 (void) FormatLocaleFile(file,
" Height: %s\n",height_limit);
1093 (void) FormatLocaleFile(file,
" List length: %s\n",list_length_limit);
1094 (void) FormatLocaleFile(file,
" Area: %s\n",area_limit);
1095 (void) FormatLocaleFile(file,
" Memory: %s\n",memory_limit);
1096 (void) FormatLocaleFile(file,
" Map: %s\n",map_limit);
1097 (void) FormatLocaleFile(file,
" Disk: %s\n",disk_limit);
1098 (void) FormatLocaleFile(file,
" File: %.20g\n",(
double) ((MagickOffsetType)
1099 resource_info.file_limit));
1100 (void) FormatLocaleFile(file,
" Thread: %.20g\n",(
double) ((MagickOffsetType)
1101 resource_info.thread_limit));
1102 (void) FormatLocaleFile(file,
" Throttle: %.20g\n",(
double)
1103 ((MagickOffsetType) resource_info.throttle_limit));
1104 (void) FormatLocaleFile(file,
" Time: %s\n",time_limit);
1105 (void) fflush(file);
1106 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1135 MagickExport
void RelinquishMagickResource(
const ResourceType type,
1136 const MagickSizeType size)
1139 resource_current[MaxTextExtent],
1140 resource_limit[MaxTextExtent],
1141 resource_request[MaxTextExtent];
1146 logging=(GetLogEventMask() & ResourceEvent) != 0 ? MagickTrue : MagickFalse;
1147 if (logging != MagickFalse)
1148 (void) FormatMagickSize(size,MagickFalse,resource_request);
1154 case MemoryResource:
1158 ActivateSemaphoreInfo(&resource_semaphore[type]);
1159 LockSemaphoreInfo(resource_semaphore[type]);
1168 resource_info.area=(MagickOffsetType) size;
1169 if (logging != MagickFalse)
1171 (void) FormatMagickSize((MagickSizeType) resource_info.area,
1172 MagickFalse,resource_current);
1173 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
1180 resource_info.disk-=size;
1181 assert(resource_info.disk >= 0);
1182 if (logging != MagickFalse)
1184 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
1185 MagickTrue,resource_current);
1186 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
1193 resource_info.file-=size;
1194 assert(resource_info.file >= 0);
1195 if (logging != MagickFalse)
1197 (void) FormatMagickSize((MagickSizeType) resource_info.file,
1198 MagickFalse,resource_current);
1199 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
1200 MagickFalse,resource_limit);
1204 case HeightResource:
1206 resource_info.height=(MagickOffsetType) size;
1207 if (logging != MagickFalse)
1209 (void) FormatMagickSize((MagickSizeType) resource_info.height,
1210 MagickFalse,resource_current);
1211 (void) FormatMagickSize(resource_info.height_limit,MagickFalse,
1216 case ListLengthResource:
1218 resource_info.list_length=(MagickOffsetType) size;
1219 if (logging != MagickFalse)
1221 (void) FormatMagickSize((MagickSizeType) resource_info.list_length,
1222 MagickFalse,resource_current);
1223 (void) FormatMagickSize(resource_info.list_length_limit,MagickFalse,
1230 resource_info.map-=size;
1231 assert(resource_info.map >= 0);
1232 if (logging != MagickFalse)
1234 (void) FormatMagickSize((MagickSizeType) resource_info.map,
1235 MagickTrue,resource_current);
1236 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
1241 case MemoryResource:
1243 resource_info.memory-=size;
1244 assert(resource_info.memory >= 0);
1245 if (logging != MagickFalse)
1247 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
1248 MagickTrue,resource_current);
1249 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
1254 case ThreadResource:
1256 if (logging != MagickFalse)
1258 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
1259 MagickFalse,resource_current);
1260 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
1261 MagickFalse,resource_limit);
1265 case ThrottleResource:
1267 if (logging != MagickFalse)
1269 (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
1270 MagickFalse,resource_current);
1271 (void) FormatMagickSize((MagickSizeType) resource_info.throttle_limit,
1272 MagickFalse,resource_limit);
1278 resource_info.time-=size;
1279 assert(resource_info.time >= 0);
1280 if (logging != MagickFalse)
1281 if (logging != MagickFalse)
1283 (void) FormatMagickSize((MagickSizeType) resource_info.time,
1284 MagickFalse,resource_current);
1285 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
1286 MagickFalse,resource_limit);
1292 resource_info.width=(MagickOffsetType) size;
1293 if (logging != MagickFalse)
1295 (void) FormatMagickSize((MagickSizeType) resource_info.width,
1296 MagickFalse,resource_current);
1297 (void) FormatMagickSize(resource_info.width_limit,MagickFalse,
1310 case MemoryResource:
1313 UnlockSemaphoreInfo(resource_semaphore[type]);
1318 if (logging != MagickFalse)
1320 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
1321 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
1322 resource_request,resource_current,resource_limit);
1348 MagickExport MagickBooleanType RelinquishUniqueFileResource(
const char *path)
1351 cache_path[MaxTextExtent];
1356 assert(path != (
const char *) NULL);
1358 if ((GetLogEventMask() & ResourceEvent) != 0)
1359 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Relinquish %s",path);
1360 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1361 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1362 LockSemaphoreInfo(resource_semaphore[FileResource]);
1364 status=DeleteNodeFromSplayTree(temporary_resources, (
const void *) path);
1365 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1366 (void) CopyMagickString(cache_path,path,MaxTextExtent);
1367 AppendImageFormat(
"cache",cache_path);
1368 if (access_utf8(cache_path,F_OK) == 0)
1370 status=ShredFile(cache_path);
1371 status|=remove_utf8(cache_path);
1373 if (status == MagickFalse)
1375 status=ShredFile(path);
1376 status|=remove_utf8(path);
1378 return(status == 0 ? MagickFalse : MagickTrue);
1399 MagickExport MagickBooleanType ResourceComponentGenesis(
void)
1418 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1420 ActivateSemaphoreInfo(&resource_semaphore[i]);
1421 (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
1422 limit=GetEnvironmentValue(
"MAGICK_WIDTH_LIMIT");
1423 if (limit != (
char *) NULL)
1425 (void) SetMagickResourceLimit(WidthResource,StringToSizeType(limit,
1427 limit=DestroyString(limit);
1429 (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
1430 limit=GetEnvironmentValue(
"MAGICK_HEIGHT_LIMIT");
1431 if (limit != (
char *) NULL)
1433 (void) SetMagickResourceLimit(HeightResource,StringToSizeType(limit,
1435 limit=DestroyString(limit);
1437 pagesize=GetMagickPageSize();
1439 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1440 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1441 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1445 memory=(MagickSizeType) pages*pagesize;
1446 if ((pagesize <= 0) || (pages <= 0))
1447 memory=2048UL*1024UL*1024UL;
1448 #if defined(MAGICKCORE_PixelCacheThreshold)
1449 memory=StringToMagickSizeType(MAGICKCORE_PixelCacheThreshold,100.0);
1451 (void) SetMagickResourceLimit(AreaResource,4*memory);
1452 limit=GetEnvironmentValue(
"MAGICK_AREA_LIMIT");
1453 if (limit != (
char *) NULL)
1455 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
1456 limit=DestroyString(limit);
1458 (void) SetMagickResourceLimit(MemoryResource,memory);
1459 limit=GetEnvironmentValue(
"MAGICK_MEMORY_LIMIT");
1460 if (limit != (
char *) NULL)
1462 (void) SetMagickResourceLimit(MemoryResource,
1463 StringToSizeType(limit,100.0));
1464 limit=DestroyString(limit);
1466 (void) SetMagickResourceLimit(MapResource,2*memory);
1467 limit=GetEnvironmentValue(
"MAGICK_MAP_LIMIT");
1468 if (limit != (
char *) NULL)
1470 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
1471 limit=DestroyString(limit);
1473 (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
1474 limit=GetEnvironmentValue(
"MAGICK_DISK_LIMIT");
1475 if (limit != (
char *) NULL)
1477 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
1478 limit=DestroyString(limit);
1481 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1482 files=(ssize_t) sysconf(_SC_OPEN_MAX);
1484 #if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1490 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1491 files=(ssize_t) resources.rlim_cur;
1494 #if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1496 files=(ssize_t) getdtablesize();
1500 (void) SetMagickResourceLimit(FileResource,MagickMax((
size_t)
1502 limit=GetEnvironmentValue(
"MAGICK_FILE_LIMIT");
1503 if (limit != (
char *) NULL)
1505 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
1506 limit=DestroyString(limit);
1508 (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads());
1509 limit=GetEnvironmentValue(
"MAGICK_THREAD_LIMIT");
1510 if (limit != (
char *) NULL)
1512 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
1514 limit=DestroyString(limit);
1516 (void) SetMagickResourceLimit(ThrottleResource,0);
1517 limit=GetEnvironmentValue(
"MAGICK_THROTTLE_LIMIT");
1518 if (limit != (
char *) NULL)
1520 (void) SetMagickResourceLimit(ThrottleResource,StringToSizeType(limit,
1522 limit=DestroyString(limit);
1524 (void) SetMagickResourceLimit(TimeResource,TimeToLiveMax);
1525 limit=GetEnvironmentValue(
"MAGICK_TIME_LIMIT");
1526 if (limit != (
char *) NULL)
1528 (void) SetMagickResourceLimit(TimeResource,(MagickSizeType)
1529 ParseMagickTimeToLive(limit));
1530 limit=DestroyString(limit);
1532 (void) SetMagickResourceLimit(ListLengthResource,MagickResourceInfinity);
1533 limit=GetEnvironmentValue(
"MAGICK_LIST_LENGTH_LIMIT");
1534 if (limit != (
char *) NULL)
1536 (void) SetMagickResourceLimit(ListLengthResource,
1537 StringToSizeType(limit,100.0));
1538 limit=DestroyString(limit);
1561 MagickExport
void ResourceComponentTerminus(
void)
1566 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1568 ActivateSemaphoreInfo(&resource_semaphore[i]);
1569 LockSemaphoreInfo(resource_semaphore[FileResource]);
1571 temporary_resources=DestroySplayTree(temporary_resources);
1573 random_info=DestroyRandomInfo(random_info);
1574 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1575 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1576 DestroySemaphoreInfo(&resource_semaphore[i]);
1605 MagickExport MagickBooleanType SetMagickResourceLimit(
const ResourceType type,
1606 const MagickSizeType limit)
1616 ActivateSemaphoreInfo(&resource_semaphore[type]);
1617 LockSemaphoreInfo(resource_semaphore[type]);
1618 value=(
char *) NULL;
1623 value=GetPolicyValue(
"resource:area");
1624 if (value == (
char *) NULL)
1625 resource_info.area_limit=limit;
1627 resource_info.area_limit=MagickMin(limit,StringToSizeType(value,100.0));
1632 value=GetPolicyValue(
"resource:disk");
1633 if (value == (
char *) NULL)
1634 resource_info.disk_limit=limit;
1636 resource_info.disk_limit=MagickMin(limit,StringToSizeType(value,100.0));
1641 value=GetPolicyValue(
"resource:file");
1642 if (value == (
char *) NULL)
1643 resource_info.file_limit=limit;
1645 resource_info.file_limit=MagickMin(limit,StringToSizeType(value,100.0));
1648 case HeightResource:
1650 value=GetPolicyValue(
"resource:height");
1651 if (value == (
char *) NULL)
1652 resource_info.height_limit=limit;
1654 resource_info.height_limit=MagickMin(limit,StringToSizeType(value,
1656 resource_info.height_limit=MagickMin(resource_info.height_limit,
1657 (MagickSizeType) MAGICK_SSIZE_MAX);
1660 case ListLengthResource:
1662 value=GetPolicyValue(
"resource:list-length");
1663 if (value == (
char *) NULL)
1664 resource_info.list_length_limit=limit;
1666 resource_info.list_length_limit=MagickMin(limit,
1667 StringToSizeType(value,100.0));
1672 value=GetPolicyValue(
"resource:map");
1673 if (value == (
char *) NULL)
1674 resource_info.map_limit=limit;
1676 resource_info.map_limit=MagickMin(limit,StringToSizeType(value,100.0));
1679 case MemoryResource:
1681 value=GetPolicyValue(
"resource:memory");
1682 if (value == (
char *) NULL)
1683 resource_info.memory_limit=limit;
1685 resource_info.memory_limit=MagickMin(limit,StringToSizeType(value,
1689 case ThreadResource:
1691 value=GetPolicyValue(
"resource:thread");
1692 if (value == (
char *) NULL)
1693 resource_info.thread_limit=limit;
1695 resource_info.thread_limit=MagickMin(limit,StringToSizeType(value,
1697 if (resource_info.thread_limit > GetOpenMPMaximumThreads())
1698 resource_info.thread_limit=GetOpenMPMaximumThreads();
1700 if (resource_info.thread_limit == 0)
1701 resource_info.thread_limit=1;
1704 case ThrottleResource:
1706 value=GetPolicyValue(
"resource:throttle");
1707 if (value == (
char *) NULL)
1708 resource_info.throttle_limit=limit;
1710 resource_info.throttle_limit=MagickMax(limit,StringToSizeType(value,
1716 value=GetPolicyValue(
"resource:time");
1717 if (value == (
char *) NULL)
1718 resource_info.time_limit=limit;
1720 resource_info.time_limit=MagickMin(limit,(MagickSizeType)
1721 ParseMagickTimeToLive(value));
1726 value=GetPolicyValue(
"resource:width");
1727 if (value == (
char *) NULL)
1728 resource_info.width_limit=limit;
1730 resource_info.width_limit=MagickMin(limit,StringToSizeType(value,
1732 resource_info.width_limit=MagickMin(resource_info.width_limit,
1733 (MagickSizeType) MAGICK_SSIZE_MAX);
1742 if (value != (
char *) NULL)
1743 value=DestroyString(value);
1744 UnlockSemaphoreInfo(resource_semaphore[type]);