MagickCore 7.1.1-43
Convert, Edit, Or Compose Bitmap Images
Loading...
Searching...
No Matches
resource.c
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% RRRR EEEEE SSSSS OOO U U RRRR CCCC EEEEE %
7% R R E SS O O U U R R C E %
8% RRRR EEE SSS O O U U RRRR C EEE %
9% R R E SS O O U U R R C E %
10% R R EEEEE SSSSS OOO UUU R R CCCC EEEEE %
11% %
12% %
13% Get/Set MagickCore Resources %
14% %
15% Software Design %
16% Cristy %
17% September 2002 %
18% %
19% %
20% Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization %
21% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% https://imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38␌
39/*
40 Include declarations.
41*/
42#include "MagickCore/studio.h"
43#include "MagickCore/cache.h"
44#include "MagickCore/configure.h"
45#include "MagickCore/exception.h"
46#include "MagickCore/exception-private.h"
47#include "MagickCore/linked-list.h"
48#include "MagickCore/log.h"
49#include "MagickCore/image.h"
50#include "MagickCore/image-private.h"
51#include "MagickCore/memory_.h"
52#include "MagickCore/nt-base-private.h"
53#include "MagickCore/option.h"
54#include "MagickCore/policy.h"
55#include "MagickCore/random_.h"
56#include "MagickCore/registry.h"
57#include "MagickCore/resource_.h"
58#include "MagickCore/resource-private.h"
59#include "MagickCore/semaphore.h"
60#include "MagickCore/signature-private.h"
61#include "MagickCore/string_.h"
62#include "MagickCore/string-private.h"
63#include "MagickCore/splay-tree.h"
64#include "MagickCore/thread-private.h"
65#include "MagickCore/timer-private.h"
66#include "MagickCore/token.h"
67#include "MagickCore/utility.h"
68#include "MagickCore/utility-private.h"
69␌
70/*
71 Define declarations.
72*/
73#define NumberOfResourceTypes \
74 (sizeof(resource_semaphore)/sizeof(*resource_semaphore))
75␌
76/*
77 Typedef declarations.
78*/
79typedef struct _ResourceInfo
80{
81 MagickOffsetType
82 width,
83 height,
84 list_length,
85 area,
86 memory,
87 map,
88 disk,
89 file,
90 thread,
91 throttle,
92 time;
93
94 MagickSizeType
95 width_limit,
96 height_limit,
97 list_length_limit,
98 area_limit,
99 memory_limit,
100 map_limit,
101 disk_limit,
102 file_limit,
103 thread_limit,
104 throttle_limit,
105 time_limit;
107␌
108/*
109 Global declarations.
110*/
111static RandomInfo
112 *random_info = (RandomInfo *) NULL;
113
114static ResourceInfo
115 resource_info =
116 {
117 MagickULLConstant(0), /* initial width */
118 MagickULLConstant(0), /* initial height */
119 MagickULLConstant(0), /* initial list length */
120 MagickULLConstant(0), /* initial area */
121 MagickULLConstant(0), /* initial memory */
122 MagickULLConstant(0), /* initial map */
123 MagickULLConstant(0), /* initial disk */
124 MagickULLConstant(0), /* initial file */
125 MagickULLConstant(0), /* initial thread */
126 MagickULLConstant(0), /* initial throttle */
127 MagickULLConstant(0), /* initial time */
128 (MagickSizeType) (MAGICK_SSIZE_MAX/sizeof(Quantum)/MaxPixelChannels), /* width limit */
129 (MagickSizeType) (MAGICK_SSIZE_MAX/sizeof(Quantum)/MaxPixelChannels), /* height limit */
130 MagickResourceInfinity, /* list length limit */
131 MagickULLConstant(3072)*1024*1024, /* area limit */
132 MagickULLConstant(1536)*1024*1024, /* memory limit */
133 MagickULLConstant(3072)*1024*1024, /* map limit */
134 MagickResourceInfinity, /* disk limit */
135 MagickULLConstant(768), /* file limit */
136 MagickULLConstant(1), /* thread limit */
137 MagickULLConstant(0), /* throttle limit */
138 MagickULLConstant(0), /* time limit */
139 };
140
141static SemaphoreInfo
142 *resource_semaphore[] = {
143 (SemaphoreInfo *) NULL,
144 (SemaphoreInfo *) NULL,
145 (SemaphoreInfo *) NULL,
146 (SemaphoreInfo *) NULL,
147 (SemaphoreInfo *) NULL,
148 (SemaphoreInfo *) NULL,
149 (SemaphoreInfo *) NULL,
150 (SemaphoreInfo *) NULL,
151 (SemaphoreInfo *) NULL,
152 (SemaphoreInfo *) NULL,
153 (SemaphoreInfo *) NULL,
154 (SemaphoreInfo *) NULL
155 };
156
157static SplayTreeInfo
158 *temporary_resources = (SplayTreeInfo *) NULL;
159␌
160/*
161%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
162% %
163% %
164% %
165% A c q u i r e M a g i c k R e s o u r c e %
166% %
167% %
168% %
169%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170%
171% AcquireMagickResource() acquires resources of the specified type.
172% MagickFalse is returned if the specified resource is exhausted otherwise
173% MagickTrue.
174%
175% The format of the AcquireMagickResource() method is:
176%
177% MagickBooleanType AcquireMagickResource(const ResourceType type,
178% const MagickSizeType size)
179%
180% A description of each parameter follows:
181%
182% o type: the type of resource.
183%
184% o size: the number of bytes needed from for this resource.
185%
186*/
187MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
188 const MagickSizeType size)
189{
190 MagickBooleanType
191 bi,
192 status;
193
194 MagickOffsetType
195 current,
196 request;
197
198 MagickSizeType
199 limit;
200
201 request=(MagickOffsetType) size;
202 if (request < 0)
203 return(MagickFalse);
204 limit=0;
205 current=0;
206 bi=MagickFalse;
207 status=MagickFalse;
208 switch (type)
209 {
210 case DiskResource:
211 case FileResource:
212 case MapResource:
213 case MemoryResource:
214 case TimeResource:
215 {
216 if (resource_semaphore[type] == (SemaphoreInfo *) NULL)
217 ActivateSemaphoreInfo(&resource_semaphore[type]);
218 LockSemaphoreInfo(resource_semaphore[type]);
219 break;
220 }
221 default: ;
222 }
223 switch (type)
224 {
225 case AreaResource:
226 {
227 bi=MagickTrue;
228 resource_info.area=request;
229 limit=resource_info.area_limit;
230 if ((limit == MagickResourceInfinity) || (size < limit))
231 status=MagickTrue;
232 break;
233 }
234 case DiskResource:
235 {
236 bi=MagickTrue;
237 limit=resource_info.disk_limit;
238 if (((MagickSizeType) resource_info.disk+(MagickSizeType) request) > (MagickSizeType) resource_info.disk)
239 {
240 resource_info.disk+=request;
241 if ((limit == MagickResourceInfinity) ||
242 (resource_info.disk < (MagickOffsetType) limit))
243 status=MagickTrue;
244 else
245 resource_info.disk-=request;
246 }
247 current=resource_info.disk;
248 break;
249 }
250 case FileResource:
251 {
252 limit=resource_info.file_limit;
253 if (((MagickSizeType) resource_info.file+(MagickSizeType) request) > (MagickSizeType) resource_info.file)
254 {
255 resource_info.file+=request;
256 if ((limit == MagickResourceInfinity) ||
257 (resource_info.file < (MagickOffsetType) limit))
258 status=MagickTrue;
259 }
260 current=resource_info.file;
261 break;
262 }
263 case HeightResource:
264 {
265 bi=MagickTrue;
266 resource_info.height=request;
267 limit=resource_info.height_limit;
268 if ((limit == MagickResourceInfinity) || (size < limit))
269 status=MagickTrue;
270 break;
271 }
272 case ListLengthResource:
273 {
274 resource_info.list_length=request;
275 limit=resource_info.list_length_limit;
276 if ((limit == MagickResourceInfinity) || (size < limit))
277 status=MagickTrue;
278 break;
279 }
280 case MapResource:
281 {
282 bi=MagickTrue;
283 limit=resource_info.map_limit;
284 if (((MagickSizeType) resource_info.map+(MagickSizeType) request) > (MagickSizeType) resource_info.map)
285 {
286 resource_info.map+=request;
287 if ((limit == MagickResourceInfinity) ||
288 (resource_info.map < (MagickOffsetType) limit))
289 status=MagickTrue;
290 else
291 resource_info.map-=request;
292 }
293 current=resource_info.map;
294 break;
295 }
296 case MemoryResource:
297 {
298 bi=MagickTrue;
299 limit=resource_info.memory_limit;
300 if (((MagickSizeType) resource_info.memory+(MagickSizeType) request) > (MagickSizeType) resource_info.memory)
301 {
302 resource_info.memory+=request;
303 if ((limit == MagickResourceInfinity) ||
304 (resource_info.memory < (MagickOffsetType) limit))
305 status=MagickTrue;
306 else
307 resource_info.memory-=request;
308 }
309 current=resource_info.memory;
310 break;
311 }
312 case ThreadResource:
313 {
314 limit=resource_info.thread_limit;
315 if ((limit == MagickResourceInfinity) ||
316 (resource_info.thread < (MagickOffsetType) limit))
317 status=MagickTrue;
318 break;
319 }
320 case ThrottleResource:
321 {
322 limit=resource_info.throttle_limit;
323 if ((limit == MagickResourceInfinity) ||
324 (resource_info.throttle < (MagickOffsetType) limit))
325 status=MagickTrue;
326 break;
327 }
328 case TimeResource:
329 {
330 limit=resource_info.time_limit;
331 if (((MagickSizeType) resource_info.time+(MagickSizeType) request) > (MagickSizeType) resource_info.time)
332 {
333 resource_info.time+=request;
334 if ((limit == 0) || (resource_info.time < (MagickOffsetType) limit))
335 status=MagickTrue;
336 else
337 resource_info.time-=request;
338 }
339 current=resource_info.time;
340 break;
341 }
342 case WidthResource:
343 {
344 bi=MagickTrue;
345 resource_info.width=request;
346 limit=resource_info.width_limit;
347 if ((limit == MagickResourceInfinity) || (size < limit))
348 status=MagickTrue;
349 break;
350 }
351 default:
352 {
353 current=0;
354 break;
355 }
356 }
357 switch (type)
358 {
359 case DiskResource:
360 case FileResource:
361 case MapResource:
362 case MemoryResource:
363 case TimeResource:
364 {
365 UnlockSemaphoreInfo(resource_semaphore[type]);
366 break;
367 }
368 default: ;
369 }
370 if ((GetLogEventMask() & ResourceEvent) != 0)
371 {
372 char
373 resource_current[MagickFormatExtent],
374 resource_limit[MagickFormatExtent],
375 resource_request[MagickFormatExtent];
376
377 (void) FormatMagickSize(size,bi,(bi != MagickFalse) ? "B" :
378 (const char *) NULL,MagickFormatExtent,resource_request);
379 (void) FormatMagickSize((MagickSizeType) current,bi,(bi != MagickFalse) ?
380 "B" : (const char *) NULL,MagickFormatExtent,resource_current);
381 (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ? "B" :
382 (const char *) NULL,MagickFormatExtent,resource_limit);
383 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
384 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
385 resource_request,resource_current,resource_limit);
386 }
387 return(status);
388}
389␌
390/*
391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
392% %
393% %
394% %
395+ A s y n c h r o n o u s R e s o u r c e C o m p o n e n t T e r m i n u s %
396% %
397% %
398% %
399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400%
401% AsynchronousResourceComponentTerminus() destroys the resource environment.
402% It differs from ResourceComponentTerminus() in that it can be called from a
403% asynchronous signal handler.
404%
405% The format of the ResourceComponentTerminus() method is:
406%
407% ResourceComponentTerminus(void)
408%
409*/
410MagickExport void AsynchronousResourceComponentTerminus(void)
411{
412 const char
413 *path;
414
415 if (temporary_resources == (SplayTreeInfo *) NULL)
416 return;
417 /*
418 Remove any lingering temporary files.
419 */
420 ResetSplayTreeIterator(temporary_resources);
421 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
422 while (path != (const char *) NULL)
423 {
424 (void) ShredFile(path);
425 (void) remove_utf8(path);
426 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
427 }
428}
429␌
430/*
431%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432% %
433% %
434% %
435% A c q u i r e U n i q u e F i l e R e s o u r c e %
436% %
437% %
438% %
439%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440%
441% AcquireUniqueFileResource() returns a unique file name, and returns a file
442% descriptor for the file open for reading and writing.
443%
444% The format of the AcquireUniqueFileResource() method is:
445%
446% int AcquireUniqueFileResource(char *path)
447%
448% A description of each parameter follows:
449%
450% o path: Specifies a pointer to an array of characters. The unique path
451% name is returned in this array.
452%
453*/
454
455static void *DestroyTemporaryResources(void *temporary_resource)
456{
457 (void) ShredFile((char *) temporary_resource);
458 (void) remove_utf8((char *) temporary_resource);
459 temporary_resource=DestroyString((char *) temporary_resource);
460 return((void *) NULL);
461}
462
463MagickExport int AcquireUniqueFileResource(char *path)
464{
465#if !defined(O_NOFOLLOW)
466#define O_NOFOLLOW 0
467#endif
468#if !defined(TMP_MAX)
469# define TMP_MAX 238328
470#endif
471
472 int
473 c,
474 file;
475
476 char
477 *p;
478
479 ssize_t
480 i;
481
482 static const char
483 portable_filename[65] =
484 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
485
487 *key;
488
489 unsigned char
490 *datum;
491
492 assert(path != (char *) NULL);
493 if ((GetLogEventMask() & ResourceEvent) != 0)
494 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"...");
495 if (random_info == (RandomInfo *) NULL)
496 {
497 if (resource_semaphore[FileResource] == (SemaphoreInfo *) NULL)
498 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
499 LockSemaphoreInfo(resource_semaphore[FileResource]);
500 if (random_info == (RandomInfo *) NULL)
501 random_info=AcquireRandomInfo();
502 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
503 }
504 file=(-1);
505 for (i=0; i < (ssize_t) TMP_MAX; i++)
506 {
507 ssize_t
508 j;
509
510 /*
511 Get temporary pathname.
512 */
513 (void) GetPathTemplate(path);
514 key=GetRandomKey(random_info,strlen(MagickPathTemplate)-6);
515 p=path+strlen(path)-strlen(MagickPathTemplate);
516 datum=GetStringInfoDatum(key);
517 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
518 {
519 c=(int) (datum[j] & 0x3f);
520 *p++=portable_filename[c];
521 }
522 key=DestroyStringInfo(key);
523#if defined(MAGICKCORE_HAVE_MKSTEMP)
524 file=mkstemp(path);
525 if (file != -1)
526 {
527#if defined(MAGICKCORE_HAVE_FCHMOD)
528 (void) fchmod(file,0600);
529#endif
530#if defined(__OS2__)
531 setmode(file,O_BINARY);
532#endif
533 break;
534 }
535#endif
536 key=GetRandomKey(random_info,strlen(MagickPathTemplate));
537 p=path+strlen(path)-strlen(MagickPathTemplate);
538 datum=GetStringInfoDatum(key);
539 for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
540 {
541 c=(int) (datum[j] & 0x3f);
542 *p++=portable_filename[c];
543 }
544 key=DestroyStringInfo(key);
545 file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
546 S_MODE);
547 if ((file >= 0) || (errno != EEXIST))
548 break;
549 }
550 if ((GetLogEventMask() & ResourceEvent) != 0)
551 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
552 if (file == -1)
553 return(file);
554 if (resource_semaphore[FileResource] == (SemaphoreInfo *) NULL)
555 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
556 LockSemaphoreInfo(resource_semaphore[FileResource]);
557 if (temporary_resources == (SplayTreeInfo *) NULL)
558 temporary_resources=NewSplayTree(CompareSplayTreeString,
559 DestroyTemporaryResources,(void *(*)(void *)) NULL);
560 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
561 (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
562 (const void *) NULL);
563 return(file);
564}
565␌
566/*
567%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
568% %
569% %
570% %
571% G e t M a g i c k R e s o u r c e %
572% %
573% %
574% %
575%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
576%
577% GetMagickResource() returns the specified resource.
578%
579% The format of the GetMagickResource() method is:
580%
581% MagickSizeType GetMagickResource(const ResourceType type)
582%
583% A description of each parameter follows:
584%
585% o type: the type of resource.
586%
587*/
588MagickExport MagickSizeType GetMagickResource(const ResourceType type)
589{
590 MagickSizeType
591 resource;
592
593 resource=0;
594 switch (type)
595 {
596 case DiskResource:
597 case FileResource:
598 case MapResource:
599 case MemoryResource:
600 case TimeResource:
601 {
602 if (resource_semaphore[type] == (SemaphoreInfo *) NULL)
603 ActivateSemaphoreInfo(&resource_semaphore[type]);
604 LockSemaphoreInfo(resource_semaphore[type]);
605 break;
606 }
607 default: ;
608 }
609 switch (type)
610 {
611 case AreaResource:
612 {
613 resource=(MagickSizeType) resource_info.area;
614 break;
615 }
616 case DiskResource:
617 {
618 resource=(MagickSizeType) resource_info.disk;
619 break;
620 }
621 case FileResource:
622 {
623 resource=(MagickSizeType) resource_info.file;
624 break;
625 }
626 case HeightResource:
627 {
628 resource=(MagickSizeType) resource_info.height;
629 break;
630 }
631 case ListLengthResource:
632 {
633 resource=(MagickSizeType) resource_info.list_length;
634 break;
635 }
636 case MapResource:
637 {
638 resource=(MagickSizeType) resource_info.map;
639 break;
640 }
641 case MemoryResource:
642 {
643 resource=(MagickSizeType) resource_info.memory;
644 break;
645 }
646 case TimeResource:
647 {
648 resource=(MagickSizeType) resource_info.time;
649 break;
650 }
651 case ThreadResource:
652 {
653 resource=(MagickSizeType) resource_info.thread;
654 break;
655 }
656 case ThrottleResource:
657 {
658 resource=(MagickSizeType) resource_info.throttle;
659 break;
660 }
661 case WidthResource:
662 {
663 resource=(MagickSizeType) resource_info.width;
664 break;
665 }
666 default:
667 break;
668 }
669 switch (type)
670 {
671 case DiskResource:
672 case FileResource:
673 case MapResource:
674 case MemoryResource:
675 case TimeResource:
676 {
677 UnlockSemaphoreInfo(resource_semaphore[type]);
678 break;
679 }
680 default: ;
681 }
682 return(resource);
683}
684␌
685/*
686%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
687% %
688% %
689% %
690% I s F i l e R e s o u r c e I d e n t i t y V a l i d %
691% %
692% %
693% %
694%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
695%
696% IsFileResourceIdentityValid() returns MagickTrue if the file resource
697% identity is valid.
698%
699% The format of the IsFileResourceIdentityValid() method is:
700%
701% MagickBooleanType IsFileResourceIdentityValid(const char *path)
702%
703% A description of each parameter follows:
704%
705% o path: the file resource path.
706%
707*/
708MagickExport MagickBooleanType IsFileResourceIdentityValid(const char *path)
709{
710 const struct stat
711 *temporary_attributes;
712
713 MagickBooleanType
714 status = MagickTrue;
715
716 struct stat
717 attributes;
718
719 if (temporary_resources == (SplayTreeInfo *) NULL)
720 return(MagickTrue);
721 LockSemaphoreInfo(resource_semaphore[FileResource]);
722 temporary_attributes=(const struct stat *) GetValueFromSplayTree(
723 temporary_resources,(const void *) path);
724 if (temporary_attributes != (const struct stat *) NULL)
725 {
726 status=GetPathAttributes(path,&attributes);
727 if (status != MagickFalse)
728 if ((attributes.st_dev != temporary_attributes->st_dev) ||
729 (attributes.st_ino != temporary_attributes->st_ino) ||
730 (attributes.st_mode != temporary_attributes->st_mode))
731 status=MagickFalse;
732 }
733 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
734 return(status);
735}
736␌
737/*
738%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
739% %
740% %
741% %
742% G e t M a g i c k R e s o u r c e L i m i t %
743% %
744% %
745% %
746%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
747%
748% GetMagickResourceLimit() returns the specified resource limit.
749%
750% The format of the GetMagickResourceLimit() method is:
751%
752% MagickSizeType GetMagickResourceLimit(const ResourceType type)
753%
754% A description of each parameter follows:
755%
756% o type: the type of resource.
757%
758*/
759MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
760{
761 MagickSizeType
762 resource;
763
764 switch (type)
765 {
766 case AreaResource:
767 return(resource_info.area_limit);
768 case HeightResource:
769 return(resource_info.height_limit);
770 case ListLengthResource:
771 return(resource_info.list_length_limit);
772 case ThreadResource:
773 return(resource_info.thread_limit);
774 case ThrottleResource:
775 return(resource_info.throttle_limit);
776 case WidthResource:
777 return(resource_info.width_limit);
778 default: ;
779 }
780 resource=0;
781 if (resource_semaphore[type] == (SemaphoreInfo *) NULL)
782 ActivateSemaphoreInfo(&resource_semaphore[type]);
783 LockSemaphoreInfo(resource_semaphore[type]);
784 switch (type)
785 {
786 case DiskResource:
787 {
788 resource=resource_info.disk_limit;
789 break;
790 }
791 case FileResource:
792 {
793 resource=resource_info.file_limit;
794 break;
795 }
796 case MapResource:
797 {
798 resource=resource_info.map_limit;
799 break;
800 }
801 case MemoryResource:
802 {
803 resource=resource_info.memory_limit;
804 break;
805 }
806 case TimeResource:
807 {
808 resource=resource_info.time_limit;
809 break;
810 }
811 default:
812 break;
813 }
814 UnlockSemaphoreInfo(resource_semaphore[type]);
815 return(resource);
816}
817␌
818/*
819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
820% %
821% %
822% %
823% L i s t M a g i c k R e s o u r c e I n f o %
824% %
825% %
826% %
827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828%
829% ListMagickResourceInfo() lists the resource info to a file.
830%
831% The format of the ListMagickResourceInfo method is:
832%
833% MagickBooleanType ListMagickResourceInfo(FILE *file,
834% ExceptionInfo *exception)
835%
836% A description of each parameter follows.
837%
838% o file: An pointer to a FILE.
839%
840% o exception: return any errors or warnings in this structure.
841%
842*/
843
844static void FormatTimeToLive(const MagickSizeType ttl,char *timeString)
845{
846 MagickSizeType
847 days,
848 hours,
849 minutes,
850 months,
851 seconds,
852 weeks,
853 years;
854
855 years=ttl/31536000;
856 seconds=ttl % 31536000;
857 if (seconds == 0)
858 {
859 (void) FormatLocaleString(timeString,MagickPathExtent,"%lld years",years);
860 return;
861 }
862 months=ttl/2628000;
863 seconds=ttl % 2628000;
864 if (seconds == 0)
865 {
866 (void) FormatLocaleString(timeString,MagickPathExtent,"%lld months",
867 months);
868 return;
869 }
870 weeks=ttl/604800;
871 seconds=ttl % 604800;
872 if (seconds == 0)
873 {
874 (void) FormatLocaleString(timeString,MagickPathExtent,"%lld weeks",weeks);
875 return;
876 }
877 days=ttl/86400;
878 seconds=ttl % 86400;
879 if (seconds == 0)
880 {
881 (void) FormatLocaleString(timeString,MagickPathExtent,"%lld days",days);
882 return;
883 }
884 hours=ttl/3600;
885 seconds=ttl % 3600;
886 if (seconds == 0)
887 {
888 (void) FormatLocaleString(timeString,MagickPathExtent,"%lld hours",hours);
889 return;
890 }
891 minutes=ttl/60;
892 seconds=ttl % 60;
893 if (seconds == 0)
894 {
895 (void) FormatLocaleString(timeString,MagickPathExtent,"%lld minutes",
896 minutes);
897 return;
898 }
899 (void) FormatLocaleString(timeString,MagickPathExtent,"%lld seconds",ttl);
900}
901
902MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
903 ExceptionInfo *magick_unused(exception))
904{
905 char
906 area_limit[MagickFormatExtent],
907 disk_limit[MagickFormatExtent],
908 height_limit[MagickFormatExtent],
909 list_length_limit[MagickFormatExtent],
910 map_limit[MagickFormatExtent],
911 memory_limit[MagickFormatExtent],
912 time_limit[MagickFormatExtent],
913 width_limit[MagickFormatExtent];
914
915 magick_unreferenced(exception);
916
917 if (file == (const FILE *) NULL)
918 file=stdout;
919 if (resource_semaphore[FileResource] == (SemaphoreInfo *) NULL)
920 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
921 LockSemaphoreInfo(resource_semaphore[FileResource]);
922 (void) FormatMagickSize(resource_info.width_limit,MagickFalse,"P",
923 MagickFormatExtent,width_limit);
924 (void) FormatMagickSize(resource_info.height_limit,MagickFalse,"P",
925 MagickFormatExtent,height_limit);
926 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,"P",
927 MagickFormatExtent,area_limit);
928 (void) CopyMagickString(list_length_limit,"unlimited",MagickFormatExtent);
929 if (resource_info.list_length_limit != MagickResourceInfinity)
930 (void) FormatMagickSize(resource_info.list_length_limit,MagickTrue,"B",
931 MagickFormatExtent,list_length_limit);
932 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,"B",
933 MagickFormatExtent,memory_limit);
934 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,"B",
935 MagickFormatExtent,map_limit);
936 (void) CopyMagickString(disk_limit,"unlimited",MagickFormatExtent);
937 if (resource_info.disk_limit != MagickResourceInfinity)
938 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,"B",
939 MagickFormatExtent,disk_limit);
940 (void) CopyMagickString(time_limit,"unlimited",MagickFormatExtent);
941 if (resource_info.time_limit != 0)
942 FormatTimeToLive(resource_info.time_limit,time_limit);
943 (void) FormatLocaleFile(file,"Resource limits:\n");
944 (void) FormatLocaleFile(file," Width: %s\n",width_limit);
945 (void) FormatLocaleFile(file," Height: %s\n",height_limit);
946 (void) FormatLocaleFile(file," Area: %s\n",area_limit);
947 (void) FormatLocaleFile(file," List length: %s\n",list_length_limit);
948 (void) FormatLocaleFile(file," Memory: %s\n",memory_limit);
949 (void) FormatLocaleFile(file," Map: %s\n",map_limit);
950 (void) FormatLocaleFile(file," Disk: %s\n",disk_limit);
951 (void) FormatLocaleFile(file," File: %.20g\n",(double) ((MagickOffsetType)
952 resource_info.file_limit));
953 (void) FormatLocaleFile(file," Thread: %.20g\n",(double) ((MagickOffsetType)
954 resource_info.thread_limit));
955 (void) FormatLocaleFile(file," Throttle: %.20g\n",(double)
956 ((MagickOffsetType) resource_info.throttle_limit));
957 (void) FormatLocaleFile(file," Time: %s\n",time_limit);
958 (void) fflush(file);
959 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
960 return(MagickTrue);
961}
962␌
963/*
964%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
965% %
966% %
967% %
968% R e l i n q u i s h M a g i c k R e s o u r c e %
969% %
970% %
971% %
972%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
973%
974% RelinquishMagickResource() relinquishes resources of the specified type.
975%
976% The format of the RelinquishMagickResource() method is:
977%
978% void RelinquishMagickResource(const ResourceType type,
979% const MagickSizeType size)
980%
981% A description of each parameter follows:
982%
983% o type: the type of resource.
984%
985% o size: the size of the resource.
986%
987*/
988MagickExport void RelinquishMagickResource(const ResourceType type,
989 const MagickSizeType size)
990{
991 MagickBooleanType
992 bi;
993
994 MagickSizeType
995 current,
996 limit;
997
998 bi=MagickFalse;
999 limit=0;
1000 current=0;
1001 switch (type)
1002 {
1003 case DiskResource:
1004 case FileResource:
1005 case MapResource:
1006 case MemoryResource:
1007 case TimeResource:
1008 {
1009 if (resource_semaphore[type] == (SemaphoreInfo *) NULL)
1010 ActivateSemaphoreInfo(&resource_semaphore[type]);
1011 LockSemaphoreInfo(resource_semaphore[type]);
1012 break;
1013 }
1014 default: ;
1015 }
1016 switch (type)
1017 {
1018 case DiskResource:
1019 {
1020 bi=MagickTrue;
1021 resource_info.disk-=(MagickOffsetType) size;
1022 current=(MagickSizeType) resource_info.disk;
1023 limit=resource_info.disk_limit;
1024 assert(resource_info.disk >= 0);
1025 break;
1026 }
1027 case FileResource:
1028 {
1029 resource_info.file-=(MagickOffsetType) size;
1030 current=(MagickSizeType) resource_info.file;
1031 limit=resource_info.file_limit;
1032 assert(resource_info.file >= 0);
1033 break;
1034 }
1035 case MapResource:
1036 {
1037 bi=MagickTrue;
1038 resource_info.map-=(MagickOffsetType) size;
1039 current=(MagickSizeType) resource_info.map;
1040 limit=resource_info.map_limit;
1041 assert(resource_info.map >= 0);
1042 break;
1043 }
1044 case MemoryResource:
1045 {
1046 bi=MagickTrue;
1047 resource_info.memory-=(MagickOffsetType) size;
1048 current=(MagickSizeType) resource_info.memory;
1049 limit=resource_info.memory_limit;
1050 assert(resource_info.memory >= 0);
1051 break;
1052 }
1053 case TimeResource:
1054 {
1055 bi=MagickTrue;
1056 resource_info.time-=(MagickOffsetType) size;
1057 current=(MagickSizeType) resource_info.time;
1058 limit=resource_info.time_limit;
1059 assert(resource_info.time >= 0);
1060 break;
1061 }
1062 default:
1063 {
1064 current=0;
1065 break;
1066 }
1067 }
1068 switch (type)
1069 {
1070 case DiskResource:
1071 case FileResource:
1072 case MapResource:
1073 case MemoryResource:
1074 case TimeResource:
1075 {
1076 UnlockSemaphoreInfo(resource_semaphore[type]);
1077 break;
1078 }
1079 default: ;
1080 }
1081 if ((GetLogEventMask() & ResourceEvent) != 0)
1082 {
1083 char
1084 resource_current[MagickFormatExtent],
1085 resource_limit[MagickFormatExtent],
1086 resource_request[MagickFormatExtent];
1087
1088 (void) FormatMagickSize(size,bi,(bi != MagickFalse) ? "B" :
1089 (const char *) NULL,MagickFormatExtent,resource_request);
1090 (void) FormatMagickSize(current,bi,(bi != MagickFalse) ? "B" :
1091 (const char *) NULL,MagickFormatExtent,resource_current);
1092 (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ? "B" :
1093 (const char *) NULL,MagickFormatExtent,resource_limit);
1094 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
1095 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
1096 resource_request,resource_current,resource_limit);
1097 }
1098}
1099␌
1100/*
1101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1102% %
1103% %
1104% %
1105% R e l i n q u i s h U n i q u e F i l e R e s o u r c e %
1106% %
1107% %
1108% %
1109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1110%
1111% RelinquishUniqueFileResource() relinquishes a unique file resource.
1112%
1113% The format of the RelinquishUniqueFileResource() method is:
1114%
1115% MagickBooleanType RelinquishUniqueFileResource(const char *path)
1116%
1117% A description of each parameter follows:
1118%
1119% o name: the name of the temporary resource.
1120%
1121*/
1122MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
1123{
1124 char
1125 cache_path[MagickPathExtent];
1126
1127 MagickStatusType
1128 status;
1129
1130 assert(path != (const char *) NULL);
1131 status=MagickFalse;
1132 if ((GetLogEventMask() & ResourceEvent) != 0)
1133 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
1134 if (resource_semaphore[FileResource] == (SemaphoreInfo *) NULL)
1135 ActivateSemaphoreInfo(&resource_semaphore[FileResource]);
1136 LockSemaphoreInfo(resource_semaphore[FileResource]);
1137 if (temporary_resources != (SplayTreeInfo *) NULL)
1138 status=DeleteNodeFromSplayTree(temporary_resources,(const void *) path);
1139 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1140 (void) CopyMagickString(cache_path,path,MagickPathExtent);
1141 AppendImageFormat("cache",cache_path);
1142 if (access_utf8(cache_path,F_OK) == 0)
1143 {
1144 status=ShredFile(cache_path);
1145 status|=(MagickStatusType) remove_utf8(cache_path);
1146 }
1147 if (status == MagickFalse)
1148 {
1149 status=ShredFile(path);
1150 status|=(MagickStatusType) remove_utf8(path);
1151 }
1152 return(status == 0 ? MagickFalse : MagickTrue);
1153}
1154␌
1155/*
1156%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1157% %
1158% %
1159% %
1160+ R e s o u r c e C o m p o n e n t G e n e s i s %
1161% %
1162% %
1163% %
1164%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1165%
1166% ResourceComponentGenesis() instantiates the resource component.
1167%
1168% The format of the ResourceComponentGenesis method is:
1169%
1170% MagickBooleanType ResourceComponentGenesis(void)
1171%
1172*/
1173
1174MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
1175{
1176 char
1177 *limit;
1178
1179 MagickSizeType
1180 memory;
1181
1182 ssize_t
1183 files,
1184 i,
1185 number_threads,
1186 pages,
1187 pagesize;
1188
1189 /*
1190 Set Magick resource limits.
1191 */
1192 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1193 if (resource_semaphore[i] == (SemaphoreInfo *) NULL)
1194 resource_semaphore[i]=AcquireSemaphoreInfo();
1195 (void) SetMagickResourceLimit(WidthResource,resource_info.width_limit);
1196 limit=GetEnvironmentValue("MAGICK_WIDTH_LIMIT");
1197 if (limit != (char *) NULL)
1198 {
1199 (void) SetMagickResourceLimit(WidthResource,StringToMagickSizeType(limit,
1200 100.0));
1201 limit=DestroyString(limit);
1202 }
1203 (void) SetMagickResourceLimit(HeightResource,resource_info.height_limit);
1204 limit=GetEnvironmentValue("MAGICK_HEIGHT_LIMIT");
1205 if (limit != (char *) NULL)
1206 {
1207 (void) SetMagickResourceLimit(HeightResource,StringToMagickSizeType(
1208 limit,100.0));
1209 limit=DestroyString(limit);
1210 }
1211 pagesize=GetMagickPageSize();
1212 pages=(-1);
1213#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1214 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1215#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1216 pages=pages/2;
1217#endif
1218#endif
1219 memory=(MagickSizeType) ((MagickOffsetType) pages*pagesize);
1220 if ((pagesize <= 0) || (pages <= 0))
1221 memory=2048UL*1024UL*1024UL;
1222#if defined(MAGICKCORE_PixelCacheThreshold)
1223 memory=MAGICKCORE_PixelCacheThreshold;
1224#endif
1225 (void) SetMagickResourceLimit(AreaResource,4*memory);
1226 limit=GetEnvironmentValue("MAGICK_AREA_LIMIT");
1227 if (limit != (char *) NULL)
1228 {
1229 (void) SetMagickResourceLimit(AreaResource,StringToMagickSizeType(limit,
1230 100.0));
1231 limit=DestroyString(limit);
1232 }
1233 (void) SetMagickResourceLimit(MemoryResource,memory);
1234 limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT");
1235 if (limit != (char *) NULL)
1236 {
1237 (void) SetMagickResourceLimit(MemoryResource,StringToMagickSizeType(
1238 limit,100.0));
1239 limit=DestroyString(limit);
1240 }
1241 (void) SetMagickResourceLimit(MapResource,2*memory);
1242 limit=GetEnvironmentValue("MAGICK_MAP_LIMIT");
1243 if (limit != (char *) NULL)
1244 {
1245 (void) SetMagickResourceLimit(MapResource,StringToMagickSizeType(limit,
1246 100.0));
1247 limit=DestroyString(limit);
1248 }
1249 (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
1250 limit=GetEnvironmentValue("MAGICK_DISK_LIMIT");
1251 if (limit != (char *) NULL)
1252 {
1253 (void) SetMagickResourceLimit(DiskResource,StringToMagickSizeType(limit,
1254 100.0));
1255 limit=DestroyString(limit);
1256 }
1257 files=(-1);
1258#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1259 files=(ssize_t) sysconf(_SC_OPEN_MAX);
1260#endif
1261#if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1262 if (files < 0)
1263 {
1264 struct rlimit
1265 resources;
1266
1267 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1268 files=(ssize_t) resources.rlim_cur;
1269 }
1270#endif
1271#if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1272 if (files < 0)
1273 files=(ssize_t) getdtablesize();
1274#endif
1275 if (files < 0)
1276 files=64;
1277 (void) SetMagickResourceLimit(FileResource,MagickMax((size_t)
1278 (3*files/4),64));
1279 limit=GetEnvironmentValue("MAGICK_FILE_LIMIT");
1280 if (limit != (char *) NULL)
1281 {
1282 (void) SetMagickResourceLimit(FileResource,StringToMagickSizeType(limit,
1283 100.0));
1284 limit=DestroyString(limit);
1285 }
1286 number_threads=(ssize_t) GetOpenMPMaximumThreads();
1287 if (number_threads > 1)
1288 number_threads--; /* reserve core for OS */
1289 (void) SetMagickResourceLimit(ThreadResource,(size_t) number_threads);
1290 limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT");
1291 if (limit != (char *) NULL)
1292 {
1293 (void) SetMagickResourceLimit(ThreadResource,StringToMagickSizeType(
1294 limit,100.0));
1295 limit=DestroyString(limit);
1296 }
1297 (void) SetMagickResourceLimit(ThrottleResource,0);
1298 limit=GetEnvironmentValue("MAGICK_THROTTLE_LIMIT");
1299 if (limit != (char *) NULL)
1300 {
1301 (void) SetMagickResourceLimit(ThrottleResource,StringToMagickSizeType(
1302 limit,100.0));
1303 limit=DestroyString(limit);
1304 }
1305 (void) SetMagickResourceLimit(TimeResource,0);
1306 limit=GetEnvironmentValue("MAGICK_TIME_LIMIT");
1307 if (limit != (char *) NULL)
1308 {
1309 (void) SetMagickResourceLimit(TimeResource,(MagickSizeType)
1310 ParseMagickTimeToLive(limit));
1311 limit=DestroyString(limit);
1312 }
1313 (void) SetMagickResourceLimit(ListLengthResource,MagickResourceInfinity);
1314 limit=GetEnvironmentValue("MAGICK_LIST_LENGTH_LIMIT");
1315 if (limit != (char *) NULL)
1316 {
1317 (void) SetMagickResourceLimit(ListLengthResource,
1318 StringToMagickSizeType(limit,100.0));
1319 limit=DestroyString(limit);
1320 }
1321 return(MagickTrue);
1322}
1323␌
1324/*
1325%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1326% %
1327% %
1328% %
1329+ R e s o u r c e C o m p o n e n t T e r m i n u s %
1330% %
1331% %
1332% %
1333%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1334%
1335% ResourceComponentTerminus() destroys the resource component.
1336%
1337% The format of the ResourceComponentTerminus() method is:
1338%
1339% ResourceComponentTerminus(void)
1340%
1341*/
1342MagickPrivate void ResourceComponentTerminus(void)
1343{
1344 ssize_t
1345 i;
1346
1347 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1348 if (resource_semaphore[i] == (SemaphoreInfo *) NULL)
1349 resource_semaphore[i]=AcquireSemaphoreInfo();
1350 LockSemaphoreInfo(resource_semaphore[FileResource]);
1351 if (temporary_resources != (SplayTreeInfo *) NULL)
1352 temporary_resources=DestroySplayTree(temporary_resources);
1353 if (random_info != (RandomInfo *) NULL)
1354 random_info=DestroyRandomInfo(random_info);
1355 UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1356 for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1357 RelinquishSemaphoreInfo(&resource_semaphore[i]);
1358}
1359␌
1360/*
1361%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1362% %
1363% %
1364% %
1365% S e t M a g i c k R e s o u r c e L i m i t %
1366% %
1367% %
1368% %
1369%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1370%
1371% SetMagickResourceLimit() sets the limit for a particular resource.
1372%
1373% The format of the SetMagickResourceLimit() method is:
1374%
1375% MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1376% const MagickSizeType limit)
1377%
1378% A description of each parameter follows:
1379%
1380% o type: the type of resource.
1381%
1382% o limit: the maximum limit for the resource.
1383%
1384*/
1385MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1386 const MagickSizeType limit)
1387{
1388 char
1389 *value;
1390
1391 MagickBooleanType
1392 status;
1393
1394 status=MagickTrue;
1395 value=(char *) NULL;
1396 switch (type)
1397 {
1398 case DiskResource:
1399 case FileResource:
1400 case MapResource:
1401 case MemoryResource:
1402 case TimeResource:
1403 {
1404 if (resource_semaphore[type] == (SemaphoreInfo *) NULL)
1405 ActivateSemaphoreInfo(&resource_semaphore[type]);
1406 LockSemaphoreInfo(resource_semaphore[type]);
1407 break;
1408 }
1409 default: ;
1410 }
1411 switch (type)
1412 {
1413 case AreaResource:
1414 {
1415 value=GetPolicyValue("resource:area");
1416 if (value == (char *) NULL)
1417 resource_info.area_limit=limit;
1418 else
1419 resource_info.area_limit=MagickMin(limit,StringToMagickSizeType(value,
1420 100.0));
1421 break;
1422 }
1423 case DiskResource:
1424 {
1425 value=GetPolicyValue("resource:disk");
1426 if (value == (char *) NULL)
1427 resource_info.disk_limit=limit;
1428 else
1429 resource_info.disk_limit=MagickMin(limit,StringToMagickSizeType(value,
1430 100.0));
1431 break;
1432 }
1433 case FileResource:
1434 {
1435 value=GetPolicyValue("resource:file");
1436 if (value == (char *) NULL)
1437 resource_info.file_limit=limit;
1438 else
1439 resource_info.file_limit=MagickMin(limit,StringToMagickSizeType(value,
1440 100.0));
1441 break;
1442 }
1443 case HeightResource:
1444 {
1445 value=GetPolicyValue("resource:height");
1446 if (value == (char *) NULL)
1447 resource_info.height_limit=limit;
1448 else
1449 resource_info.height_limit=MagickMin(limit,StringToMagickSizeType(
1450 value,100.0));
1451 resource_info.height_limit=MagickMin(resource_info.height_limit,
1452 (MagickSizeType) MAGICK_SSIZE_MAX);
1453 break;
1454 }
1455 case ListLengthResource:
1456 {
1457 value=GetPolicyValue("resource:list-length");
1458 if (value == (char *) NULL)
1459 resource_info.list_length_limit=limit;
1460 else
1461 resource_info.list_length_limit=MagickMin(limit,
1462 StringToMagickSizeType(value,100.0));
1463 break;
1464 }
1465 case MapResource:
1466 {
1467 value=GetPolicyValue("resource:map");
1468 if (value == (char *) NULL)
1469 resource_info.map_limit=limit;
1470 else
1471 resource_info.map_limit=MagickMin(limit,StringToMagickSizeType(
1472 value,100.0));
1473 break;
1474 }
1475 case MemoryResource:
1476 {
1477 value=GetPolicyValue("resource:memory");
1478 if (value == (char *) NULL)
1479 resource_info.memory_limit=limit;
1480 else
1481 resource_info.memory_limit=MagickMin(limit,StringToMagickSizeType(
1482 value,100.0));
1483 break;
1484 }
1485 case ThreadResource:
1486 {
1487 value=GetPolicyValue("resource:thread");
1488 if (value == (char *) NULL)
1489 resource_info.thread_limit=limit;
1490 else
1491 resource_info.thread_limit=MagickMin(limit,StringToMagickSizeType(
1492 value,100.0));
1493 if (resource_info.thread_limit > GetOpenMPMaximumThreads())
1494 resource_info.thread_limit=GetOpenMPMaximumThreads();
1495 else
1496 if (resource_info.thread_limit == 0)
1497 resource_info.thread_limit=1;
1498 break;
1499 }
1500 case ThrottleResource:
1501 {
1502 value=GetPolicyValue("resource:throttle");
1503 if (value == (char *) NULL)
1504 resource_info.throttle_limit=limit;
1505 else
1506 resource_info.throttle_limit=MagickMax(limit,StringToMagickSizeType(
1507 value,100.0));
1508 break;
1509 }
1510 case TimeResource:
1511 {
1512 value=GetPolicyValue("resource:time");
1513 if (value == (char *) NULL)
1514 resource_info.time_limit=limit;
1515 else
1516 resource_info.time_limit=MagickMin(limit,(MagickSizeType)
1517 ParseMagickTimeToLive(value));
1518 break;
1519 }
1520 case WidthResource:
1521 {
1522 value=GetPolicyValue("resource:width");
1523 if (value == (char *) NULL)
1524 resource_info.width_limit=limit;
1525 else
1526 resource_info.width_limit=MagickMin(limit,StringToMagickSizeType(value,
1527 100.0));
1528 resource_info.width_limit=MagickMin(resource_info.width_limit,
1529 (MagickSizeType) MAGICK_SSIZE_MAX);
1530 break;
1531 }
1532 default:
1533 {
1534 status=MagickFalse;
1535 break;
1536 }
1537 }
1538 switch (type)
1539 {
1540 case DiskResource:
1541 case FileResource:
1542 case MapResource:
1543 case MemoryResource:
1544 case TimeResource:
1545 {
1546 UnlockSemaphoreInfo(resource_semaphore[type]);
1547 break;
1548 }
1549 default: ;
1550 }
1551 if (value != (char *) NULL)
1552 value=DestroyString(value);
1553 return(status);
1554}