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))
798 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
824MagickExport MagickSizeType GetMagickResourceLimit(
const ResourceType type)
830 if (type >= NumberOfResourceTypes)
833 ActivateSemaphoreInfo(&resource_semaphore[type]);
834 LockSemaphoreInfo(resource_semaphore[type]);
839 resource=resource_info.area_limit;
844 resource=resource_info.disk_limit;
849 resource=resource_info.file_limit;
854 resource=resource_info.height_limit;
857 case ListLengthResource:
859 resource=resource_info.list_length_limit;
864 resource=resource_info.memory_limit;
869 resource=resource_info.map_limit;
874 resource=resource_info.thread_limit;
877 case ThrottleResource:
879 resource=resource_info.throttle_limit;
884 resource=resource_info.time_limit;
889 resource=resource_info.width_limit;
895 UnlockSemaphoreInfo(resource_semaphore[type]);
925static ssize_t FormatPixelSize(
const MagickSizeType size,
926 const MagickBooleanType bi,
char *format)
943 "",
"Ki",
"Mi",
"Gi",
"Ti",
"Pi",
"Ei",
"Zi",
"Yi",
"Ri",
"Qi", (
char *) NULL
945 *traditional_units[] =
947 "",
"K",
"M",
"G",
"T",
"P",
"E",
"Z",
"Y",
"R",
"Q", (
char *) NULL
951 units=traditional_units;
952 if (bi != MagickFalse)
957#if defined(_MSC_VER) && (_MSC_VER == 1200)
958 length=(double) ((MagickOffsetType) size);
960 length=(double) size;
962 for (i=0; (length >= bytes) && (units[i+1] != (
const char *) NULL); i++)
965 for (j=2; j < 12; j++)
967 count=FormatLocaleString(format,MaxTextExtent,
"%.*g%sP",(
int) (i+j),length,
969 if (strchr(format,
'+') == (
char *) NULL)
975static void FormatTimeToLive(
const MagickSizeType ttl,
char *timeString)
987 seconds=ttl % 31536000;
990 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld years",years);
994 seconds=ttl % 2628000;
997 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld months",
1002 seconds=ttl % 604800;
1005 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld weeks",weeks);
1009 seconds=ttl % 86400;
1012 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld days",days);
1019 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld hours",hours);
1026 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld minutes",
1030 (void) FormatLocaleString(timeString,MagickPathExtent,
"%lld seconds",ttl);
1033MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
1034 ExceptionInfo *magick_unused(exception))
1037 area_limit[MaxTextExtent],
1038 disk_limit[MaxTextExtent],
1039 height_limit[MaxTextExtent],
1040 list_length_limit[MaxTextExtent],
1041 map_limit[MaxTextExtent],
1042 memory_limit[MaxTextExtent],
1043 time_limit[MaxTextExtent],
1044 width_limit[MaxTextExtent];
1046 magick_unreferenced(exception);
1048 if (file == (
const FILE *) NULL)
1050 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1051 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1052 LockSemaphoreInfo(resource_semaphore[FileResource]);
1053 (void) FormatPixelSize(resource_info.width_limit,MagickFalse,width_limit);
1054 (void) FormatPixelSize(resource_info.height_limit,MagickFalse,height_limit);
1055 (void) FormatPixelSize(resource_info.area_limit,MagickFalse,area_limit);
1056 (void) CopyMagickString(list_length_limit,
"unlimited",MaxTextExtent);
1057 if (resource_info.list_length_limit != MagickResourceInfinity)
1058 (void) FormatMagickSize(resource_info.list_length_limit,MagickTrue,
1060 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
1061 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,map_limit);
1062 (void) CopyMagickString(disk_limit,
"unlimited",MaxTextExtent);
1063 if (resource_info.disk_limit != MagickResourceInfinity)
1064 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,disk_limit);
1065 (void) CopyMagickString(time_limit,
"unlimited",MaxTextExtent);
1066 if (resource_info.time_limit != MagickResourceInfinity)
1067 FormatTimeToLive(resource_info.time_limit,time_limit);
1068 (void) FormatLocaleFile(file,
"Resource limits:\n");
1069 (void) FormatLocaleFile(file,
" Width: %s\n",width_limit);
1070 (void) FormatLocaleFile(file,
" Height: %s\n",height_limit);
1071 (void) FormatLocaleFile(file,
" List length: %s\n",list_length_limit);
1072 (void) FormatLocaleFile(file,
" Area: %s\n",area_limit);
1073 (void) FormatLocaleFile(file,
" Memory: %s\n",memory_limit);
1074 (void) FormatLocaleFile(file,
" Map: %s\n",map_limit);
1075 (void) FormatLocaleFile(file,
" Disk: %s\n",disk_limit);
1076 (void) FormatLocaleFile(file,
" File: %.20g\n",(
double) ((MagickOffsetType)
1077 resource_info.file_limit));
1078 (void) FormatLocaleFile(file,
" Thread: %.20g\n",(
double) ((MagickOffsetType)
1079 resource_info.thread_limit));
1080 (void) FormatLocaleFile(file,
" Throttle: %.20g\n",(
double)
1081 ((MagickOffsetType) resource_info.throttle_limit));
1082 (void) FormatLocaleFile(file,
" Time: %s\n",time_limit);
1083 (void) fflush(file);
1084 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1113MagickExport
void RelinquishMagickResource(
const ResourceType type,
1114 const MagickSizeType size)
1117 resource_current[MaxTextExtent],
1118 resource_limit[MaxTextExtent],
1119 resource_request[MaxTextExtent];
1124 logging=(GetLogEventMask() & ResourceEvent) != 0 ? MagickTrue : MagickFalse;
1125 if (logging != MagickFalse)
1126 (void) FormatMagickSize(size,MagickFalse,resource_request);
1132 case MemoryResource:
1136 ActivateSemaphoreInfo(&resource_semaphore[type]);
1137 LockSemaphoreInfo(resource_semaphore[type]);
1146 resource_info.area=(MagickOffsetType) size;
1147 if (logging != MagickFalse)
1149 (void) FormatMagickSize((MagickSizeType) resource_info.area,
1150 MagickFalse,resource_current);
1151 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
1158 resource_info.disk-=size;
1159 assert(resource_info.disk >= 0);
1160 if (logging != MagickFalse)
1162 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
1163 MagickTrue,resource_current);
1164 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
1171 resource_info.file-=size;
1172 assert(resource_info.file >= 0);
1173 if (logging != MagickFalse)
1175 (void) FormatMagickSize((MagickSizeType) resource_info.file,
1176 MagickFalse,resource_current);
1177 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
1178 MagickFalse,resource_limit);
1182 case HeightResource:
1184 resource_info.height=(MagickOffsetType) size;
1185 if (logging != MagickFalse)
1187 (void) FormatMagickSize((MagickSizeType) resource_info.height,
1188 MagickFalse,resource_current);
1189 (void) FormatMagickSize(resource_info.height_limit,MagickFalse,
1194 case ListLengthResource:
1196 resource_info.list_length=(MagickOffsetType) size;
1197 if (logging != MagickFalse)
1199 (void) FormatMagickSize((MagickSizeType) resource_info.list_length,
1200 MagickFalse,resource_current);
1201 (void) FormatMagickSize(resource_info.list_length_limit,MagickFalse,
1208 resource_info.map-=size;
1209 assert(resource_info.map >= 0);
1210 if (logging != MagickFalse)
1212 (void) FormatMagickSize((MagickSizeType) resource_info.map,
1213 MagickTrue,resource_current);
1214 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
1219 case MemoryResource:
1221 resource_info.memory-=size;
1222 assert(resource_info.memory >= 0);
1223 if (logging != MagickFalse)
1225 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
1226 MagickTrue,resource_current);
1227 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
1232 case ThreadResource:
1234 if (logging != MagickFalse)
1236 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
1237 MagickFalse,resource_current);
1238 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
1239 MagickFalse,resource_limit);
1243 case ThrottleResource:
1245 if (logging != MagickFalse)
1247 (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
1248 MagickFalse,resource_current);
1249 (void) FormatMagickSize((MagickSizeType) resource_info.throttle_limit,
1250 MagickFalse,resource_limit);
1256 resource_info.time-=size;
1257 assert(resource_info.time >= 0);
1258 if (logging != MagickFalse)
1260 (void) FormatMagickSize((MagickSizeType) resource_info.time,
1261 MagickFalse,resource_current);
1262 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
1263 MagickFalse,resource_limit);
1269 resource_info.width=(MagickOffsetType) size;
1270 if (logging != MagickFalse)
1272 (void) FormatMagickSize((MagickSizeType) resource_info.width,
1273 MagickFalse,resource_current);
1274 (void) FormatMagickSize(resource_info.width_limit,MagickFalse,
1287 case MemoryResource:
1290 UnlockSemaphoreInfo(resource_semaphore[type]);
1295 if (logging != MagickFalse)
1297 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"%s: %s/%s/%s",
1298 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
1299 resource_request,resource_current,resource_limit);
1325MagickExport MagickBooleanType RelinquishUniqueFileResource(
const char *path)
1328 cache_path[MaxTextExtent];
1333 assert(path != (
const char *) NULL);
1335 if ((GetLogEventMask() & ResourceEvent) != 0)
1336 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),
"Relinquish %s",path);
1337 if (resource_semaphore[FileResource] == (
SemaphoreInfo *) NULL)
1338 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1339 LockSemaphoreInfo(resource_semaphore[FileResource]);
1340 if (temporary_resources != (SplayTreeInfo *) NULL)
1341 status=DeleteNodeFromSplayTree(temporary_resources,(
const void *) path);
1342 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1343 (void) CopyMagickString(cache_path,path,MaxTextExtent);
1344 AppendImageFormat(
"cache",cache_path);
1345 if (access_utf8(cache_path,F_OK) == 0)
1347 status=ShredFile(cache_path);
1348 status|=remove_utf8(cache_path);
1350 if (status == MagickFalse)
1352 status=ShredFile(path);
1353 status|=remove_utf8(path);
1355 return(status == 0 ? MagickFalse : MagickTrue);
1376MagickExport MagickBooleanType ResourceComponentGenesis(
void)
1394 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1396 ActivateSemaphoreInfo(&resource_semaphore[i]);
1397 (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
1398 limit=GetEnvironmentValue(
"MAGICK_WIDTH_LIMIT");
1399 if (limit != (
char *) NULL)
1401 (void) SetMagickResourceLimit(WidthResource,StringToSizeType(limit,
1403 limit=DestroyString(limit);
1405 (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
1406 limit=GetEnvironmentValue(
"MAGICK_HEIGHT_LIMIT");
1407 if (limit != (
char *) NULL)
1409 (void) SetMagickResourceLimit(HeightResource,StringToSizeType(limit,
1411 limit=DestroyString(limit);
1413 pagesize=GetMagickPageSize();
1415#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1416 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1417#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1421 memory=(MagickSizeType) pages*pagesize;
1422 if ((pagesize <= 0) || (pages <= 0))
1423 memory=2048UL*1024UL*1024UL;
1424#if defined(MAGICKCORE_PixelCacheThreshold)
1425 memory=StringToMagickSizeType(MAGICKCORE_PixelCacheThreshold,100.0);
1427 (void) SetMagickResourceLimit(AreaResource,4*memory);
1428 limit=GetEnvironmentValue(
"MAGICK_AREA_LIMIT");
1429 if (limit != (
char *) NULL)
1431 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
1432 limit=DestroyString(limit);
1434 (void) SetMagickResourceLimit(MemoryResource,memory);
1435 limit=GetEnvironmentValue(
"MAGICK_MEMORY_LIMIT");
1436 if (limit != (
char *) NULL)
1438 (void) SetMagickResourceLimit(MemoryResource,
1439 StringToSizeType(limit,100.0));
1440 limit=DestroyString(limit);
1442 (void) SetMagickResourceLimit(MapResource,2*memory);
1443 limit=GetEnvironmentValue(
"MAGICK_MAP_LIMIT");
1444 if (limit != (
char *) NULL)
1446 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
1447 limit=DestroyString(limit);
1449 (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
1450 limit=GetEnvironmentValue(
"MAGICK_DISK_LIMIT");
1451 if (limit != (
char *) NULL)
1453 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
1454 limit=DestroyString(limit);
1457#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1458 files=(ssize_t) sysconf(_SC_OPEN_MAX);
1460#if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1466 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1467 files=(ssize_t) resources.rlim_cur;
1470#if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1472 files=(ssize_t) getdtablesize();
1476 (void) SetMagickResourceLimit(FileResource,MagickMax((
size_t)
1478 limit=GetEnvironmentValue(
"MAGICK_FILE_LIMIT");
1479 if (limit != (
char *) NULL)
1481 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
1482 limit=DestroyString(limit);
1484 number_threads=(ssize_t) GetOpenMPMaximumThreads();
1485 if (number_threads > 1)
1487 (void) SetMagickResourceLimit(ThreadResource,(
size_t) number_threads);
1488 limit=GetEnvironmentValue(
"MAGICK_THREAD_LIMIT");
1489 if (limit != (
char *) NULL)
1491 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
1493 limit=DestroyString(limit);
1495 (void) SetMagickResourceLimit(ThrottleResource,0);
1496 limit=GetEnvironmentValue(
"MAGICK_THROTTLE_LIMIT");
1497 if (limit != (
char *) NULL)
1499 (void) SetMagickResourceLimit(ThrottleResource,StringToSizeType(limit,
1501 limit=DestroyString(limit);
1503 (void) SetMagickResourceLimit(TimeResource,MagickResourceInfinity);
1504 limit=GetEnvironmentValue(
"MAGICK_TIME_LIMIT");
1505 if (limit != (
char *) NULL)
1507 (void) SetMagickResourceLimit(TimeResource,(MagickSizeType)
1508 ParseMagickTimeToLive(limit));
1509 limit=DestroyString(limit);
1511 (void) SetMagickResourceLimit(ListLengthResource,MagickResourceInfinity);
1512 limit=GetEnvironmentValue(
"MAGICK_LIST_LENGTH_LIMIT");
1513 if (limit != (
char *) NULL)
1515 (void) SetMagickResourceLimit(ListLengthResource,
1516 StringToSizeType(limit,100.0));
1517 limit=DestroyString(limit);
1540MagickExport
void ResourceComponentTerminus(
void)
1545 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1547 ActivateSemaphoreInfo(&resource_semaphore[i]);
1548 LockSemaphoreInfo(resource_semaphore[FileResource]);
1549 if (temporary_resources != (SplayTreeInfo *) NULL)
1550 temporary_resources=DestroySplayTree(temporary_resources);
1551 if (random_info != (RandomInfo *) NULL)
1552 random_info=DestroyRandomInfo(random_info);
1553 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1554 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1555 DestroySemaphoreInfo(&resource_semaphore[i]);
1584MagickExport MagickBooleanType SetMagickResourceLimit(
const ResourceType type,
1585 const MagickSizeType limit)
1595 ActivateSemaphoreInfo(&resource_semaphore[type]);
1596 LockSemaphoreInfo(resource_semaphore[type]);
1597 value=(
char *) NULL;
1602 value=GetPolicyValue(
"resource:area");
1603 if (value == (
char *) NULL)
1604 resource_info.area_limit=limit;
1606 resource_info.area_limit=MagickMin(limit,StringToSizeType(value,100.0));
1611 value=GetPolicyValue(
"resource:disk");
1612 if (value == (
char *) NULL)
1613 resource_info.disk_limit=limit;
1615 resource_info.disk_limit=MagickMin(limit,StringToSizeType(value,100.0));
1620 value=GetPolicyValue(
"resource:file");
1621 if (value == (
char *) NULL)
1622 resource_info.file_limit=limit;
1624 resource_info.file_limit=MagickMin(limit,StringToSizeType(value,100.0));
1627 case HeightResource:
1629 value=GetPolicyValue(
"resource:height");
1630 if (value == (
char *) NULL)
1631 resource_info.height_limit=limit;
1633 resource_info.height_limit=MagickMin(limit,StringToSizeType(value,
1635 resource_info.height_limit=MagickMin(resource_info.height_limit,
1636 (MagickSizeType) MAGICK_SSIZE_MAX);
1639 case ListLengthResource:
1641 value=GetPolicyValue(
"resource:list-length");
1642 if (value == (
char *) NULL)
1643 resource_info.list_length_limit=limit;
1645 resource_info.list_length_limit=MagickMin(limit,
1646 StringToSizeType(value,100.0));
1651 value=GetPolicyValue(
"resource:map");
1652 if (value == (
char *) NULL)
1653 resource_info.map_limit=limit;
1655 resource_info.map_limit=MagickMin(limit,StringToSizeType(value,100.0));
1658 case MemoryResource:
1660 value=GetPolicyValue(
"resource:memory");
1661 if (value == (
char *) NULL)
1662 resource_info.memory_limit=limit;
1664 resource_info.memory_limit=MagickMin(limit,StringToSizeType(value,
1668 case ThreadResource:
1670 value=GetPolicyValue(
"resource:thread");
1671 if (value == (
char *) NULL)
1672 resource_info.thread_limit=limit;
1674 resource_info.thread_limit=MagickMin(limit,StringToSizeType(value,
1676 if (resource_info.thread_limit > GetOpenMPMaximumThreads())
1677 resource_info.thread_limit=GetOpenMPMaximumThreads();
1679 if (resource_info.thread_limit == 0)
1680 resource_info.thread_limit=1;
1683 case ThrottleResource:
1685 value=GetPolicyValue(
"resource:throttle");
1686 if (value == (
char *) NULL)
1687 resource_info.throttle_limit=limit;
1689 resource_info.throttle_limit=MagickMax(limit,StringToSizeType(value,
1695 value=GetPolicyValue(
"resource:time");
1696 if (value == (
char *) NULL)
1697 resource_info.time_limit=limit;
1699 resource_info.time_limit=MagickMin(limit,(MagickSizeType)
1700 ParseMagickTimeToLive(value));
1705 value=GetPolicyValue(
"resource:width");
1706 if (value == (
char *) NULL)
1707 resource_info.width_limit=limit;
1709 resource_info.width_limit=MagickMin(limit,StringToSizeType(value,
1711 resource_info.width_limit=MagickMin(resource_info.width_limit,
1712 (MagickSizeType) MAGICK_SSIZE_MAX);
1721 if (value != (
char *) NULL)
1722 value=DestroyString(value);
1723 UnlockSemaphoreInfo(resource_semaphore[type]);