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 (((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 == MagickResourceInfinity) ||
394 (resource_info.time < (MagickOffsetType) limit))
397 resource_info.time-=request;
399 if (logging != MagickFalse)
401 (void) FormatMagickSize(size,MagickFalse,resource_request);
402 (void) FormatMagickSize((MagickSizeType) resource_info.time,
403 MagickFalse,resource_current);
404 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
410 resource_info.width=(MagickOffsetType) size;
411 limit=resource_info.width_limit;
412 if ((limit == MagickResourceInfinity) || (size < limit))
414 if (logging != MagickFalse)
416 (void) FormatMagickSize(size,MagickFalse,resource_request);
417 (void) FormatMagickSize(size,MagickFalse,resource_current);
418 (void) FormatMagickSize(limit,MagickFalse,resource_limit);
433 UnlockSemaphoreInfo(resource_semaphore[type]);
438 if (logging != MagickFalse)
440 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
441 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
442 resource_request,resource_current,resource_limit);
467MagickExport
void AsynchronousResourceComponentTerminus(
void)
472 if (temporary_resources == (SplayTreeInfo *) NULL)
477 ResetSplayTreeIterator(temporary_resources);
478 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
479 while (path != (
const char *) NULL)
481 (void) ShredFile(path);
482 (void) remove_utf8(path);
483 path=(
const char *) GetNextKeyInSplayTree(temporary_resources);
512static void *DestroyTemporaryResources(
void *temporary_resource)
514 (void) ShredFile((
char *) temporary_resource);
515 (void) remove_utf8((
char *) temporary_resource);
516 temporary_resource=DestroyString((
char *) temporary_resource);
517 return((
void *) NULL);
520MagickExport MagickBooleanType GetPathTemplate(
char *path)
535 (void) FormatLocaleString(path,MaxTextExtent,
"magick-" MagickPathTemplate);
536 exception=AcquireExceptionInfo();
537 directory=(
char *) GetImageRegistry(StringRegistryType,
"temporary-path",
539 exception=DestroyExceptionInfo(exception);
540 if (directory == (
char *) NULL)
541 directory=GetEnvironmentValue(
"MAGICK_TEMPORARY_PATH");
542 if (directory == (
char *) NULL)
543 directory=GetEnvironmentValue(
"MAGICK_TMPDIR");
544 if (directory == (
char *) NULL)
545 directory=GetEnvironmentValue(
"TMPDIR");
546#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) || defined(__CYGWIN__)
547 if (directory == (
char *) NULL)
548 directory=GetEnvironmentValue(
"TMP");
549 if (directory == (
char *) NULL)
550 directory=GetEnvironmentValue(
"TEMP");
553 if (directory == (
char *) NULL)
554 directory=GetEnvironmentValue(
"MTMPDIR");
557 if (directory == (
char *) NULL)
558 directory=ConstantString(P_tmpdir);
560 if (directory == (
char *) NULL)
562 value=GetPolicyValue(
"resource:temporary-path");
563 if (value != (
char *) NULL)
565 (void) CloneString(&directory,value);
566 value=DestroyString(value);
568 if (strlen(directory) > (MaxTextExtent-25))
570 directory=DestroyString(directory);
573 status=GetPathAttributes(directory,&attributes);
574 if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
576 directory=DestroyString(directory);
579 if (directory[strlen(directory)-1] == *DirectorySeparator)
580 (void) FormatLocaleString(path,MaxTextExtent,
"%smagick-" MagickPathTemplate,
583 (
void) FormatLocaleString(path,MaxTextExtent,
"%s%smagick-"
584 MagickPathTemplate,directory,DirectorySeparator);
585 directory=DestroyString(directory);
586#if defined(MAGICKCORE_WINDOWS_SUPPORT)
595 for (p=(path[1] == *DirectorySeparator ? path+2 : path); *p !=
'\0'; p++)
596 if (*p == *DirectorySeparator)
603MagickExport
int AcquireUniqueFileResource(
char *path)
605#if !defined(O_NOFOLLOW)
609# define TMP_MAX 238328
623 portable_filename[65] =
624 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
632 assert(path != (
char *) NULL);
633 if ((GetLogEventMask() & ResourceEvent) != 0)
634 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"...");
635 if (random_info == (RandomInfo *) NULL)
637 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
638 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
639 LockSemaphoreInfo(resource_semaphore[FileResource]);
640 if (random_info == (RandomInfo *) NULL)
641 random_info=AcquireRandomInfo();
642 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
645 for (i=0; i < (ssize_t) TMP_MAX; i++)
653 (void) GetPathTemplate(path);
654 key=GetRandomKey(random_info,strlen(MagickPathTemplate)-6);
655 p=path+strlen(path)-strlen(MagickPathTemplate);
656 datum=GetStringInfoDatum(key);
657 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
659 c=(int) (datum[j] & 0x3f);
660 *p++=portable_filename[c];
662 key=DestroyStringInfo(key);
663#if defined(MAGICKCORE_HAVE_MKSTEMP)
667#if defined(MAGICKCORE_HAVE_FCHMOD)
668 (void) fchmod(file,0600);
671 setmode(file,O_BINARY);
676 key=GetRandomKey(random_info,strlen(MagickPathTemplate));
677 p=path+strlen(path)-strlen(MagickPathTemplate);
678 datum=GetStringInfoDatum(key);
679 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
681 c=(int) (datum[j] & 0x3f);
682 *p++=portable_filename[c];
684 key=DestroyStringInfo(key);
685 file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
687 if ((file >= 0) || (errno != EEXIST))
690 if ((GetLogEventMask() & ResourceEvent) != 0)
691 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Acquire %s",path);
694 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
695 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
696 LockSemaphoreInfo(resource_semaphore[FileResource]);
697 if (temporary_resources == (SplayTreeInfo *) NULL)
698 temporary_resources=NewSplayTree(CompareSplayTreeString,
699 DestroyTemporaryResources,(
void *(*)(
void *)) NULL);
700 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
701 (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
702 (
const void *) NULL);
728MagickExport MagickSizeType GetMagickResource(
const ResourceType type)
743 ActivateSemaphoreInfo(&resource_semaphore[type]);
744 LockSemaphoreInfo(resource_semaphore[type]);
753 resource=(MagickSizeType) resource_info.area;
758 resource=(MagickSizeType) resource_info.disk;
763 resource=(MagickSizeType) resource_info.file;
768 resource=(MagickSizeType) resource_info.height;
771 case ListLengthResource:
773 resource=(MagickSizeType) resource_info.list_length;
778 resource=(MagickSizeType) resource_info.map;
783 resource=(MagickSizeType) resource_info.memory;
788 resource=(MagickSizeType) resource_info.thread;
791 case ThrottleResource:
793 resource=(MagickSizeType) resource_info.throttle;
798 resource=(MagickSizeType) resource_info.time;
803 resource=(MagickSizeType) resource_info.width;
817 UnlockSemaphoreInfo(resource_semaphore[type]);
847MagickExport MagickSizeType GetMagickResourceLimit(
const ResourceType type)
854 ActivateSemaphoreInfo(&resource_semaphore[type]);
855 LockSemaphoreInfo(resource_semaphore[type]);
860 resource=resource_info.area_limit;
865 resource=resource_info.disk_limit;
870 resource=resource_info.file_limit;
875 resource=resource_info.height_limit;
878 case ListLengthResource:
880 resource=resource_info.list_length_limit;
885 resource=resource_info.memory_limit;
890 resource=resource_info.map_limit;
895 resource=resource_info.thread_limit;
898 case ThrottleResource:
900 resource=resource_info.throttle_limit;
905 resource=resource_info.time_limit;
910 resource=resource_info.width_limit;
916 UnlockSemaphoreInfo(resource_semaphore[type]);
946static ssize_t FormatPixelSize(
const MagickSizeType size,
947 const MagickBooleanType bi,
char *format)
964 "",
"Ki",
"Mi",
"Gi",
"Ti",
"Pi",
"Ei",
"Zi",
"Yi",
"Ri",
"Qi", (
char *) NULL
966 *traditional_units[] =
968 "",
"K",
"M",
"G",
"T",
"P",
"E",
"Z",
"Y",
"R",
"Q", (
char *) NULL
972 units=traditional_units;
973 if (bi != MagickFalse)
978#if defined(_MSC_VER) && (_MSC_VER == 1200)
979 length=(double) ((MagickOffsetType) size);
981 length=(double) size;
983 for (i=0; (length >= bytes) && (units[i+1] != (
const char *) NULL); i++)
986 for (j=2; j < 12; j++)
988 count=FormatLocaleString(format,MaxTextExtent,
"%.*g%sP",(
int) (i+j),length,
990 if (strchr(format,
'+') == (
char *) NULL)
996static void FormatTimeToLive(
const MagickSizeType ttl,
char *timeString)
1008 seconds=ttl % 31536000;
1011 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld years",years);
1015 seconds=ttl % 2628000;
1018 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld months",
1023 seconds=ttl % 604800;
1026 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld weeks",weeks);
1030 seconds=ttl % 86400;
1033 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld days",days);
1040 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld hours",hours);
1047 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld minutes",
1051 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld seconds",ttl);
1054MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
1055 ExceptionInfo *magick_unused(exception))
1058 area_limit[MaxTextExtent],
1059 disk_limit[MaxTextExtent],
1060 height_limit[MaxTextExtent],
1061 list_length_limit[MaxTextExtent],
1062 map_limit[MaxTextExtent],
1063 memory_limit[MaxTextExtent],
1064 time_limit[MaxTextExtent],
1065 width_limit[MaxTextExtent];
1067 magick_unreferenced(exception);
1069 if (file == (
const FILE *) NULL)
1071 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1072 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1073 LockSemaphoreInfo(resource_semaphore[FileResource]);
1074 (void) FormatPixelSize(resource_info.width_limit,MagickFalse,width_limit);
1075 (void) FormatPixelSize(resource_info.height_limit,MagickFalse,height_limit);
1076 (void) FormatPixelSize(resource_info.area_limit,MagickFalse,area_limit);
1077 (void) CopyMagickString(list_length_limit,
"unlimited",MaxTextExtent);
1078 if (resource_info.list_length_limit != MagickResourceInfinity)
1079 (void) FormatMagickSize(resource_info.list_length_limit,MagickTrue,
1081 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
1082 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,map_limit);
1083 (void) CopyMagickString(disk_limit,
"unlimited",MaxTextExtent);
1084 if (resource_info.disk_limit != MagickResourceInfinity)
1085 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,disk_limit);
1086 (void) CopyMagickString(time_limit,
"unlimited",MaxTextExtent);
1087 if (resource_info.time_limit != MagickResourceInfinity)
1088 FormatTimeToLive(resource_info.time_limit,time_limit);
1089 (void) FormatLocaleFile(file,
"Resource limits:\n");
1090 (void) FormatLocaleFile(file,
" Width: %s\n",width_limit);
1091 (void) FormatLocaleFile(file,
" Height: %s\n",height_limit);
1092 (void) FormatLocaleFile(file,
" List length: %s\n",list_length_limit);
1093 (void) FormatLocaleFile(file,
" Area: %s\n",area_limit);
1094 (void) FormatLocaleFile(file,
" Memory: %s\n",memory_limit);
1095 (void) FormatLocaleFile(file,
" Map: %s\n",map_limit);
1096 (void) FormatLocaleFile(file,
" Disk: %s\n",disk_limit);
1097 (void) FormatLocaleFile(file,
" File: %.20g\n",(
double) ((MagickOffsetType)
1098 resource_info.file_limit));
1099 (void) FormatLocaleFile(file,
" Thread: %.20g\n",(
double) ((MagickOffsetType)
1100 resource_info.thread_limit));
1101 (void) FormatLocaleFile(file,
" Throttle: %.20g\n",(
double)
1102 ((MagickOffsetType) resource_info.throttle_limit));
1103 (void) FormatLocaleFile(file,
" Time: %s\n",time_limit);
1104 (void) fflush(file);
1105 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1134MagickExport
void RelinquishMagickResource(
const ResourceType type,
1135 const MagickSizeType size)
1138 resource_current[MaxTextExtent],
1139 resource_limit[MaxTextExtent],
1140 resource_request[MaxTextExtent];
1145 logging=(GetLogEventMask() & ResourceEvent) != 0 ? MagickTrue : MagickFalse;
1146 if (logging != MagickFalse)
1147 (void) FormatMagickSize(size,MagickFalse,resource_request);
1153 case MemoryResource:
1157 ActivateSemaphoreInfo(&resource_semaphore[type]);
1158 LockSemaphoreInfo(resource_semaphore[type]);
1167 resource_info.area=(MagickOffsetType) size;
1168 if (logging != MagickFalse)
1170 (void) FormatMagickSize((MagickSizeType) resource_info.area,
1171 MagickFalse,resource_current);
1172 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
1179 resource_info.disk-=size;
1180 assert(resource_info.disk >= 0);
1181 if (logging != MagickFalse)
1183 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
1184 MagickTrue,resource_current);
1185 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
1192 resource_info.file-=size;
1193 assert(resource_info.file >= 0);
1194 if (logging != MagickFalse)
1196 (void) FormatMagickSize((MagickSizeType) resource_info.file,
1197 MagickFalse,resource_current);
1198 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
1199 MagickFalse,resource_limit);
1203 case HeightResource:
1205 resource_info.height=(MagickOffsetType) size;
1206 if (logging != MagickFalse)
1208 (void) FormatMagickSize((MagickSizeType) resource_info.height,
1209 MagickFalse,resource_current);
1210 (void) FormatMagickSize(resource_info.height_limit,MagickFalse,
1215 case ListLengthResource:
1217 resource_info.list_length=(MagickOffsetType) size;
1218 if (logging != MagickFalse)
1220 (void) FormatMagickSize((MagickSizeType) resource_info.list_length,
1221 MagickFalse,resource_current);
1222 (void) FormatMagickSize(resource_info.list_length_limit,MagickFalse,
1229 resource_info.map-=size;
1230 assert(resource_info.map >= 0);
1231 if (logging != MagickFalse)
1233 (void) FormatMagickSize((MagickSizeType) resource_info.map,
1234 MagickTrue,resource_current);
1235 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
1240 case MemoryResource:
1242 resource_info.memory-=size;
1243 assert(resource_info.memory >= 0);
1244 if (logging != MagickFalse)
1246 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
1247 MagickTrue,resource_current);
1248 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
1253 case ThreadResource:
1255 if (logging != MagickFalse)
1257 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
1258 MagickFalse,resource_current);
1259 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
1260 MagickFalse,resource_limit);
1264 case ThrottleResource:
1266 if (logging != MagickFalse)
1268 (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
1269 MagickFalse,resource_current);
1270 (void) FormatMagickSize((MagickSizeType) resource_info.throttle_limit,
1271 MagickFalse,resource_limit);
1277 resource_info.time-=size;
1278 assert(resource_info.time >= 0);
1279 if (logging != MagickFalse)
1281 (void) FormatMagickSize((MagickSizeType) resource_info.time,
1282 MagickFalse,resource_current);
1283 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
1284 MagickFalse,resource_limit);
1290 resource_info.width=(MagickOffsetType) size;
1291 if (logging != MagickFalse)
1293 (void) FormatMagickSize((MagickSizeType) resource_info.width,
1294 MagickFalse,resource_current);
1295 (void) FormatMagickSize(resource_info.width_limit,MagickFalse,
1308 case MemoryResource:
1311 UnlockSemaphoreInfo(resource_semaphore[type]);
1316 if (logging != MagickFalse)
1318 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
1319 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
1320 resource_request,resource_current,resource_limit);
1346MagickExport MagickBooleanType RelinquishUniqueFileResource(
const char *path)
1349 cache_path[MaxTextExtent];
1354 assert(path != (
const char *) NULL);
1356 if ((GetLogEventMask() & ResourceEvent) != 0)
1357 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Relinquish %s",path);
1358 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1359 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1360 LockSemaphoreInfo(resource_semaphore[FileResource]);
1361 if (temporary_resources != (SplayTreeInfo *) NULL)
1362 status=DeleteNodeFromSplayTree(temporary_resources, (
const void *) path);
1363 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1364 (void) CopyMagickString(cache_path,path,MaxTextExtent);
1365 AppendImageFormat(
"cache",cache_path);
1366 if (access_utf8(cache_path,F_OK) == 0)
1368 status=ShredFile(cache_path);
1369 status|=remove_utf8(cache_path);
1371 if (status == MagickFalse)
1373 status=ShredFile(path);
1374 status|=remove_utf8(path);
1376 return(status == 0 ? MagickFalse : MagickTrue);
1397MagickExport MagickBooleanType ResourceComponentGenesis(
void)
1415 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1417 ActivateSemaphoreInfo(&resource_semaphore[i]);
1418 (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
1419 limit=GetEnvironmentValue(
"MAGICK_WIDTH_LIMIT");
1420 if (limit != (
char *) NULL)
1422 (void) SetMagickResourceLimit(WidthResource,StringToSizeType(limit,
1424 limit=DestroyString(limit);
1426 (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
1427 limit=GetEnvironmentValue(
"MAGICK_HEIGHT_LIMIT");
1428 if (limit != (
char *) NULL)
1430 (void) SetMagickResourceLimit(HeightResource,StringToSizeType(limit,
1432 limit=DestroyString(limit);
1434 pagesize=GetMagickPageSize();
1436#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1437 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1438#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1442 memory=(MagickSizeType) pages*pagesize;
1443 if ((pagesize <= 0) || (pages <= 0))
1444 memory=2048UL*1024UL*1024UL;
1445#if defined(MAGICKCORE_PixelCacheThreshold)
1446 memory=StringToMagickSizeType(MAGICKCORE_PixelCacheThreshold,100.0);
1448 (void) SetMagickResourceLimit(AreaResource,4*memory);
1449 limit=GetEnvironmentValue(
"MAGICK_AREA_LIMIT");
1450 if (limit != (
char *) NULL)
1452 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
1453 limit=DestroyString(limit);
1455 (void) SetMagickResourceLimit(MemoryResource,memory);
1456 limit=GetEnvironmentValue(
"MAGICK_MEMORY_LIMIT");
1457 if (limit != (
char *) NULL)
1459 (void) SetMagickResourceLimit(MemoryResource,
1460 StringToSizeType(limit,100.0));
1461 limit=DestroyString(limit);
1463 (void) SetMagickResourceLimit(MapResource,2*memory);
1464 limit=GetEnvironmentValue(
"MAGICK_MAP_LIMIT");
1465 if (limit != (
char *) NULL)
1467 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
1468 limit=DestroyString(limit);
1470 (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
1471 limit=GetEnvironmentValue(
"MAGICK_DISK_LIMIT");
1472 if (limit != (
char *) NULL)
1474 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
1475 limit=DestroyString(limit);
1478#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1479 files=(ssize_t) sysconf(_SC_OPEN_MAX);
1481#if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1487 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1488 files=(ssize_t) resources.rlim_cur;
1491#if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1493 files=(ssize_t) getdtablesize();
1497 (void) SetMagickResourceLimit(FileResource,MagickMax((
size_t)
1499 limit=GetEnvironmentValue(
"MAGICK_FILE_LIMIT");
1500 if (limit != (
char *) NULL)
1502 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
1503 limit=DestroyString(limit);
1505 number_threads=(ssize_t) GetOpenMPMaximumThreads();
1506 if (number_threads > 1)
1508 (void) SetMagickResourceLimit(ThreadResource,(
size_t) number_threads);
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,MagickResourceInfinity);
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);
1561MagickExport
void ResourceComponentTerminus(
void)
1566 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1568 ActivateSemaphoreInfo(&resource_semaphore[i]);
1569 LockSemaphoreInfo(resource_semaphore[FileResource]);
1570 if (temporary_resources != (SplayTreeInfo *) NULL)
1571 temporary_resources=DestroySplayTree(temporary_resources);
1572 if (random_info != (RandomInfo *) NULL)
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]);
1605MagickExport 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]);