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))
114 *random_info = (RandomInfo *) NULL;
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 MagickResourceInfinity,
144 *resource_semaphore[] = {
160 *temporary_resources = (SplayTreeInfo *) NULL;
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 (resource_info.disk <= (MagickOffsetMax-request))
248 resource_info.disk+=request;
249 if ((limit == MagickResourceInfinity) ||
250 (resource_info.disk < (MagickOffsetType) limit))
253 resource_info.disk-=request;
255 if (logging != MagickFalse)
257 (void) FormatMagickSize(size,MagickTrue,resource_request);
258 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
259 MagickTrue,resource_current);
260 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
266 limit=resource_info.file_limit;
267 if (resource_info.file <= (MagickOffsetMax-request))
269 resource_info.file+=request;
270 if ((limit == MagickResourceInfinity) ||
271 (resource_info.file < (MagickOffsetType) limit))
274 if (logging != MagickFalse)
276 (void) FormatMagickSize(size,MagickFalse,resource_request);
277 (void) FormatMagickSize((MagickSizeType) resource_info.file,
278 MagickFalse,resource_current);
279 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
285 resource_info.height=(MagickOffsetType) size;
286 limit=resource_info.height_limit;
287 if ((limit == MagickResourceInfinity) || (size < limit))
289 if (logging != MagickFalse)
291 (void) FormatMagickSize(size,MagickFalse,resource_request);
292 (void) FormatMagickSize(size,MagickFalse,resource_current);
293 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
297 case ListLengthResource:
299 resource_info.list_length=(MagickOffsetType) size;
300 limit=resource_info.list_length_limit;
301 if ((limit == MagickResourceInfinity) || (size < limit))
303 if (logging != MagickFalse)
305 (void) FormatMagickSize(size,MagickFalse,resource_request);
306 (void) FormatMagickSize(size,MagickFalse,resource_current);
307 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
313 limit=resource_info.map_limit;
314 if (resource_info.map <= (MagickOffsetMax-request))
316 resource_info.map+=request;
317 if ((limit == MagickResourceInfinity) ||
318 (resource_info.map < (MagickOffsetType) limit))
321 resource_info.map-=request;
323 if (logging != MagickFalse)
325 (void) FormatMagickSize(size,MagickTrue,resource_request);
326 (void) FormatMagickSize((MagickSizeType) resource_info.map,
327 MagickTrue,resource_current);
328 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
334 limit=resource_info.memory_limit;
335 if (resource_info.memory <= (MagickOffsetMax-request))
337 resource_info.memory+=request;
338 if ((limit == MagickResourceInfinity) ||
339 (resource_info.memory < (MagickOffsetType) limit))
342 resource_info.memory-=request;
344 if (logging != MagickFalse)
346 (void) FormatMagickSize(size,MagickTrue,resource_request);
347 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
348 MagickTrue,resource_current);
349 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
355 limit=resource_info.thread_limit;
356 if ((limit == MagickResourceInfinity) ||
357 (resource_info.thread < (MagickOffsetType) limit))
359 if (logging != MagickFalse)
361 (void) FormatMagickSize(size,MagickFalse,resource_request);
362 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
363 MagickFalse,resource_current);
364 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
368 case ThrottleResource:
370 limit=resource_info.throttle_limit;
371 if ((limit == MagickResourceInfinity) ||
372 (resource_info.throttle < (MagickOffsetType) limit))
374 if (logging != MagickFalse)
376 (void) FormatMagickSize(size,MagickFalse,resource_request);
377 (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
378 MagickFalse,resource_current);
379 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
385 limit=resource_info.time_limit;
386 if (resource_info.time <= (MagickOffsetMax-request))
388 resource_info.time+=request;
389 if ((limit == MagickResourceInfinity) ||
390 (resource_info.time < (MagickOffsetType) limit))
393 resource_info.time-=request;
395 if (logging != MagickFalse)
397 (void) FormatMagickSize(size,MagickFalse,resource_request);
398 (void) FormatMagickSize((MagickSizeType) resource_info.time,
399 MagickFalse,resource_current);
400 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
406 resource_info.width=(MagickOffsetType) size;
407 limit=resource_info.width_limit;
408 if ((limit == MagickResourceInfinity) || (size < limit))
410 if (logging != MagickFalse)
412 (void) FormatMagickSize(size,MagickFalse,resource_request);
413 (void) FormatMagickSize(size,MagickFalse,resource_current);
414 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
429 UnlockSemaphoreInfo(resource_semaphore[type]);
434 if (logging != MagickFalse)
436 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
437 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
438 resource_request,resource_current,resource_limit);
463MagickExport
void AsynchronousResourceComponentTerminus(
void)
468 if (temporary_resources == (SplayTreeInfo *) NULL)
473 ResetSplayTreeIterator(temporary_resources);
474 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
475 while (path != (
const char *) NULL)
477 (void) ShredFile(path);
478 (void) remove_utf8(path);
479 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
508static void *DestroyTemporaryResources(
void *temporary_resource)
510 (void) ShredFile((
char *) temporary_resource);
511 (void) remove_utf8((
char *) temporary_resource);
512 temporary_resource=DestroyString((
char *) temporary_resource);
513 return((
void *) NULL);
516MagickExport MagickBooleanType GetPathTemplate(
char *path)
531 (void) FormatLocaleString(path,MaxTextExtent,
"magick-" MagickPathTemplate);
532 exception=AcquireExceptionInfo();
533 directory=(
char *) GetImageRegistry(StringRegistryType,
"temporary-path",
535 exception=DestroyExceptionInfo(exception);
536 if (directory == (
char *) NULL)
537 directory=GetEnvironmentValue(
"MAGICK_TEMPORARY_PATH");
538 if (directory == (
char *) NULL)
539 directory=GetEnvironmentValue(
"MAGICK_TMPDIR");
540 if (directory == (
char *) NULL)
541 directory=GetEnvironmentValue(
"TMPDIR");
542#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) || defined(__CYGWIN__)
543 if (directory == (
char *) NULL)
544 directory=GetEnvironmentValue(
"TMP");
545 if (directory == (
char *) NULL)
546 directory=GetEnvironmentValue(
"TEMP");
549 if (directory == (
char *) NULL)
550 directory=GetEnvironmentValue(
"MTMPDIR");
553 if (directory == (
char *) NULL)
554 directory=ConstantString(P_tmpdir);
556 if (directory == (
char *) NULL)
558 value=GetPolicyValue(
"resource:temporary-path");
559 if (value != (
char *) NULL)
561 (void) CloneString(&directory,value);
562 value=DestroyString(value);
564 if (strlen(directory) > (MaxTextExtent-25))
566 directory=DestroyString(directory);
569 status=GetPathAttributes(directory,&attributes);
570 if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
572 directory=DestroyString(directory);
575 if (directory[strlen(directory)-1] == *DirectorySeparator)
576 (void) FormatLocaleString(path,MaxTextExtent,
"%smagick-" MagickPathTemplate,
579 (
void) FormatLocaleString(path,MaxTextExtent,
"%s%smagick-"
580 MagickPathTemplate,directory,DirectorySeparator);
581 directory=DestroyString(directory);
582#if defined(MAGICKCORE_WINDOWS_SUPPORT)
591 for (p=(path[1] == *DirectorySeparator ? path+2 : path); *p !=
'\0'; p++)
592 if (*p == *DirectorySeparator)
599MagickExport
int AcquireUniqueFileResource(
char *path)
601#if !defined(O_NOFOLLOW)
605# define TMP_MAX 238328
619 portable_filename[65] =
620 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
628 assert(path != (
char *) NULL);
629 if ((GetLogEventMask() & ResourceEvent) != 0)
630 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"...");
631 if (random_info == (RandomInfo *) NULL)
633 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
634 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
635 LockSemaphoreInfo(resource_semaphore[FileResource]);
636 if (random_info == (RandomInfo *) NULL)
637 random_info=AcquireRandomInfo();
638 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
641 for (i=0; i < (ssize_t) TMP_MAX; i++)
649 (void) GetPathTemplate(path);
650 key=GetRandomKey(random_info,strlen(MagickPathTemplate)-6);
651 p=path+strlen(path)-strlen(MagickPathTemplate);
652 datum=GetStringInfoDatum(key);
653 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
655 c=(int) (datum[j] & 0x3f);
656 *p++=portable_filename[c];
658 key=DestroyStringInfo(key);
659#if defined(MAGICKCORE_HAVE_MKSTEMP)
663#if defined(MAGICKCORE_HAVE_FCHMOD)
664 (void) fchmod(file,0600);
667 setmode(file,O_BINARY);
672 key=GetRandomKey(random_info,strlen(MagickPathTemplate));
673 p=path+strlen(path)-strlen(MagickPathTemplate);
674 datum=GetStringInfoDatum(key);
675 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
677 c=(int) (datum[j] & 0x3f);
678 *p++=portable_filename[c];
680 key=DestroyStringInfo(key);
681 file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
683 if ((file >= 0) || (errno != EEXIST))
686 if ((GetLogEventMask() & ResourceEvent) != 0)
687 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Acquire %s",path);
690 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
691 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
692 LockSemaphoreInfo(resource_semaphore[FileResource]);
693 if (temporary_resources == (SplayTreeInfo *) NULL)
694 temporary_resources=NewSplayTree(CompareSplayTreeString,
695 DestroyTemporaryResources,(
void *(*)(
void *)) NULL);
696 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
697 (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
698 (
const void *) NULL);
724MagickExport MagickSizeType GetMagickResource(
const ResourceType type)
739 ActivateSemaphoreInfo(&resource_semaphore[type]);
740 LockSemaphoreInfo(resource_semaphore[type]);
749 resource=(MagickSizeType) resource_info.area;
754 resource=(MagickSizeType) resource_info.disk;
759 resource=(MagickSizeType) resource_info.file;
764 resource=(MagickSizeType) resource_info.height;
767 case ListLengthResource:
769 resource=(MagickSizeType) resource_info.list_length;
774 resource=(MagickSizeType) resource_info.map;
779 resource=(MagickSizeType) resource_info.memory;
784 resource=(MagickSizeType) resource_info.thread;
787 case ThrottleResource:
789 resource=(MagickSizeType) resource_info.throttle;
794 resource=(MagickSizeType) resource_info.time;
799 resource=(MagickSizeType) resource_info.width;
813 UnlockSemaphoreInfo(resource_semaphore[type]);
843MagickExport MagickSizeType GetMagickResourceLimit(
const ResourceType type)
849 if (type >= NumberOfResourceTypes)
852 ActivateSemaphoreInfo(&resource_semaphore[type]);
853 LockSemaphoreInfo(resource_semaphore[type]);
858 resource=resource_info.area_limit;
863 resource=resource_info.disk_limit;
868 resource=resource_info.file_limit;
873 resource=resource_info.height_limit;
876 case ListLengthResource:
878 resource=resource_info.list_length_limit;
883 resource=resource_info.memory_limit;
888 resource=resource_info.map_limit;
893 resource=resource_info.thread_limit;
896 case ThrottleResource:
898 resource=resource_info.throttle_limit;
903 resource=resource_info.time_limit;
908 resource=resource_info.width_limit;
914 UnlockSemaphoreInfo(resource_semaphore[type]);
944static ssize_t FormatPixelSize(
const MagickSizeType size,
945 const MagickBooleanType bi,
char *format)
962 "",
"Ki",
"Mi",
"Gi",
"Ti",
"Pi",
"Ei",
"Zi",
"Yi",
"Ri",
"Qi", (
char *) NULL
964 *traditional_units[] =
966 "",
"K",
"M",
"G",
"T",
"P",
"E",
"Z",
"Y",
"R",
"Q", (
char *) NULL
970 units=traditional_units;
971 if (bi != MagickFalse)
976#if defined(_MSC_VER) && (_MSC_VER == 1200)
977 length=(double) ((MagickOffsetType) size);
979 length=(double) size;
981 for (i=0; (length >= bytes) && (units[i+1] != (
const char *) NULL); i++)
984 for (j=2; j < 12; j++)
986 count=FormatLocaleString(format,MaxTextExtent,
"%.*g%sP",(
int) (i+j),length,
988 if (strchr(format,
'+') == (
char *) NULL)
994static void FormatTimeToLive(
const MagickSizeType ttl,
char *timeString)
1006 seconds=ttl % 31536000;
1009 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld years",years);
1013 seconds=ttl % 2628000;
1016 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld months",
1021 seconds=ttl % 604800;
1024 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld weeks",weeks);
1028 seconds=ttl % 86400;
1031 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld days",days);
1038 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld hours",hours);
1045 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld minutes",
1049 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld seconds",ttl);
1052MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
1053 ExceptionInfo *magick_unused(exception))
1056 area_limit[MaxTextExtent],
1057 disk_limit[MaxTextExtent],
1058 height_limit[MaxTextExtent],
1059 list_length_limit[MaxTextExtent],
1060 map_limit[MaxTextExtent],
1061 memory_limit[MaxTextExtent],
1062 time_limit[MaxTextExtent],
1063 width_limit[MaxTextExtent];
1065 magick_unreferenced(exception);
1067 if (file == (
const FILE *) NULL)
1069 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1070 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1071 LockSemaphoreInfo(resource_semaphore[FileResource]);
1072 (void) FormatPixelSize(resource_info.width_limit,MagickFalse,width_limit);
1073 (void) FormatPixelSize(resource_info.height_limit,MagickFalse,height_limit);
1074 (void) FormatPixelSize(resource_info.area_limit,MagickFalse,area_limit);
1075 (void) CopyMagickString(list_length_limit,
"unlimited",MaxTextExtent);
1076 if (resource_info.list_length_limit != MagickResourceInfinity)
1077 (void) FormatMagickSize(resource_info.list_length_limit,MagickTrue,
1079 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
1080 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,map_limit);
1081 (void) CopyMagickString(disk_limit,
"unlimited",MaxTextExtent);
1082 if (resource_info.disk_limit != MagickResourceInfinity)
1083 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,disk_limit);
1084 (void) CopyMagickString(time_limit,
"unlimited",MaxTextExtent);
1085 if (resource_info.time_limit != MagickResourceInfinity)
1086 FormatTimeToLive(resource_info.time_limit,time_limit);
1087 (void) FormatLocaleFile(file,
"Resource limits:\n");
1088 (void) FormatLocaleFile(file,
" Width: %s\n",width_limit);
1089 (void) FormatLocaleFile(file,
" Height: %s\n",height_limit);
1090 (void) FormatLocaleFile(file,
" List length: %s\n",list_length_limit);
1091 (void) FormatLocaleFile(file,
" Area: %s\n",area_limit);
1092 (void) FormatLocaleFile(file,
" Memory: %s\n",memory_limit);
1093 (void) FormatLocaleFile(file,
" Map: %s\n",map_limit);
1094 (void) FormatLocaleFile(file,
" Disk: %s\n",disk_limit);
1095 (void) FormatLocaleFile(file,
" File: %.20g\n",(
double) ((MagickOffsetType)
1096 resource_info.file_limit));
1097 (void) FormatLocaleFile(file,
" Thread: %.20g\n",(
double) ((MagickOffsetType)
1098 resource_info.thread_limit));
1099 (void) FormatLocaleFile(file,
" Throttle: %.20g\n",(
double)
1100 ((MagickOffsetType) resource_info.throttle_limit));
1101 (void) FormatLocaleFile(file,
" Time: %s\n",time_limit);
1102 (void) fflush(file);
1103 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1132MagickExport
void RelinquishMagickResource(
const ResourceType type,
1133 const MagickSizeType size)
1136 resource_current[MaxTextExtent],
1137 resource_limit[MaxTextExtent],
1138 resource_request[MaxTextExtent];
1143 logging=(GetLogEventMask() & ResourceEvent) != 0 ? MagickTrue : MagickFalse;
1144 if (logging != MagickFalse)
1145 (void) FormatMagickSize(size,MagickFalse,resource_request);
1151 case MemoryResource:
1155 ActivateSemaphoreInfo(&resource_semaphore[type]);
1156 LockSemaphoreInfo(resource_semaphore[type]);
1165 resource_info.area=(MagickOffsetType) size;
1166 if (logging != MagickFalse)
1168 (void) FormatMagickSize((MagickSizeType) resource_info.area,
1169 MagickFalse,resource_current);
1170 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
1177 resource_info.disk-=size;
1178 assert(resource_info.disk >= 0);
1179 if (logging != MagickFalse)
1181 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
1182 MagickTrue,resource_current);
1183 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
1190 resource_info.file-=size;
1191 assert(resource_info.file >= 0);
1192 if (logging != MagickFalse)
1194 (void) FormatMagickSize((MagickSizeType) resource_info.file,
1195 MagickFalse,resource_current);
1196 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
1197 MagickFalse,resource_limit);
1201 case HeightResource:
1203 resource_info.height=(MagickOffsetType) size;
1204 if (logging != MagickFalse)
1206 (void) FormatMagickSize((MagickSizeType) resource_info.height,
1207 MagickFalse,resource_current);
1208 (void) FormatMagickSize(resource_info.height_limit,MagickFalse,
1213 case ListLengthResource:
1215 resource_info.list_length=(MagickOffsetType) size;
1216 if (logging != MagickFalse)
1218 (void) FormatMagickSize((MagickSizeType) resource_info.list_length,
1219 MagickFalse,resource_current);
1220 (void) FormatMagickSize(resource_info.list_length_limit,MagickFalse,
1227 resource_info.map-=size;
1228 assert(resource_info.map >= 0);
1229 if (logging != MagickFalse)
1231 (void) FormatMagickSize((MagickSizeType) resource_info.map,
1232 MagickTrue,resource_current);
1233 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
1238 case MemoryResource:
1240 resource_info.memory-=size;
1241 assert(resource_info.memory >= 0);
1242 if (logging != MagickFalse)
1244 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
1245 MagickTrue,resource_current);
1246 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
1251 case ThreadResource:
1253 if (logging != MagickFalse)
1255 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
1256 MagickFalse,resource_current);
1257 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
1258 MagickFalse,resource_limit);
1262 case ThrottleResource:
1264 if (logging != MagickFalse)
1266 (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
1267 MagickFalse,resource_current);
1268 (void) FormatMagickSize((MagickSizeType) resource_info.throttle_limit,
1269 MagickFalse,resource_limit);
1275 resource_info.time-=size;
1276 assert(resource_info.time >= 0);
1277 if (logging != MagickFalse)
1279 (void) FormatMagickSize((MagickSizeType) resource_info.time,
1280 MagickFalse,resource_current);
1281 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
1282 MagickFalse,resource_limit);
1288 resource_info.width=(MagickOffsetType) size;
1289 if (logging != MagickFalse)
1291 (void) FormatMagickSize((MagickSizeType) resource_info.width,
1292 MagickFalse,resource_current);
1293 (void) FormatMagickSize(resource_info.width_limit,MagickFalse,
1306 case MemoryResource:
1309 UnlockSemaphoreInfo(resource_semaphore[type]);
1314 if (logging != MagickFalse)
1316 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
1317 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
1318 resource_request,resource_current,resource_limit);
1344MagickExport MagickBooleanType RelinquishUniqueFileResource(
const char *path)
1347 cache_path[MaxTextExtent];
1352 assert(path != (
const char *) NULL);
1354 if ((GetLogEventMask() & ResourceEvent) != 0)
1355 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Relinquish %s",path);
1356 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1357 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1358 LockSemaphoreInfo(resource_semaphore[FileResource]);
1359 if (temporary_resources != (SplayTreeInfo *) NULL)
1360 status=DeleteNodeFromSplayTree(temporary_resources, (
const void *) path);
1361 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1362 (void) CopyMagickString(cache_path,path,MaxTextExtent);
1363 AppendImageFormat(
"cache",cache_path);
1364 if (access_utf8(cache_path,F_OK) == 0)
1366 status=ShredFile(cache_path);
1367 status|=remove_utf8(cache_path);
1369 if (status == MagickFalse)
1371 status=ShredFile(path);
1372 status|=remove_utf8(path);
1374 return(status == 0 ? MagickFalse : MagickTrue);
1395MagickExport MagickBooleanType ResourceComponentGenesis(
void)
1413 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1415 ActivateSemaphoreInfo(&resource_semaphore[i]);
1416 (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
1417 limit=GetEnvironmentValue(
"MAGICK_WIDTH_LIMIT");
1418 if (limit != (
char *) NULL)
1420 (void) SetMagickResourceLimit(WidthResource,StringToSizeType(limit,
1422 limit=DestroyString(limit);
1424 (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
1425 limit=GetEnvironmentValue(
"MAGICK_HEIGHT_LIMIT");
1426 if (limit != (
char *) NULL)
1428 (void) SetMagickResourceLimit(HeightResource,StringToSizeType(limit,
1430 limit=DestroyString(limit);
1432 pagesize=GetMagickPageSize();
1434#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1435 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1436#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1440 memory=(MagickSizeType) pages*pagesize;
1441 if ((pagesize <= 0) || (pages <= 0))
1442 memory=2048UL*1024UL*1024UL;
1443#if defined(MAGICKCORE_PixelCacheThreshold)
1444 memory=StringToMagickSizeType(MAGICKCORE_PixelCacheThreshold,100.0);
1446 (void) SetMagickResourceLimit(AreaResource,4*memory);
1447 limit=GetEnvironmentValue(
"MAGICK_AREA_LIMIT");
1448 if (limit != (
char *) NULL)
1450 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
1451 limit=DestroyString(limit);
1453 (void) SetMagickResourceLimit(MemoryResource,memory);
1454 limit=GetEnvironmentValue(
"MAGICK_MEMORY_LIMIT");
1455 if (limit != (
char *) NULL)
1457 (void) SetMagickResourceLimit(MemoryResource,
1458 StringToSizeType(limit,100.0));
1459 limit=DestroyString(limit);
1461 (void) SetMagickResourceLimit(MapResource,2*memory);
1462 limit=GetEnvironmentValue(
"MAGICK_MAP_LIMIT");
1463 if (limit != (
char *) NULL)
1465 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
1466 limit=DestroyString(limit);
1468 (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
1469 limit=GetEnvironmentValue(
"MAGICK_DISK_LIMIT");
1470 if (limit != (
char *) NULL)
1472 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
1473 limit=DestroyString(limit);
1476#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1477 files=(ssize_t) sysconf(_SC_OPEN_MAX);
1479#if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1485 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1486 files=(ssize_t) resources.rlim_cur;
1489#if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1491 files=(ssize_t) getdtablesize();
1495 (void) SetMagickResourceLimit(FileResource,MagickMax((
size_t)
1497 limit=GetEnvironmentValue(
"MAGICK_FILE_LIMIT");
1498 if (limit != (
char *) NULL)
1500 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
1501 limit=DestroyString(limit);
1503 number_threads=(ssize_t) GetOpenMPMaximumThreads();
1504 if (number_threads > 1)
1506 (void) SetMagickResourceLimit(ThreadResource,(
size_t) number_threads);
1507 limit=GetEnvironmentValue(
"MAGICK_THREAD_LIMIT");
1508 if (limit != (
char *) NULL)
1510 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
1512 limit=DestroyString(limit);
1514 (void) SetMagickResourceLimit(ThrottleResource,0);
1515 limit=GetEnvironmentValue(
"MAGICK_THROTTLE_LIMIT");
1516 if (limit != (
char *) NULL)
1518 (void) SetMagickResourceLimit(ThrottleResource,StringToSizeType(limit,
1520 limit=DestroyString(limit);
1522 (void) SetMagickResourceLimit(TimeResource,MagickResourceInfinity);
1523 limit=GetEnvironmentValue(
"MAGICK_TIME_LIMIT");
1524 if (limit != (
char *) NULL)
1526 (void) SetMagickResourceLimit(TimeResource,(MagickSizeType)
1527 ParseMagickTimeToLive(limit));
1528 limit=DestroyString(limit);
1530 (void) SetMagickResourceLimit(ListLengthResource,MagickResourceInfinity);
1531 limit=GetEnvironmentValue(
"MAGICK_LIST_LENGTH_LIMIT");
1532 if (limit != (
char *) NULL)
1534 (void) SetMagickResourceLimit(ListLengthResource,
1535 StringToSizeType(limit,100.0));
1536 limit=DestroyString(limit);
1559MagickExport
void ResourceComponentTerminus(
void)
1564 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1566 ActivateSemaphoreInfo(&resource_semaphore[i]);
1567 LockSemaphoreInfo(resource_semaphore[FileResource]);
1568 if (temporary_resources != (SplayTreeInfo *) NULL)
1569 temporary_resources=DestroySplayTree(temporary_resources);
1570 if (random_info != (RandomInfo *) NULL)
1571 random_info=DestroyRandomInfo(random_info);
1572 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1573 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1574 DestroySemaphoreInfo(&resource_semaphore[i]);
1603MagickExport MagickBooleanType SetMagickResourceLimit(
const ResourceType type,
1604 const MagickSizeType limit)
1614 ActivateSemaphoreInfo(&resource_semaphore[type]);
1615 LockSemaphoreInfo(resource_semaphore[type]);
1616 value=(
char *) NULL;
1621 value=GetPolicyValue(
"resource:area");
1622 if (value == (
char *) NULL)
1623 resource_info.area_limit=limit;
1625 resource_info.area_limit=MagickMin(limit,StringToSizeType(value,100.0));
1630 value=GetPolicyValue(
"resource:disk");
1631 if (value == (
char *) NULL)
1632 resource_info.disk_limit=limit;
1634 resource_info.disk_limit=MagickMin(limit,StringToSizeType(value,100.0));
1639 value=GetPolicyValue(
"resource:file");
1640 if (value == (
char *) NULL)
1641 resource_info.file_limit=limit;
1643 resource_info.file_limit=MagickMin(limit,StringToSizeType(value,100.0));
1646 case HeightResource:
1648 value=GetPolicyValue(
"resource:height");
1649 if (value == (
char *) NULL)
1650 resource_info.height_limit=limit;
1652 resource_info.height_limit=MagickMin(limit,StringToSizeType(value,
1654 resource_info.height_limit=MagickMin(resource_info.height_limit,
1655 (MagickSizeType) MAGICK_SSIZE_MAX);
1658 case ListLengthResource:
1660 value=GetPolicyValue(
"resource:list-length");
1661 if (value == (
char *) NULL)
1662 resource_info.list_length_limit=limit;
1664 resource_info.list_length_limit=MagickMin(limit,
1665 StringToSizeType(value,100.0));
1670 value=GetPolicyValue(
"resource:map");
1671 if (value == (
char *) NULL)
1672 resource_info.map_limit=limit;
1674 resource_info.map_limit=MagickMin(limit,StringToSizeType(value,100.0));
1677 case MemoryResource:
1679 value=GetPolicyValue(
"resource:memory");
1680 if (value == (
char *) NULL)
1681 resource_info.memory_limit=limit;
1683 resource_info.memory_limit=MagickMin(limit,StringToSizeType(value,
1687 case ThreadResource:
1689 value=GetPolicyValue(
"resource:thread");
1690 if (value == (
char *) NULL)
1691 resource_info.thread_limit=limit;
1693 resource_info.thread_limit=MagickMin(limit,StringToSizeType(value,
1695 if (resource_info.thread_limit > GetOpenMPMaximumThreads())
1696 resource_info.thread_limit=GetOpenMPMaximumThreads();
1698 if (resource_info.thread_limit == 0)
1699 resource_info.thread_limit=1;
1702 case ThrottleResource:
1704 value=GetPolicyValue(
"resource:throttle");
1705 if (value == (
char *) NULL)
1706 resource_info.throttle_limit=limit;
1708 resource_info.throttle_limit=MagickMax(limit,StringToSizeType(value,
1714 value=GetPolicyValue(
"resource:time");
1715 if (value == (
char *) NULL)
1716 resource_info.time_limit=limit;
1718 resource_info.time_limit=MagickMin(limit,(MagickSizeType)
1719 ParseMagickTimeToLive(value));
1724 value=GetPolicyValue(
"resource:width");
1725 if (value == (
char *) NULL)
1726 resource_info.width_limit=limit;
1728 resource_info.width_limit=MagickMin(limit,StringToSizeType(value,
1730 resource_info.width_limit=MagickMin(resource_info.width_limit,
1731 (MagickSizeType) MAGICK_SSIZE_MAX);
1740 if (value != (
char *) NULL)
1741 value=DestroyString(value);
1742 UnlockSemaphoreInfo(resource_semaphore[type]);