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/resource-private.h"
60#include "magick/semaphore.h"
61#include "magick/signature-private.h"
62#include "magick/string_.h"
63#include "magick/string-private.h"
64#include "magick/splay-tree.h"
65#include "magick/thread-private.h"
66#include "magick/timer-private.h"
67#include "magick/token.h"
68#include "magick/timer-private.h"
69#include "magick/utility.h"
70#include "magick/utility-private.h"
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
int AcquireUniqueFileResource(
char *path)
518#if !defined(O_NOFOLLOW)
522# define TMP_MAX 238328
539 portable_filename[65] =
540 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
551 assert(path != (
char *) NULL);
552 if ((GetLogEventMask() & ResourceEvent) != 0)
553 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"...");
554 if (random_info == (RandomInfo *) NULL)
556 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
557 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
558 LockSemaphoreInfo(resource_semaphore[FileResource]);
559 if (random_info == (RandomInfo *) NULL)
560 random_info=AcquireRandomInfo();
561 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
564 for (i=0; i < (ssize_t) TMP_MAX; i++)
572 (void) GetPathTemplate(path);
573 key=GetRandomKey(random_info,strlen(MagickPathTemplate)-6);
574 p=path+strlen(path)-strlen(MagickPathTemplate);
575 datum=GetStringInfoDatum(key);
576 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
578 c=(int) (datum[j] & 0x3f);
579 *p++=portable_filename[c];
581 key=DestroyStringInfo(key);
582#if defined(MAGICKCORE_HAVE_MKSTEMP)
586#if defined(MAGICKCORE_HAVE_FCHMOD)
587 (void) fchmod(file,0600);
590 setmode(file,O_BINARY);
595 key=GetRandomKey(random_info,strlen(MagickPathTemplate));
596 p=path+strlen(path)-strlen(MagickPathTemplate);
597 datum=GetStringInfoDatum(key);
598 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
600 c=(int) (datum[j] & 0x3f);
601 *p++=portable_filename[c];
603 key=DestroyStringInfo(key);
604 file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
606 if ((file >= 0) || (errno != EEXIST))
609 if ((GetLogEventMask() & ResourceEvent) != 0)
610 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Acquire %s",path);
613 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
614 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
615 LockSemaphoreInfo(resource_semaphore[FileResource]);
616 if (temporary_resources == (SplayTreeInfo *) NULL)
617 temporary_resources=NewSplayTree(CompareSplayTreeString,
618 DestroyTemporaryResources,RelinquishMagickMemory);
619 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
620 attributes=(
struct stat *) AcquireCriticalMemory(
sizeof(
struct stat));
621 status=GetPathAttributes(path,attributes);
622 if (status == MagickFalse)
623 attributes=(
struct stat *) RelinquishMagickMemory(attributes);
625 status=AddValueToSplayTree(temporary_resources,ConstantString(path),
627 if (status == MagickFalse)
628 file=close_utf8(file)-1;
654MagickExport MagickSizeType GetMagickResource(
const ResourceType type)
669 ActivateSemaphoreInfo(&resource_semaphore[type]);
670 LockSemaphoreInfo(resource_semaphore[type]);
679 resource=(MagickSizeType) resource_info.area;
684 resource=(MagickSizeType) resource_info.disk;
689 resource=(MagickSizeType) resource_info.file;
694 resource=(MagickSizeType) resource_info.height;
697 case ListLengthResource:
699 resource=(MagickSizeType) resource_info.list_length;
704 resource=(MagickSizeType) resource_info.map;
709 resource=(MagickSizeType) resource_info.memory;
714 resource=(MagickSizeType) resource_info.thread;
717 case ThrottleResource:
719 resource=(MagickSizeType) resource_info.throttle;
724 resource=(MagickSizeType) resource_info.time;
729 resource=(MagickSizeType) resource_info.width;
743 UnlockSemaphoreInfo(resource_semaphore[type]);
774MagickExport MagickBooleanType IsFileResourceIdentityValid(
const char *path)
777 *temporary_attributes;
785 if (temporary_resources == (SplayTreeInfo *) NULL)
787 LockSemaphoreInfo(resource_semaphore[FileResource]);
788 temporary_attributes=(
const struct stat *) GetValueFromSplayTree(
789 temporary_resources,(
const void *) path);
790 if (temporary_attributes != (
const struct stat *) NULL)
792 status=GetPathAttributes(path,&attributes);
793 if (status != MagickFalse)
794 if ((attributes.st_dev != temporary_attributes->st_dev) ||
795 (attributes.st_ino != temporary_attributes->st_ino) ||
796 (attributes.st_mode != temporary_attributes->st_mode))
799 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
825MagickExport MagickSizeType GetMagickResourceLimit(
const ResourceType type)
831 if (type >= NumberOfResourceTypes)
834 ActivateSemaphoreInfo(&resource_semaphore[type]);
835 LockSemaphoreInfo(resource_semaphore[type]);
840 resource=resource_info.area_limit;
845 resource=resource_info.disk_limit;
850 resource=resource_info.file_limit;
855 resource=resource_info.height_limit;
858 case ListLengthResource:
860 resource=resource_info.list_length_limit;
865 resource=resource_info.memory_limit;
870 resource=resource_info.map_limit;
875 resource=resource_info.thread_limit;
878 case ThrottleResource:
880 resource=resource_info.throttle_limit;
885 resource=resource_info.time_limit;
890 resource=resource_info.width_limit;
896 UnlockSemaphoreInfo(resource_semaphore[type]);
926static ssize_t FormatPixelSize(
const MagickSizeType size,
927 const MagickBooleanType bi,
char *format)
944 "",
"Ki",
"Mi",
"Gi",
"Ti",
"Pi",
"Ei",
"Zi",
"Yi",
"Ri",
"Qi", (
char *) NULL
946 *traditional_units[] =
948 "",
"K",
"M",
"G",
"T",
"P",
"E",
"Z",
"Y",
"R",
"Q", (
char *) NULL
952 units=traditional_units;
953 if (bi != MagickFalse)
958#if defined(_MSC_VER) && (_MSC_VER == 1200)
959 length=(double) ((MagickOffsetType) size);
961 length=(double) size;
963 for (i=0; (length >= bytes) && (units[i+1] != (
const char *) NULL); i++)
966 for (j=2; j < 12; j++)
968 count=FormatLocaleString(format,MaxTextExtent,
"%.*g%sP",(
int) (i+j),length,
970 if (strchr(format,
'+') == (
char *) NULL)
976static void FormatTimeToLive(
const MagickSizeType ttl,
char *timeString)
988 seconds=ttl % 31536000;
991 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld years",years);
995 seconds=ttl % 2628000;
998 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld months",
1003 seconds=ttl % 604800;
1006 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld weeks",weeks);
1010 seconds=ttl % 86400;
1013 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld days",days);
1020 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld hours",hours);
1027 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld minutes",
1031 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld seconds",ttl);
1034MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
1035 ExceptionInfo *magick_unused(exception))
1038 area_limit[MaxTextExtent],
1039 disk_limit[MaxTextExtent],
1040 height_limit[MaxTextExtent],
1041 list_length_limit[MaxTextExtent],
1042 map_limit[MaxTextExtent],
1043 memory_limit[MaxTextExtent],
1044 time_limit[MaxTextExtent],
1045 width_limit[MaxTextExtent];
1047 magick_unreferenced(exception);
1049 if (file == (
const FILE *) NULL)
1051 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1052 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1053 LockSemaphoreInfo(resource_semaphore[FileResource]);
1054 (void) FormatPixelSize(resource_info.width_limit,MagickFalse,width_limit);
1055 (void) FormatPixelSize(resource_info.height_limit,MagickFalse,height_limit);
1056 (void) FormatPixelSize(resource_info.area_limit,MagickFalse,area_limit);
1057 (void) CopyMagickString(list_length_limit,
"unlimited",MaxTextExtent);
1058 if (resource_info.list_length_limit != MagickResourceInfinity)
1059 (void) FormatMagickSize(resource_info.list_length_limit,MagickTrue,
1061 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
1062 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,map_limit);
1063 (void) CopyMagickString(disk_limit,
"unlimited",MaxTextExtent);
1064 if (resource_info.disk_limit != MagickResourceInfinity)
1065 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,disk_limit);
1066 (void) CopyMagickString(time_limit,
"unlimited",MaxTextExtent);
1067 if (resource_info.time_limit != MagickResourceInfinity)
1068 FormatTimeToLive(resource_info.time_limit,time_limit);
1069 (void) FormatLocaleFile(file,
"Resource limits:\n");
1070 (void) FormatLocaleFile(file,
" Width: %s\n",width_limit);
1071 (void) FormatLocaleFile(file,
" Height: %s\n",height_limit);
1072 (void) FormatLocaleFile(file,
" List length: %s\n",list_length_limit);
1073 (void) FormatLocaleFile(file,
" Area: %s\n",area_limit);
1074 (void) FormatLocaleFile(file,
" Memory: %s\n",memory_limit);
1075 (void) FormatLocaleFile(file,
" Map: %s\n",map_limit);
1076 (void) FormatLocaleFile(file,
" Disk: %s\n",disk_limit);
1077 (void) FormatLocaleFile(file,
" File: %.20g\n",(
double) ((MagickOffsetType)
1078 resource_info.file_limit));
1079 (void) FormatLocaleFile(file,
" Thread: %.20g\n",(
double) ((MagickOffsetType)
1080 resource_info.thread_limit));
1081 (void) FormatLocaleFile(file,
" Throttle: %.20g\n",(
double)
1082 ((MagickOffsetType) resource_info.throttle_limit));
1083 (void) FormatLocaleFile(file,
" Time: %s\n",time_limit);
1084 (void) fflush(file);
1085 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1114MagickExport
void RelinquishMagickResource(
const ResourceType type,
1115 const MagickSizeType size)
1118 resource_current[MaxTextExtent],
1119 resource_limit[MaxTextExtent],
1120 resource_request[MaxTextExtent];
1125 logging=(GetLogEventMask() & ResourceEvent) != 0 ? MagickTrue : MagickFalse;
1126 if (logging != MagickFalse)
1127 (void) FormatMagickSize(size,MagickFalse,resource_request);
1133 case MemoryResource:
1137 ActivateSemaphoreInfo(&resource_semaphore[type]);
1138 LockSemaphoreInfo(resource_semaphore[type]);
1147 resource_info.area=(MagickOffsetType) size;
1148 if (logging != MagickFalse)
1150 (void) FormatMagickSize((MagickSizeType) resource_info.area,
1151 MagickFalse,resource_current);
1152 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
1159 resource_info.disk-=size;
1160 assert(resource_info.disk >= 0);
1161 if (logging != MagickFalse)
1163 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
1164 MagickTrue,resource_current);
1165 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
1172 resource_info.file-=size;
1173 assert(resource_info.file >= 0);
1174 if (logging != MagickFalse)
1176 (void) FormatMagickSize((MagickSizeType) resource_info.file,
1177 MagickFalse,resource_current);
1178 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
1179 MagickFalse,resource_limit);
1183 case HeightResource:
1185 resource_info.height=(MagickOffsetType) size;
1186 if (logging != MagickFalse)
1188 (void) FormatMagickSize((MagickSizeType) resource_info.height,
1189 MagickFalse,resource_current);
1190 (void) FormatMagickSize(resource_info.height_limit,MagickFalse,
1195 case ListLengthResource:
1197 resource_info.list_length=(MagickOffsetType) size;
1198 if (logging != MagickFalse)
1200 (void) FormatMagickSize((MagickSizeType) resource_info.list_length,
1201 MagickFalse,resource_current);
1202 (void) FormatMagickSize(resource_info.list_length_limit,MagickFalse,
1209 resource_info.map-=size;
1210 assert(resource_info.map >= 0);
1211 if (logging != MagickFalse)
1213 (void) FormatMagickSize((MagickSizeType) resource_info.map,
1214 MagickTrue,resource_current);
1215 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
1220 case MemoryResource:
1222 resource_info.memory-=size;
1223 assert(resource_info.memory >= 0);
1224 if (logging != MagickFalse)
1226 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
1227 MagickTrue,resource_current);
1228 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
1233 case ThreadResource:
1235 if (logging != MagickFalse)
1237 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
1238 MagickFalse,resource_current);
1239 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
1240 MagickFalse,resource_limit);
1244 case ThrottleResource:
1246 if (logging != MagickFalse)
1248 (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
1249 MagickFalse,resource_current);
1250 (void) FormatMagickSize((MagickSizeType) resource_info.throttle_limit,
1251 MagickFalse,resource_limit);
1257 resource_info.time-=size;
1258 assert(resource_info.time >= 0);
1259 if (logging != MagickFalse)
1261 (void) FormatMagickSize((MagickSizeType) resource_info.time,
1262 MagickFalse,resource_current);
1263 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
1264 MagickFalse,resource_limit);
1270 resource_info.width=(MagickOffsetType) size;
1271 if (logging != MagickFalse)
1273 (void) FormatMagickSize((MagickSizeType) resource_info.width,
1274 MagickFalse,resource_current);
1275 (void) FormatMagickSize(resource_info.width_limit,MagickFalse,
1288 case MemoryResource:
1291 UnlockSemaphoreInfo(resource_semaphore[type]);
1296 if (logging != MagickFalse)
1298 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
1299 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
1300 resource_request,resource_current,resource_limit);
1326MagickExport MagickBooleanType RelinquishUniqueFileResource(
const char *path)
1329 cache_path[MaxTextExtent];
1334 assert(path != (
const char *) NULL);
1336 if ((GetLogEventMask() & ResourceEvent) != 0)
1337 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Relinquish %s",path);
1338 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1339 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1340 LockSemaphoreInfo(resource_semaphore[FileResource]);
1341 if (temporary_resources != (SplayTreeInfo *) NULL)
1342 status=DeleteNodeFromSplayTree(temporary_resources,(
const void *) path);
1343 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1344 (void) CopyMagickString(cache_path,path,MaxTextExtent);
1345 AppendImageFormat(
"cache",cache_path);
1346 if (access_utf8(cache_path,F_OK) == 0)
1348 status=ShredFile(cache_path);
1349 status|=remove_utf8(cache_path);
1351 if (status == MagickFalse)
1353 status=ShredFile(path);
1354 status|=remove_utf8(path);
1356 return(status == 0 ? MagickFalse : MagickTrue);
1377MagickExport MagickBooleanType ResourceComponentGenesis(
void)
1395 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1397 ActivateSemaphoreInfo(&resource_semaphore[i]);
1398 (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
1399 limit=GetEnvironmentValue(
"MAGICK_WIDTH_LIMIT");
1400 if (limit != (
char *) NULL)
1402 (void) SetMagickResourceLimit(WidthResource,StringToSizeType(limit,
1404 limit=DestroyString(limit);
1406 (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
1407 limit=GetEnvironmentValue(
"MAGICK_HEIGHT_LIMIT");
1408 if (limit != (
char *) NULL)
1410 (void) SetMagickResourceLimit(HeightResource,StringToSizeType(limit,
1412 limit=DestroyString(limit);
1414 pagesize=GetMagickPageSize();
1416#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1417 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1418#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1422 memory=(MagickSizeType) pages*pagesize;
1423 if ((pagesize <= 0) || (pages <= 0))
1424 memory=2048UL*1024UL*1024UL;
1425#if defined(MAGICKCORE_PixelCacheThreshold)
1426 memory=StringToMagickSizeType(MAGICKCORE_PixelCacheThreshold,100.0);
1428 (void) SetMagickResourceLimit(AreaResource,4*memory);
1429 limit=GetEnvironmentValue(
"MAGICK_AREA_LIMIT");
1430 if (limit != (
char *) NULL)
1432 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
1433 limit=DestroyString(limit);
1435 (void) SetMagickResourceLimit(MemoryResource,memory);
1436 limit=GetEnvironmentValue(
"MAGICK_MEMORY_LIMIT");
1437 if (limit != (
char *) NULL)
1439 (void) SetMagickResourceLimit(MemoryResource,
1440 StringToSizeType(limit,100.0));
1441 limit=DestroyString(limit);
1443 (void) SetMagickResourceLimit(MapResource,2*memory);
1444 limit=GetEnvironmentValue(
"MAGICK_MAP_LIMIT");
1445 if (limit != (
char *) NULL)
1447 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
1448 limit=DestroyString(limit);
1450 (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
1451 limit=GetEnvironmentValue(
"MAGICK_DISK_LIMIT");
1452 if (limit != (
char *) NULL)
1454 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
1455 limit=DestroyString(limit);
1458#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1459 files=(ssize_t) sysconf(_SC_OPEN_MAX);
1461#if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1467 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1468 files=(ssize_t) resources.rlim_cur;
1471#if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1473 files=(ssize_t) getdtablesize();
1477 (void) SetMagickResourceLimit(FileResource,MagickMax((
size_t)
1479 limit=GetEnvironmentValue(
"MAGICK_FILE_LIMIT");
1480 if (limit != (
char *) NULL)
1482 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
1483 limit=DestroyString(limit);
1485 number_threads=(ssize_t) GetOpenMPMaximumThreads();
1486 if (number_threads > 1)
1488 (void) SetMagickResourceLimit(ThreadResource,(
size_t) number_threads);
1489 limit=GetEnvironmentValue(
"MAGICK_THREAD_LIMIT");
1490 if (limit != (
char *) NULL)
1492 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
1494 limit=DestroyString(limit);
1496 (void) SetMagickResourceLimit(ThrottleResource,0);
1497 limit=GetEnvironmentValue(
"MAGICK_THROTTLE_LIMIT");
1498 if (limit != (
char *) NULL)
1500 (void) SetMagickResourceLimit(ThrottleResource,StringToSizeType(limit,
1502 limit=DestroyString(limit);
1504 (void) SetMagickResourceLimit(TimeResource,MagickResourceInfinity);
1505 limit=GetEnvironmentValue(
"MAGICK_TIME_LIMIT");
1506 if (limit != (
char *) NULL)
1508 (void) SetMagickResourceLimit(TimeResource,(MagickSizeType)
1509 ParseMagickTimeToLive(limit));
1510 limit=DestroyString(limit);
1512 (void) SetMagickResourceLimit(ListLengthResource,MagickResourceInfinity);
1513 limit=GetEnvironmentValue(
"MAGICK_LIST_LENGTH_LIMIT");
1514 if (limit != (
char *) NULL)
1516 (void) SetMagickResourceLimit(ListLengthResource,
1517 StringToSizeType(limit,100.0));
1518 limit=DestroyString(limit);
1541MagickExport
void ResourceComponentTerminus(
void)
1546 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1548 ActivateSemaphoreInfo(&resource_semaphore[i]);
1549 LockSemaphoreInfo(resource_semaphore[FileResource]);
1550 if (temporary_resources != (SplayTreeInfo *) NULL)
1551 temporary_resources=DestroySplayTree(temporary_resources);
1552 if (random_info != (RandomInfo *) NULL)
1553 random_info=DestroyRandomInfo(random_info);
1554 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1555 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1556 DestroySemaphoreInfo(&resource_semaphore[i]);
1585MagickExport MagickBooleanType SetMagickResourceLimit(
const ResourceType type,
1586 const MagickSizeType limit)
1596 ActivateSemaphoreInfo(&resource_semaphore[type]);
1597 LockSemaphoreInfo(resource_semaphore[type]);
1598 value=(
char *) NULL;
1603 value=GetPolicyValue(
"resource:area");
1604 if (value == (
char *) NULL)
1605 resource_info.area_limit=limit;
1607 resource_info.area_limit=MagickMin(limit,StringToSizeType(value,100.0));
1612 value=GetPolicyValue(
"resource:disk");
1613 if (value == (
char *) NULL)
1614 resource_info.disk_limit=limit;
1616 resource_info.disk_limit=MagickMin(limit,StringToSizeType(value,100.0));
1621 value=GetPolicyValue(
"resource:file");
1622 if (value == (
char *) NULL)
1623 resource_info.file_limit=limit;
1625 resource_info.file_limit=MagickMin(limit,StringToSizeType(value,100.0));
1628 case HeightResource:
1630 value=GetPolicyValue(
"resource:height");
1631 if (value == (
char *) NULL)
1632 resource_info.height_limit=limit;
1634 resource_info.height_limit=MagickMin(limit,StringToSizeType(value,
1636 resource_info.height_limit=MagickMin(resource_info.height_limit,
1637 (MagickSizeType) MAGICK_SSIZE_MAX);
1640 case ListLengthResource:
1642 value=GetPolicyValue(
"resource:list-length");
1643 if (value == (
char *) NULL)
1644 resource_info.list_length_limit=limit;
1646 resource_info.list_length_limit=MagickMin(limit,
1647 StringToSizeType(value,100.0));
1652 value=GetPolicyValue(
"resource:map");
1653 if (value == (
char *) NULL)
1654 resource_info.map_limit=limit;
1656 resource_info.map_limit=MagickMin(limit,StringToSizeType(value,100.0));
1659 case MemoryResource:
1661 value=GetPolicyValue(
"resource:memory");
1662 if (value == (
char *) NULL)
1663 resource_info.memory_limit=limit;
1665 resource_info.memory_limit=MagickMin(limit,StringToSizeType(value,
1669 case ThreadResource:
1671 value=GetPolicyValue(
"resource:thread");
1672 if (value == (
char *) NULL)
1673 resource_info.thread_limit=limit;
1675 resource_info.thread_limit=MagickMin(limit,StringToSizeType(value,
1677 if (resource_info.thread_limit > GetOpenMPMaximumThreads())
1678 resource_info.thread_limit=GetOpenMPMaximumThreads();
1680 if (resource_info.thread_limit == 0)
1681 resource_info.thread_limit=1;
1684 case ThrottleResource:
1686 value=GetPolicyValue(
"resource:throttle");
1687 if (value == (
char *) NULL)
1688 resource_info.throttle_limit=limit;
1690 resource_info.throttle_limit=MagickMax(limit,StringToSizeType(value,
1696 value=GetPolicyValue(
"resource:time");
1697 if (value == (
char *) NULL)
1698 resource_info.time_limit=limit;
1700 resource_info.time_limit=MagickMin(limit,(MagickSizeType)
1701 ParseMagickTimeToLive(value));
1706 value=GetPolicyValue(
"resource:width");
1707 if (value == (
char *) NULL)
1708 resource_info.width_limit=limit;
1710 resource_info.width_limit=MagickMin(limit,StringToSizeType(value,
1712 resource_info.width_limit=MagickMin(resource_info.width_limit,
1713 (MagickSizeType) MAGICK_SSIZE_MAX);
1722 if (value != (
char *) NULL)
1723 value=DestroyString(value);
1724 UnlockSemaphoreInfo(resource_semaphore[type]);