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/token.h"
66 #include "magick/utility.h"
67 #include "magick/utility-private.h"
72 #define MagickPathTemplate "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
73 #define NumberOfResourceTypes \
74 (sizeof(resource_semaphore)/sizeof(*resource_semaphore))
117 MagickULLConstant(0),
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),
130 MagickResourceInfinity,
131 MagickULLConstant(3072)*1024*1024,
132 MagickULLConstant(1536)*1024*1024,
133 MagickULLConstant(3072)*1024*1024,
134 MagickResourceInfinity,
135 MagickULLConstant(768),
136 MagickULLConstant(1),
137 MagickULLConstant(0),
138 MagickResourceInfinity
142 *resource_semaphore[] = {
187 MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
188 const MagickSizeType size)
191 resource_current[MaxTextExtent] =
"",
192 resource_limit[MaxTextExtent] =
"",
193 resource_request[MaxTextExtent] =
"";
205 request=(MagickOffsetType) size;
209 logging=(GetLogEventMask() & ResourceEvent) != 0 ? MagickTrue : MagickFalse;
219 ActivateSemaphoreInfo(&resource_semaphore[type]);
220 LockSemaphoreInfo(resource_semaphore[type]);
229 resource_info.area=(MagickOffsetType) size;
230 limit=resource_info.area_limit;
231 if ((limit == MagickResourceInfinity) || (size < limit))
233 if (logging != MagickFalse)
235 (void) FormatMagickSize(size,MagickFalse,resource_request);
236 (void) FormatMagickSize(size,MagickFalse,resource_current);
237 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
243 limit=resource_info.disk_limit;
244 if (((MagickSizeType) resource_info.disk+request) >
245 (MagickSizeType) resource_info.disk)
247 resource_info.disk+=request;
248 if ((limit == MagickResourceInfinity) ||
249 (resource_info.disk < (MagickOffsetType) limit))
252 resource_info.disk-=request;
254 if (logging != MagickFalse)
256 (void) FormatMagickSize(size,MagickTrue,resource_request);
257 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
258 MagickTrue,resource_current);
259 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
265 limit=resource_info.file_limit;
266 if (((MagickSizeType) resource_info.file+request) >
267 (MagickSizeType) resource_info.file)
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 (((MagickSizeType) resource_info.map+request) >
315 (MagickSizeType) resource_info.map)
317 resource_info.map+=request;
318 if ((limit == MagickResourceInfinity) ||
319 (resource_info.map < (MagickOffsetType) limit))
322 resource_info.map-=request;
324 if (logging != MagickFalse)
326 (void) FormatMagickSize(size,MagickTrue,resource_request);
327 (void) FormatMagickSize((MagickSizeType) resource_info.map,
328 MagickTrue,resource_current);
329 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
335 limit=resource_info.memory_limit;
336 if (((MagickSizeType) resource_info.memory+request) >
337 (MagickSizeType) resource_info.memory)
339 resource_info.memory+=request;
340 if ((limit == MagickResourceInfinity) ||
341 (resource_info.memory < (MagickOffsetType) limit))
344 resource_info.memory-=request;
346 if (logging != MagickFalse)
348 (void) FormatMagickSize(size,MagickTrue,resource_request);
349 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
350 MagickTrue,resource_current);
351 (void) FormatMagickSize(limit,MagickTrue,resource_limit);
357 limit=resource_info.thread_limit;
358 if ((limit == MagickResourceInfinity) ||
359 (resource_info.thread < (MagickOffsetType) limit))
361 if (logging != MagickFalse)
363 (void) FormatMagickSize(size,MagickFalse,resource_request);
364 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
365 MagickFalse,resource_current);
366 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
370 case ThrottleResource:
372 limit=resource_info.throttle_limit;
373 if ((limit == MagickResourceInfinity) ||
374 (resource_info.throttle < (MagickOffsetType) limit))
376 if (logging != MagickFalse)
378 (void) FormatMagickSize(size,MagickFalse,resource_request);
379 (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
380 MagickFalse,resource_current);
381 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
387 limit=resource_info.time_limit;
388 if (((MagickSizeType) resource_info.time+request) >
389 (MagickSizeType) resource_info.time)
391 resource_info.time+=request;
392 if ((limit == MagickResourceInfinity) ||
393 ((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);
466 MagickExport
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);
511 static 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);
519 MagickExport 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");
555 #if defined(P_tmpdir)
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)
602 MagickExport
int AcquireUniqueFileResource(
char *path)
604 #if !defined(O_NOFOLLOW)
607 #if !defined(TMP_MAX)
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);
727 MagickExport 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]);
846 MagickExport 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]);
945 static ssize_t FormatPixelSize(
const MagickSizeType size,
946 const MagickBooleanType bi,
char *format)
965 "",
"Ki",
"Mi",
"Gi",
"Ti",
"Pi",
"Ei",
"Zi",
"Yi", (
char *) NULL
967 *traditional_units[] =
969 "",
"K",
"M",
"G",
"T",
"P",
"E",
"Z",
"Y", (
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 MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
1001 area_limit[MaxTextExtent],
1002 disk_limit[MaxTextExtent],
1003 height_limit[MaxTextExtent],
1004 list_length_limit[MaxTextExtent],
1005 map_limit[MaxTextExtent],
1006 memory_limit[MaxTextExtent],
1007 time_limit[MaxTextExtent],
1008 width_limit[MaxTextExtent];
1010 magick_unreferenced(exception);
1012 if (file == (
const FILE *) NULL)
1014 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1015 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1016 LockSemaphoreInfo(resource_semaphore[FileResource]);
1017 (void) FormatPixelSize(resource_info.width_limit,MagickFalse,width_limit);
1018 (void) FormatPixelSize(resource_info.height_limit,MagickFalse,height_limit);
1019 (void) FormatPixelSize(resource_info.area_limit,MagickFalse,area_limit);
1020 (void) CopyMagickString(list_length_limit,
"unlimited",MaxTextExtent);
1021 if (resource_info.list_length_limit != MagickResourceInfinity)
1022 (void) FormatMagickSize(resource_info.list_length_limit,MagickTrue,
1024 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
1025 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,map_limit);
1026 (void) CopyMagickString(disk_limit,
"unlimited",MaxTextExtent);
1027 if (resource_info.disk_limit != MagickResourceInfinity)
1028 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,disk_limit);
1029 (void) CopyMagickString(time_limit,
"unlimited",MaxTextExtent);
1030 if (resource_info.time_limit != MagickResourceInfinity)
1031 (void) FormatLocaleString(time_limit,MaxTextExtent,
"%.20g",(
double)
1032 ((MagickOffsetType) resource_info.time_limit));
1033 (void) FormatLocaleFile(file,
"Resource limits:\n");
1034 (void) FormatLocaleFile(file,
" Width: %s\n",width_limit);
1035 (void) FormatLocaleFile(file,
" Height: %s\n",height_limit);
1036 (void) FormatLocaleFile(file,
" List length: %s\n",list_length_limit);
1037 (void) FormatLocaleFile(file,
" Area: %s\n",area_limit);
1038 (void) FormatLocaleFile(file,
" Memory: %s\n",memory_limit);
1039 (void) FormatLocaleFile(file,
" Map: %s\n",map_limit);
1040 (void) FormatLocaleFile(file,
" Disk: %s\n",disk_limit);
1041 (void) FormatLocaleFile(file,
" File: %.20g\n",(
double) ((MagickOffsetType)
1042 resource_info.file_limit));
1043 (void) FormatLocaleFile(file,
" Thread: %.20g\n",(
double) ((MagickOffsetType)
1044 resource_info.thread_limit));
1045 (void) FormatLocaleFile(file,
" Throttle: %.20g\n",(
double)
1046 ((MagickOffsetType) resource_info.throttle_limit));
1047 (void) FormatLocaleFile(file,
" Time: %s\n",time_limit);
1048 (void) fflush(file);
1049 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1078 MagickExport
void RelinquishMagickResource(
const ResourceType type,
1079 const MagickSizeType size)
1082 resource_current[MaxTextExtent],
1083 resource_limit[MaxTextExtent],
1084 resource_request[MaxTextExtent];
1089 logging=(GetLogEventMask() & ResourceEvent) != 0 ? MagickTrue : MagickFalse;
1090 if (logging != MagickFalse)
1091 (void) FormatMagickSize(size,MagickFalse,resource_request);
1097 case MemoryResource:
1101 ActivateSemaphoreInfo(&resource_semaphore[type]);
1102 LockSemaphoreInfo(resource_semaphore[type]);
1111 resource_info.area=(MagickOffsetType) size;
1112 if (logging != MagickFalse)
1114 (void) FormatMagickSize((MagickSizeType) resource_info.area,
1115 MagickFalse,resource_current);
1116 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
1123 resource_info.disk-=size;
1124 assert(resource_info.disk >= 0);
1125 if (logging != MagickFalse)
1127 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
1128 MagickTrue,resource_current);
1129 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
1136 resource_info.file-=size;
1137 assert(resource_info.file >= 0);
1138 if (logging != MagickFalse)
1140 (void) FormatMagickSize((MagickSizeType) resource_info.file,
1141 MagickFalse,resource_current);
1142 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
1143 MagickFalse,resource_limit);
1147 case HeightResource:
1149 resource_info.height=(MagickOffsetType) size;
1150 if (logging != MagickFalse)
1152 (void) FormatMagickSize((MagickSizeType) resource_info.height,
1153 MagickFalse,resource_current);
1154 (void) FormatMagickSize(resource_info.height_limit,MagickFalse,
1159 case ListLengthResource:
1161 resource_info.list_length=(MagickOffsetType) size;
1162 if (logging != MagickFalse)
1164 (void) FormatMagickSize((MagickSizeType) resource_info.list_length,
1165 MagickFalse,resource_current);
1166 (void) FormatMagickSize(resource_info.list_length_limit,MagickFalse,
1173 resource_info.map-=size;
1174 assert(resource_info.map >= 0);
1175 if (logging != MagickFalse)
1177 (void) FormatMagickSize((MagickSizeType) resource_info.map,
1178 MagickTrue,resource_current);
1179 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
1184 case MemoryResource:
1186 resource_info.memory-=size;
1187 assert(resource_info.memory >= 0);
1188 if (logging != MagickFalse)
1190 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
1191 MagickTrue,resource_current);
1192 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
1197 case ThreadResource:
1199 if (logging != MagickFalse)
1201 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
1202 MagickFalse,resource_current);
1203 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
1204 MagickFalse,resource_limit);
1208 case ThrottleResource:
1210 if (logging != MagickFalse)
1212 (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
1213 MagickFalse,resource_current);
1214 (void) FormatMagickSize((MagickSizeType) resource_info.throttle_limit,
1215 MagickFalse,resource_limit);
1221 resource_info.time-=size;
1222 assert(resource_info.time >= 0);
1223 if (logging != MagickFalse)
1224 if (logging != MagickFalse)
1226 (void) FormatMagickSize((MagickSizeType) resource_info.time,
1227 MagickFalse,resource_current);
1228 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
1229 MagickFalse,resource_limit);
1235 resource_info.width=(MagickOffsetType) size;
1236 if (logging != MagickFalse)
1238 (void) FormatMagickSize((MagickSizeType) resource_info.width,
1239 MagickFalse,resource_current);
1240 (void) FormatMagickSize(resource_info.width_limit,MagickFalse,
1253 case MemoryResource:
1256 UnlockSemaphoreInfo(resource_semaphore[type]);
1261 if (logging != MagickFalse)
1263 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
1264 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
1265 resource_request,resource_current,resource_limit);
1291 MagickExport MagickBooleanType RelinquishUniqueFileResource(
const char *path)
1294 cache_path[MaxTextExtent];
1299 assert(path != (
const char *) NULL);
1301 if ((GetLogEventMask() & ResourceEvent) != 0)
1302 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Relinquish %s",path);
1303 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1304 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1305 LockSemaphoreInfo(resource_semaphore[FileResource]);
1307 status=DeleteNodeFromSplayTree(temporary_resources, (
const void *) path);
1308 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1309 (void) CopyMagickString(cache_path,path,MaxTextExtent);
1310 AppendImageFormat(
"cache",cache_path);
1311 if (access_utf8(cache_path,F_OK) == 0)
1313 status=ShredFile(cache_path);
1314 status|=remove_utf8(cache_path);
1316 if (status == MagickFalse)
1318 status=ShredFile(path);
1319 status|=remove_utf8(path);
1321 return(status == 0 ? MagickFalse : MagickTrue);
1342 MagickExport MagickBooleanType ResourceComponentGenesis(
void)
1361 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1363 ActivateSemaphoreInfo(&resource_semaphore[i]);
1364 (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
1365 limit=GetEnvironmentValue(
"MAGICK_WIDTH_LIMIT");
1366 if (limit != (
char *) NULL)
1368 (void) SetMagickResourceLimit(WidthResource,StringToSizeType(limit,
1370 limit=DestroyString(limit);
1372 (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
1373 limit=GetEnvironmentValue(
"MAGICK_HEIGHT_LIMIT");
1374 if (limit != (
char *) NULL)
1376 (void) SetMagickResourceLimit(HeightResource,StringToSizeType(limit,
1378 limit=DestroyString(limit);
1380 pagesize=GetMagickPageSize();
1382 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1383 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1384 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1388 memory=(MagickSizeType) pages*pagesize;
1389 if ((pagesize <= 0) || (pages <= 0))
1390 memory=2048UL*1024UL*1024UL;
1391 #if defined(PixelCacheThreshold)
1392 memory=PixelCacheThreshold;
1394 (void) SetMagickResourceLimit(AreaResource,2*memory);
1395 limit=GetEnvironmentValue(
"MAGICK_AREA_LIMIT");
1396 if (limit != (
char *) NULL)
1398 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
1399 limit=DestroyString(limit);
1401 (void) SetMagickResourceLimit(MemoryResource,memory);
1402 limit=GetEnvironmentValue(
"MAGICK_MEMORY_LIMIT");
1403 if (limit != (
char *) NULL)
1405 (void) SetMagickResourceLimit(MemoryResource,
1406 StringToSizeType(limit,100.0));
1407 limit=DestroyString(limit);
1409 (void) SetMagickResourceLimit(MapResource,2*memory);
1410 limit=GetEnvironmentValue(
"MAGICK_MAP_LIMIT");
1411 if (limit != (
char *) NULL)
1413 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
1414 limit=DestroyString(limit);
1416 (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
1417 limit=GetEnvironmentValue(
"MAGICK_DISK_LIMIT");
1418 if (limit != (
char *) NULL)
1420 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
1421 limit=DestroyString(limit);
1424 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1425 files=(ssize_t) sysconf(_SC_OPEN_MAX);
1427 #if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1433 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1434 files=(ssize_t) resources.rlim_cur;
1437 #if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1439 files=(ssize_t) getdtablesize();
1443 (void) SetMagickResourceLimit(FileResource,MagickMax((
size_t)
1445 limit=GetEnvironmentValue(
"MAGICK_FILE_LIMIT");
1446 if (limit != (
char *) NULL)
1448 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
1449 limit=DestroyString(limit);
1451 (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads());
1452 limit=GetEnvironmentValue(
"MAGICK_THREAD_LIMIT");
1453 if (limit != (
char *) NULL)
1455 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
1457 limit=DestroyString(limit);
1459 (void) SetMagickResourceLimit(ThrottleResource,0);
1460 limit=GetEnvironmentValue(
"MAGICK_THROTTLE_LIMIT");
1461 if (limit != (
char *) NULL)
1463 (void) SetMagickResourceLimit(ThrottleResource,StringToSizeType(limit,
1465 limit=DestroyString(limit);
1467 (void) SetMagickResourceLimit(TimeResource,MagickResourceInfinity);
1468 limit=GetEnvironmentValue(
"MAGICK_TIME_LIMIT");
1469 if (limit != (
char *) NULL)
1471 (void) SetMagickResourceLimit(TimeResource,StringToSizeType(limit,100.0));
1472 limit=DestroyString(limit);
1474 (void) SetMagickResourceLimit(ListLengthResource,MagickResourceInfinity);
1475 limit=GetEnvironmentValue(
"MAGICK_LIST_LENGTH_LIMIT");
1476 if (limit != (
char *) NULL)
1478 (void) SetMagickResourceLimit(ListLengthResource,
1479 StringToSizeType(limit,100.0));
1480 limit=DestroyString(limit);
1503 MagickExport
void ResourceComponentTerminus(
void)
1508 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1510 ActivateSemaphoreInfo(&resource_semaphore[i]);
1511 LockSemaphoreInfo(resource_semaphore[FileResource]);
1513 temporary_resources=DestroySplayTree(temporary_resources);
1515 random_info=DestroyRandomInfo(random_info);
1516 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1517 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1518 DestroySemaphoreInfo(&resource_semaphore[i]);
1547 MagickExport MagickBooleanType SetMagickResourceLimit(
const ResourceType type,
1548 const MagickSizeType limit)
1558 ActivateSemaphoreInfo(&resource_semaphore[type]);
1559 LockSemaphoreInfo(resource_semaphore[type]);
1560 value=(
char *) NULL;
1565 value=GetPolicyValue(
"resource:area");
1566 if (value == (
char *) NULL)
1567 resource_info.area_limit=limit;
1569 resource_info.area_limit=MagickMin(limit,StringToSizeType(value,100.0));
1574 value=GetPolicyValue(
"resource:disk");
1575 if (value == (
char *) NULL)
1576 resource_info.disk_limit=limit;
1578 resource_info.disk_limit=MagickMin(limit,StringToSizeType(value,100.0));
1583 value=GetPolicyValue(
"resource:file");
1584 if (value == (
char *) NULL)
1585 resource_info.file_limit=limit;
1587 resource_info.file_limit=MagickMin(limit,StringToSizeType(value,100.0));
1590 case HeightResource:
1592 value=GetPolicyValue(
"resource:height");
1593 if (value == (
char *) NULL)
1594 resource_info.height_limit=limit;
1596 resource_info.height_limit=MagickMin(limit,StringToSizeType(value,
1598 resource_info.height_limit=MagickMin(resource_info.height_limit,
1599 (MagickSizeType) MAGICK_SSIZE_MAX);
1602 case ListLengthResource:
1604 value=GetPolicyValue(
"resource:list-length");
1605 if (value == (
char *) NULL)
1606 resource_info.list_length_limit=limit;
1608 resource_info.list_length_limit=MagickMin(limit,
1609 StringToSizeType(value,100.0));
1614 value=GetPolicyValue(
"resource:map");
1615 if (value == (
char *) NULL)
1616 resource_info.map_limit=limit;
1618 resource_info.map_limit=MagickMin(limit,StringToSizeType(value,100.0));
1621 case MemoryResource:
1623 value=GetPolicyValue(
"resource:memory");
1624 if (value == (
char *) NULL)
1625 resource_info.memory_limit=limit;
1627 resource_info.memory_limit=MagickMin(limit,StringToSizeType(value,
1631 case ThreadResource:
1633 value=GetPolicyValue(
"resource:thread");
1634 if (value == (
char *) NULL)
1635 resource_info.thread_limit=limit;
1637 resource_info.thread_limit=MagickMin(limit,StringToSizeType(value,
1639 if (resource_info.thread_limit > GetOpenMPMaximumThreads())
1640 resource_info.thread_limit=GetOpenMPMaximumThreads();
1642 if (resource_info.thread_limit == 0)
1643 resource_info.thread_limit=1;
1646 case ThrottleResource:
1648 value=GetPolicyValue(
"resource:throttle");
1649 if (value == (
char *) NULL)
1650 resource_info.throttle_limit=limit;
1652 resource_info.throttle_limit=MagickMax(limit,StringToSizeType(value,
1658 value=GetPolicyValue(
"resource:time");
1659 if (value == (
char *) NULL)
1660 resource_info.time_limit=limit;
1662 resource_info.time_limit=MagickMin(limit,StringToSizeType(value,100.0));
1663 ResetPixelCacheEpoch();
1668 value=GetPolicyValue(
"resource:width");
1669 if (value == (
char *) NULL)
1670 resource_info.width_limit=limit;
1672 resource_info.width_limit=MagickMin(limit,StringToSizeType(value,
1674 resource_info.width_limit=MagickMin(resource_info.width_limit,
1675 (MagickSizeType) MAGICK_SSIZE_MAX);
1684 if (value != (
char *) NULL)
1685 value=DestroyString(value);
1686 UnlockSemaphoreInfo(resource_semaphore[type]);