blob: 2415099abea80a442e801de58572d020c3c354eb [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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% John Cristy %
17% September 2002 %
18% %
19% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% 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% http://www.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*/
cristy4c08aed2011-07-01 19:47:50 +000042#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/hashmap.h"
48#include "MagickCore/log.h"
49#include "MagickCore/image.h"
50#include "MagickCore/memory_.h"
51#include "MagickCore/option.h"
52#include "MagickCore/policy.h"
53#include "MagickCore/random_.h"
54#include "MagickCore/registry.h"
55#include "MagickCore/resource_.h"
cristy0a4d92f2011-08-31 19:25:00 +000056#include "MagickCore/resource-private.h"
cristy4c08aed2011-07-01 19:47:50 +000057#include "MagickCore/semaphore.h"
58#include "MagickCore/signature-private.h"
59#include "MagickCore/string_.h"
60#include "MagickCore/string-private.h"
61#include "MagickCore/splay-tree.h"
62#include "MagickCore/thread-private.h"
63#include "MagickCore/token.h"
64#include "MagickCore/utility.h"
cristyd1dd6e42011-09-04 01:46:08 +000065#include "MagickCore/utility-private.h"
cristy3ed852e2009-09-05 21:47:34 +000066
67/*
68 Typedef declarations.
69*/
70typedef struct _ResourceInfo
71{
72 MagickOffsetType
73 area,
74 memory,
75 map,
76 disk,
77 file,
78 thread,
79 time;
80
81 MagickSizeType
82 area_limit,
83 memory_limit,
84 map_limit,
85 disk_limit,
86 file_limit,
87 thread_limit,
88 time_limit;
89} ResourceInfo;
90
91/*
92 Global declarations.
93*/
94static RandomInfo
95 *random_info = (RandomInfo *) NULL;
96
97static ResourceInfo
98 resource_info =
99 {
100 MagickULLConstant(0),
101 MagickULLConstant(0),
102 MagickULLConstant(0),
103 MagickULLConstant(0),
104 MagickULLConstant(0),
105 MagickULLConstant(0),
106 MagickULLConstant(0),
cristy2b97bd22011-10-04 18:12:42 +0000107 MagickULLConstant(3072)*1024*1024,
cristy3ed852e2009-09-05 21:47:34 +0000108 MagickULLConstant(1536)*1024*1024,
cristy9bfdd582010-10-23 01:27:25 +0000109 MagickULLConstant(3072)*1024*1024,
cristy3ed852e2009-09-05 21:47:34 +0000110 MagickResourceInfinity,
111 MagickULLConstant(768),
cristy9bfdd582010-10-23 01:27:25 +0000112 MagickULLConstant(4),
cristy3ed852e2009-09-05 21:47:34 +0000113 MagickResourceInfinity
114 };
115
116static SemaphoreInfo
117 *resource_semaphore = (SemaphoreInfo *) NULL;
118
119static SplayTreeInfo
120 *temporary_resources = (SplayTreeInfo *) NULL;
121
122/*
123%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124% %
125% %
126% %
127% A c q u i r e M a g i c k R e s o u r c e %
128% %
129% %
130% %
131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132%
133% AcquireMagickResource() acquires resources of the specified type.
134% MagickFalse is returned if the specified resource is exhausted otherwise
135% MagickTrue.
136%
137% The format of the AcquireMagickResource() method is:
138%
139% MagickBooleanType AcquireMagickResource(const ResourceType type,
140% const MagickSizeType size)
141%
142% A description of each parameter follows:
143%
144% o type: the type of resource.
145%
146% o size: the number of bytes needed from for this resource.
147%
148*/
149MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
150 const MagickSizeType size)
151{
152 char
153 resource_current[MaxTextExtent],
154 resource_limit[MaxTextExtent],
155 resource_request[MaxTextExtent];
156
157 MagickBooleanType
158 status;
159
160 MagickSizeType
161 limit;
162
163 status=MagickFalse;
cristyb9080c92009-12-01 20:13:26 +0000164 (void) FormatMagickSize(size,MagickFalse,resource_request);
cristy18b17442009-10-25 18:36:48 +0000165 if (resource_semaphore == (SemaphoreInfo *) NULL)
166 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000167 LockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000168 switch (type)
169 {
170 case AreaResource:
171 {
172 resource_info.area=(MagickOffsetType) size;
173 limit=resource_info.area_limit;
174 status=(resource_info.area_limit == MagickResourceInfinity) ||
175 (size < limit) ? MagickTrue : MagickFalse;
cristyb9080c92009-12-01 20:13:26 +0000176 (void) FormatMagickSize((MagickSizeType) resource_info.area,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000177 resource_current);
cristyb9080c92009-12-01 20:13:26 +0000178 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
179 resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000180 break;
181 }
182 case MemoryResource:
183 {
184 resource_info.memory+=size;
185 limit=resource_info.memory_limit;
186 status=(resource_info.memory_limit == MagickResourceInfinity) ||
187 ((MagickSizeType) resource_info.memory < limit) ?
188 MagickTrue : MagickFalse;
cristyb9080c92009-12-01 20:13:26 +0000189 (void) FormatMagickSize((MagickSizeType) resource_info.memory,MagickTrue,
cristy3ed852e2009-09-05 21:47:34 +0000190 resource_current);
cristyb9080c92009-12-01 20:13:26 +0000191 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
cristy3ed852e2009-09-05 21:47:34 +0000192 resource_limit);
193 break;
194 }
195 case MapResource:
196 {
197 resource_info.map+=size;
198 limit=resource_info.map_limit;
199 status=(resource_info.map_limit == MagickResourceInfinity) ||
200 ((MagickSizeType) resource_info.map < limit) ?
201 MagickTrue : MagickFalse;
cristyb9080c92009-12-01 20:13:26 +0000202 (void) FormatMagickSize((MagickSizeType) resource_info.map,MagickTrue,
cristy3ed852e2009-09-05 21:47:34 +0000203 resource_current);
cristyb9080c92009-12-01 20:13:26 +0000204 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
cristy3ed852e2009-09-05 21:47:34 +0000205 resource_limit);
206 break;
207 }
208 case DiskResource:
209 {
210 resource_info.disk+=size;
211 limit=resource_info.disk_limit;
212 status=(resource_info.disk_limit == MagickResourceInfinity) ||
213 ((MagickSizeType) resource_info.disk < limit) ?
214 MagickTrue : MagickFalse;
cristy518d13d2011-01-04 15:25:24 +0000215 (void) FormatMagickSize((MagickSizeType) resource_info.disk,MagickTrue,
cristy3ed852e2009-09-05 21:47:34 +0000216 resource_current);
cristy518d13d2011-01-04 15:25:24 +0000217 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
cristyb9080c92009-12-01 20:13:26 +0000218 resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000219 break;
220 }
221 case FileResource:
222 {
223 resource_info.file+=size;
224 limit=resource_info.file_limit;
225 status=(resource_info.file_limit == MagickResourceInfinity) ||
226 ((MagickSizeType) resource_info.file < limit) ?
227 MagickTrue : MagickFalse;
cristyb9080c92009-12-01 20:13:26 +0000228 (void) FormatMagickSize((MagickSizeType) resource_info.file,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000229 resource_current);
230 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
cristyb9080c92009-12-01 20:13:26 +0000231 MagickFalse,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000232 break;
233 }
234 case ThreadResource:
235 {
236 resource_info.thread+=size;
237 limit=resource_info.thread_limit;
238 status=(resource_info.thread_limit == MagickResourceInfinity) ||
239 ((MagickSizeType) resource_info.thread < limit) ?
240 MagickTrue : MagickFalse;
cristyb9080c92009-12-01 20:13:26 +0000241 (void) FormatMagickSize((MagickSizeType) resource_info.thread,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000242 resource_current);
243 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
cristyb9080c92009-12-01 20:13:26 +0000244 MagickFalse,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000245 break;
246 }
247 case TimeResource:
248 {
249 resource_info.time+=size;
250 limit=resource_info.time_limit;
251 status=(resource_info.time_limit == MagickResourceInfinity) ||
252 ((MagickSizeType) resource_info.time < limit) ?
253 MagickTrue : MagickFalse;
cristyb9080c92009-12-01 20:13:26 +0000254 (void) FormatMagickSize((MagickSizeType) resource_info.time,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000255 resource_current);
256 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
cristyb9080c92009-12-01 20:13:26 +0000257 MagickFalse,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000258 break;
259 }
260 default:
261 break;
262 }
cristyf84a1932010-01-03 18:00:18 +0000263 UnlockSemaphoreInfo(resource_semaphore);
cristy9bfdd582010-10-23 01:27:25 +0000264 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
cristy042ee782011-04-22 18:48:30 +0000265 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
cristya21afde2010-07-02 00:45:40 +0000266 resource_request,resource_current,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000267 return(status);
268}
269
270/*
271%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272% %
273% %
274% %
cristycfffdac2010-09-30 03:05:09 +0000275+ 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 %
cristy3ed852e2009-09-05 21:47:34 +0000276% %
277% %
278% %
279%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280%
cristyf34a1452009-10-24 22:29:27 +0000281% AsynchronousResourceComponentTerminus() destroys the resource environment.
282% It differs from ResourceComponentTerminus() in that it can be called from a
cristy3ed852e2009-09-05 21:47:34 +0000283% asynchronous signal handler.
284%
cristyf34a1452009-10-24 22:29:27 +0000285% The format of the ResourceComponentTerminus() method is:
cristy3ed852e2009-09-05 21:47:34 +0000286%
cristyf34a1452009-10-24 22:29:27 +0000287% ResourceComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000288%
289*/
cristy0a4d92f2011-08-31 19:25:00 +0000290MagickPrivate void AsynchronousResourceComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000291{
292 const char
293 *path;
294
295 if (temporary_resources == (SplayTreeInfo *) NULL)
296 return;
297 /*
298 Remove any lingering temporary files.
299 */
300 ResetSplayTreeIterator(temporary_resources);
301 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
302 while (path != (const char *) NULL)
303 {
cristy18c6c272011-09-23 14:40:37 +0000304 (void) remove_utf8(path);
cristy3ed852e2009-09-05 21:47:34 +0000305 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
306 }
307}
308
309/*
310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311% %
312% %
313% %
314% 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 %
315% %
316% %
317% %
318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319%
320% AcquireUniqueFileResource() returns a unique file name, and returns a file
321% descriptor for the file open for reading and writing.
322%
323% The format of the AcquireUniqueFileResource() method is:
324%
325% int AcquireUniqueFileResource(char *path)
326%
327% A description of each parameter follows:
328%
329% o path: Specifies a pointer to an array of characters. The unique path
330% name is returned in this array.
331%
332*/
333
334static void *DestroyTemporaryResources(void *temporary_resource)
335{
cristy18c6c272011-09-23 14:40:37 +0000336 (void) remove_utf8((char *) temporary_resource);
cristycfbec6a2010-09-28 18:27:51 +0000337 temporary_resource=DestroyString((char *) temporary_resource);
cristy3ed852e2009-09-05 21:47:34 +0000338 return((void *) NULL);
339}
340
341static MagickBooleanType GetPathTemplate(char *path)
342{
343 char
344 *directory;
345
346 ExceptionInfo
347 *exception;
348
349 MagickBooleanType
350 status;
351
352 register char
353 *p;
354
355 struct stat
356 attributes;
357
358 (void) CopyMagickString(path,"magick-XXXXXXXX",MaxTextExtent);
359 exception=AcquireExceptionInfo();
360 directory=(char *) GetImageRegistry(StringRegistryType,"temporary-path",
361 exception);
362 exception=DestroyExceptionInfo(exception);
363 if (directory == (char *) NULL)
364 directory=GetEnvironmentValue("MAGICK_TEMPORARY_PATH");
365 if (directory == (char *) NULL)
366 directory=GetEnvironmentValue("MAGICK_TMPDIR");
367 if (directory == (char *) NULL)
368 directory=GetPolicyValue("temporary-path");
369 if (directory == (char *) NULL)
370 directory=GetEnvironmentValue("TMPDIR");
cristy0157aea2010-04-24 21:12:18 +0000371#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
cristy3ed852e2009-09-05 21:47:34 +0000372 if (directory == (char *) NULL)
373 directory=GetEnvironmentValue("TMP");
374 if (directory == (char *) NULL)
375 directory=GetEnvironmentValue("TEMP");
376#endif
377#if defined(__VMS)
378 if (directory == (char *) NULL)
379 directory=GetEnvironmentValue("MTMPDIR");
380#endif
381#if defined(P_tmpdir)
382 if (directory == (char *) NULL)
383 directory=ConstantString(P_tmpdir);
384#endif
385 if (directory == (char *) NULL)
386 return(MagickTrue);
387 if (strlen(directory) > (MaxTextExtent-15))
388 {
389 directory=DestroyString(directory);
390 return(MagickTrue);
391 }
392 status=GetPathAttributes(directory,&attributes);
393 if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
394 {
395 directory=DestroyString(directory);
396 return(MagickTrue);
397 }
398 if (directory[strlen(directory)-1] == *DirectorySeparator)
cristyb51dff52011-05-19 16:55:47 +0000399 (void) FormatLocaleString(path,MaxTextExtent,"%smagick-XXXXXXXX",directory);
cristy3ed852e2009-09-05 21:47:34 +0000400 else
cristyb51dff52011-05-19 16:55:47 +0000401 (void) FormatLocaleString(path,MaxTextExtent,"%s%smagick-XXXXXXXX",
cristy3ed852e2009-09-05 21:47:34 +0000402 directory,DirectorySeparator);
403 directory=DestroyString(directory);
404 if (*DirectorySeparator != '/')
405 for (p=path; *p != '\0'; p++)
406 if (*p == *DirectorySeparator)
407 *p='/';
408 return(MagickTrue);
409}
410
411MagickExport int AcquireUniqueFileResource(char *path)
412{
413#if !defined(O_NOFOLLOW)
414#define O_NOFOLLOW 0
415#endif
416#if !defined(TMP_MAX)
417# define TMP_MAX 238328
418#endif
419
cristy3ed852e2009-09-05 21:47:34 +0000420 int
421 c,
422 file;
423
424 register char
425 *p;
426
cristybb503372010-05-27 20:51:26 +0000427 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000428 i;
429
430 static const char
431 portable_filename[65] =
432 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
433
434 StringInfo
435 *key;
436
437 unsigned char
438 *datum;
439
440 assert(path != (char *) NULL);
441 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
442 if (random_info == (RandomInfo *) NULL)
443 random_info=AcquireRandomInfo();
444 file=(-1);
cristycee97112010-05-28 00:44:52 +0000445 for (i=0; i < (ssize_t) TMP_MAX; i++)
cristy3ed852e2009-09-05 21:47:34 +0000446 {
447 /*
448 Get temporary pathname.
449 */
450 (void) GetPathTemplate(path);
cristy59ca45d2011-02-03 14:54:57 +0000451 key=GetRandomKey(random_info,2);
452 p=path+strlen(path)-8;
453 datum=GetStringInfoDatum(key);
454 for (i=0; i < (ssize_t) GetStringInfoLength(key); i++)
455 {
456 c=(int) (datum[i] & 0x3f);
457 *p++=portable_filename[c];
458 }
459 key=DestroyStringInfo(key);
cristy3ed852e2009-09-05 21:47:34 +0000460#if defined(MAGICKCORE_HAVE_MKSTEMP)
461 file=mkstemp(path);
462#if defined(__OS2__)
463 setmode(file,O_BINARY);
464#endif
465 if (file != -1)
466 break;
467#endif
cristy59ca45d2011-02-03 14:54:57 +0000468 key=GetRandomKey(random_info,6);
469 p=path+strlen(path)-6;
cristy3ed852e2009-09-05 21:47:34 +0000470 datum=GetStringInfoDatum(key);
cristy59ca45d2011-02-03 14:54:57 +0000471 for (i=0; i < (ssize_t) GetStringInfoLength(key); i++)
cristy3ed852e2009-09-05 21:47:34 +0000472 {
473 c=(int) (datum[i] & 0x3f);
474 *p++=portable_filename[c];
475 }
476 key=DestroyStringInfo(key);
cristy18c6c272011-09-23 14:40:37 +0000477 file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,S_MODE);
cristy59ca45d2011-02-03 14:54:57 +0000478 if ((file >= 0) || (errno != EEXIST))
cristy3ed852e2009-09-05 21:47:34 +0000479 break;
480 }
481 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
482 if (file == -1)
483 return(file);
cristy18b17442009-10-25 18:36:48 +0000484 if (resource_semaphore == (SemaphoreInfo *) NULL)
485 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000486 LockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000487 if (temporary_resources == (SplayTreeInfo *) NULL)
488 temporary_resources=NewSplayTree(CompareSplayTreeString,
cristyf77fa462010-09-28 18:35:53 +0000489 DestroyTemporaryResources,(void *(*)(void *)) NULL);
cristyf84a1932010-01-03 18:00:18 +0000490 UnlockSemaphoreInfo(resource_semaphore);
cristycfbec6a2010-09-28 18:27:51 +0000491 (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
cristyf77fa462010-09-28 18:35:53 +0000492 (const void *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000493 return(file);
494}
495
496/*
497%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
498% %
499% %
500% %
cristy3ed852e2009-09-05 21:47:34 +0000501% G e t M a g i c k R e s o u r c e %
502% %
503% %
504% %
505%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
506%
507% GetMagickResource() returns the specified resource.
508%
509% The format of the GetMagickResource() method is:
510%
511% MagickSizeType GetMagickResource(const ResourceType type)
512%
513% A description of each parameter follows:
514%
515% o type: the type of resource.
516%
517*/
518MagickExport MagickSizeType GetMagickResource(const ResourceType type)
519{
520 MagickSizeType
521 resource;
522
523 resource=0;
cristyf84a1932010-01-03 18:00:18 +0000524 LockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000525 switch (type)
526 {
527 case AreaResource:
528 {
529 resource=(MagickSizeType) resource_info.area;
530 break;
531 }
532 case MemoryResource:
533 {
534 resource=(MagickSizeType) resource_info.memory;
535 break;
536 }
537 case MapResource:
538 {
539 resource=(MagickSizeType) resource_info.map;
540 break;
541 }
542 case DiskResource:
543 {
544 resource=(MagickSizeType) resource_info.disk;
545 break;
546 }
547 case FileResource:
548 {
549 resource=(MagickSizeType) resource_info.file;
550 break;
551 }
552 case ThreadResource:
553 {
554 resource=(MagickSizeType) resource_info.thread;
555 break;
556 }
557 case TimeResource:
558 {
559 resource=(MagickSizeType) resource_info.time;
560 break;
561 }
562 default:
563 break;
564 }
cristyf84a1932010-01-03 18:00:18 +0000565 UnlockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000566 return(resource);
567}
568
569/*
570%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
571% %
572% %
573% %
574% G e t M a g i c k R e s o u r c e L i m i t %
575% %
576% %
577% %
578%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
579%
cristy7a40ba82011-01-08 20:31:18 +0000580% GetMagickResourceLimit() returns the specified resource limit.
cristy3ed852e2009-09-05 21:47:34 +0000581%
582% The format of the GetMagickResourceLimit() method is:
583%
cristy50a10922010-02-15 18:35:25 +0000584% MagickSizeType GetMagickResourceLimit(const ResourceType type)
cristy3ed852e2009-09-05 21:47:34 +0000585%
586% A description of each parameter follows:
587%
588% o type: the type of resource.
589%
590*/
591MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
592{
593 MagickSizeType
594 resource;
595
596 resource=0;
cristy18b17442009-10-25 18:36:48 +0000597 if (resource_semaphore == (SemaphoreInfo *) NULL)
598 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000599 LockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000600 switch (type)
601 {
602 case AreaResource:
603 {
604 resource=resource_info.area_limit;
605 break;
606 }
607 case MemoryResource:
608 {
609 resource=resource_info.memory_limit;
610 break;
611 }
612 case MapResource:
613 {
614 resource=resource_info.map_limit;
615 break;
616 }
617 case DiskResource:
618 {
619 resource=resource_info.disk_limit;
620 break;
621 }
622 case FileResource:
623 {
624 resource=resource_info.file_limit;
625 break;
626 }
627 case ThreadResource:
628 {
629 resource=resource_info.thread_limit;
630 break;
631 }
632 case TimeResource:
633 {
634 resource=resource_info.time_limit;
635 break;
636 }
637 default:
638 break;
639 }
cristyf84a1932010-01-03 18:00:18 +0000640 UnlockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000641 return(resource);
642}
643
644/*
645%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
646% %
647% %
648% %
cristy3ed852e2009-09-05 21:47:34 +0000649% L i s t M a g i c k R e s o u r c e I n f o %
650% %
651% %
652% %
653%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
654%
655% ListMagickResourceInfo() lists the resource info to a file.
656%
657% The format of the ListMagickResourceInfo method is:
658%
659% MagickBooleanType ListMagickResourceInfo(FILE *file,
660% ExceptionInfo *exception)
661%
662% A description of each parameter follows.
663%
664% o file: An pointer to a FILE.
665%
666% o exception: return any errors or warnings in this structure.
667%
668*/
669MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
670 ExceptionInfo *magick_unused(exception))
671{
672 char
673 area_limit[MaxTextExtent],
674 disk_limit[MaxTextExtent],
675 map_limit[MaxTextExtent],
676 memory_limit[MaxTextExtent],
677 time_limit[MaxTextExtent];
678
679 if (file == (const FILE *) NULL)
680 file=stdout;
cristy18b17442009-10-25 18:36:48 +0000681 if (resource_semaphore == (SemaphoreInfo *) NULL)
682 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000683 LockSemaphoreInfo(resource_semaphore);
cristyb9080c92009-12-01 20:13:26 +0000684 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,area_limit);
685 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
686 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,map_limit);
cristy9bfdd582010-10-23 01:27:25 +0000687 (void) CopyMagickString(disk_limit,"unlimited",MaxTextExtent);
688 if (resource_info.disk_limit != MagickResourceInfinity)
cristy518d13d2011-01-04 15:25:24 +0000689 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,disk_limit);
cristy3ed852e2009-09-05 21:47:34 +0000690 (void) CopyMagickString(time_limit,"unlimited",MaxTextExtent);
691 if (resource_info.time_limit != MagickResourceInfinity)
cristyb51dff52011-05-19 16:55:47 +0000692 (void) FormatLocaleString(time_limit,MaxTextExtent,"%.20g",(double)
cristy54ea5732011-06-10 12:39:53 +0000693 ((MagickOffsetType) resource_info.time_limit));
cristyb51dff52011-05-19 16:55:47 +0000694 (void) FormatLocaleFile(file,"File Area Memory Map"
cristyf0bfc582009-12-05 15:09:34 +0000695 " Disk Thread Time\n");
cristy1e604812011-05-19 18:07:50 +0000696 (void) FormatLocaleFile(file,
697 "--------------------------------------------------------"
cristyb9080c92009-12-01 20:13:26 +0000698 "-----------------------\n");
cristy1e604812011-05-19 18:07:50 +0000699 (void) FormatLocaleFile(file,"%4g %10s %10s %10s %10s %6g %11s\n",
cristy54ea5732011-06-10 12:39:53 +0000700 (double) ((MagickOffsetType) resource_info.file_limit),area_limit,
701 memory_limit,map_limit,disk_limit,(double) ((MagickOffsetType)
702 resource_info.thread_limit),time_limit);
cristy3ed852e2009-09-05 21:47:34 +0000703 (void) fflush(file);
cristyf84a1932010-01-03 18:00:18 +0000704 UnlockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000705 return(MagickTrue);
706}
707
708/*
709%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710% %
711% %
712% %
713% R e l i n q u i s h M a g i c k R e s o u r c e %
714% %
715% %
716% %
717%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
718%
719% RelinquishMagickResource() relinquishes resources of the specified type.
720%
721% The format of the RelinquishMagickResource() method is:
722%
723% void RelinquishMagickResource(const ResourceType type,
724% const MagickSizeType size)
725%
726% A description of each parameter follows:
727%
728% o type: the type of resource.
729%
730% o size: the size of the resource.
731%
732*/
733MagickExport void RelinquishMagickResource(const ResourceType type,
734 const MagickSizeType size)
735{
736 char
737 resource_current[MaxTextExtent],
738 resource_limit[MaxTextExtent],
739 resource_request[MaxTextExtent];
740
cristyb9080c92009-12-01 20:13:26 +0000741 (void) FormatMagickSize(size,MagickFalse,resource_request);
cristy18b17442009-10-25 18:36:48 +0000742 if (resource_semaphore == (SemaphoreInfo *) NULL)
743 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000744 LockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000745 switch (type)
746 {
747 case AreaResource:
748 {
749 resource_info.area=(MagickOffsetType) size;
cristyb9080c92009-12-01 20:13:26 +0000750 (void) FormatMagickSize((MagickSizeType) resource_info.area,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000751 resource_current);
cristyb9080c92009-12-01 20:13:26 +0000752 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
753 resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000754 break;
755 }
756 case MemoryResource:
757 {
758 resource_info.memory-=size;
759 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
cristyb9080c92009-12-01 20:13:26 +0000760 MagickTrue,resource_current);
761 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
762 resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000763 break;
764 }
765 case MapResource:
766 {
767 resource_info.map-=size;
cristyb9080c92009-12-01 20:13:26 +0000768 (void) FormatMagickSize((MagickSizeType) resource_info.map,MagickTrue,
cristy3ed852e2009-09-05 21:47:34 +0000769 resource_current);
cristyb9080c92009-12-01 20:13:26 +0000770 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
771 resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000772 break;
773 }
774 case DiskResource:
775 {
776 resource_info.disk-=size;
cristy518d13d2011-01-04 15:25:24 +0000777 (void) FormatMagickSize((MagickSizeType) resource_info.disk,MagickTrue,
cristy3ed852e2009-09-05 21:47:34 +0000778 resource_current);
cristy518d13d2011-01-04 15:25:24 +0000779 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
cristyb9080c92009-12-01 20:13:26 +0000780 resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000781 break;
782 }
783 case FileResource:
784 {
785 resource_info.file-=size;
cristyb9080c92009-12-01 20:13:26 +0000786 (void) FormatMagickSize((MagickSizeType) resource_info.file,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000787 resource_current);
788 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
cristyb9080c92009-12-01 20:13:26 +0000789 MagickFalse,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000790 break;
791 }
792 case ThreadResource:
793 {
794 resource_info.thread-=size;
cristyb9080c92009-12-01 20:13:26 +0000795 (void) FormatMagickSize((MagickSizeType) resource_info.thread,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000796 resource_current);
797 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
cristyb9080c92009-12-01 20:13:26 +0000798 MagickFalse,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000799 break;
800 }
801 case TimeResource:
802 {
803 resource_info.time-=size;
cristyb9080c92009-12-01 20:13:26 +0000804 (void) FormatMagickSize((MagickSizeType) resource_info.time,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000805 resource_current);
806 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
cristyb9080c92009-12-01 20:13:26 +0000807 MagickFalse,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000808 break;
809 }
810 default:
811 break;
812 }
cristyf84a1932010-01-03 18:00:18 +0000813 UnlockSemaphoreInfo(resource_semaphore);
cristy9bfdd582010-10-23 01:27:25 +0000814 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
cristy042ee782011-04-22 18:48:30 +0000815 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
cristya21afde2010-07-02 00:45:40 +0000816 resource_request,resource_current,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000817}
818
819/*
820%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
821% %
822% %
823% %
824% 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 %
825% %
826% %
827% %
828%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
829%
830% RelinquishUniqueFileResource() relinquishes a unique file resource.
831%
832% The format of the RelinquishUniqueFileResource() method is:
833%
834% MagickBooleanType RelinquishUniqueFileResource(const char *path)
835%
836% A description of each parameter follows:
837%
838% o name: the name of the temporary resource.
839%
840*/
841MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
842{
843 char
844 cache_path[MaxTextExtent];
845
846 assert(path != (const char *) NULL);
847 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
848 if (temporary_resources != (SplayTreeInfo *) NULL)
849 {
850 register char
851 *p;
852
853 ResetSplayTreeIterator(temporary_resources);
854 p=(char *) GetNextKeyInSplayTree(temporary_resources);
855 while (p != (char *) NULL)
856 {
857 if (LocaleCompare(p,path) == 0)
858 break;
859 p=(char *) GetNextKeyInSplayTree(temporary_resources);
860 }
861 if (p != (char *) NULL)
862 (void) DeleteNodeFromSplayTree(temporary_resources,p);
863 }
864 (void) CopyMagickString(cache_path,path,MaxTextExtent);
865 AppendImageFormat("cache",cache_path);
cristy18c6c272011-09-23 14:40:37 +0000866 (void) remove_utf8(cache_path);
867 return(remove_utf8(path) == 0 ? MagickTrue : MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +0000868}
869
870/*
871%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872% %
873% %
874% %
cristyf34a1452009-10-24 22:29:27 +0000875+ R e s o u r c e C o m p o n e n t G e n e s i s %
876% %
877% %
878% %
879%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
880%
881% ResourceComponentGenesis() instantiates the resource component.
882%
883% The format of the ResourceComponentGenesis method is:
884%
885% MagickBooleanType ResourceComponentGenesis(void)
886%
887*/
888
cristy652316c2010-11-23 13:49:46 +0000889static inline size_t MagickMax(const size_t x,const size_t y)
cristyf34a1452009-10-24 22:29:27 +0000890{
891 if (x > y)
892 return(x);
893 return(y);
894}
895
896static inline MagickSizeType StringToSizeType(const char *string,
897 const double interval)
898{
899 double
900 value;
901
cristy9b34e302011-11-05 02:15:45 +0000902 value=SiPrefixToDoubleInterval(string,interval);
cristyf34a1452009-10-24 22:29:27 +0000903 if (value >= (double) MagickULLConstant(~0))
904 return(MagickULLConstant(~0));
905 return((MagickSizeType) value);
906}
907
cristy5ff4eaf2011-09-03 01:38:02 +0000908MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +0000909{
910 char
911 *limit;
912
cristy9d314ff2011-03-09 01:30:28 +0000913 MagickSizeType
914 memory;
915
cristybb503372010-05-27 20:51:26 +0000916 ssize_t
cristyf34a1452009-10-24 22:29:27 +0000917 files,
918 pages,
919 pagesize;
920
cristyf34a1452009-10-24 22:29:27 +0000921 /*
922 Set Magick resource limits.
923 */
cristy165b6092009-10-26 13:52:10 +0000924 AcquireSemaphoreInfo(&resource_semaphore);
cristyf34a1452009-10-24 22:29:27 +0000925 pagesize=GetMagickPageSize();
926 pages=(-1);
927#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
cristycee97112010-05-28 00:44:52 +0000928 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
cristyf34a1452009-10-24 22:29:27 +0000929#endif
930 memory=(MagickSizeType) pages*pagesize;
931 if ((pagesize <= 0) || (pages <= 0))
932 memory=2048UL*1024UL*1024UL;
933#if defined(PixelCacheThreshold)
934 memory=PixelCacheThreshold;
935#endif
cristy2b97bd22011-10-04 18:12:42 +0000936 (void) SetMagickResourceLimit(AreaResource,2*memory);
cristyb0a27eb2010-10-23 23:34:32 +0000937 (void) SetMagickResourceLimit(MemoryResource,memory);
938 (void) SetMagickResourceLimit(MapResource,2*memory);
cristyf34a1452009-10-24 22:29:27 +0000939 limit=GetEnvironmentValue("MAGICK_AREA_LIMIT");
940 if (limit == (char *) NULL)
941 limit=GetPolicyValue("area");
942 if (limit != (char *) NULL)
943 {
944 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
945 limit=DestroyString(limit);
946 }
947 limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT");
948 if (limit == (char *) NULL)
949 limit=GetPolicyValue("memory");
950 if (limit != (char *) NULL)
951 {
952 (void) SetMagickResourceLimit(MemoryResource,
953 StringToSizeType(limit,100.0));
954 limit=DestroyString(limit);
955 }
956 limit=GetEnvironmentValue("MAGICK_MAP_LIMIT");
957 if (limit == (char *) NULL)
958 limit=GetPolicyValue("map");
959 if (limit != (char *) NULL)
960 {
961 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
962 limit=DestroyString(limit);
963 }
964 limit=GetEnvironmentValue("MAGICK_DISK_LIMIT");
965 if (limit == (char *) NULL)
966 limit=GetPolicyValue("disk");
967 if (limit != (char *) NULL)
968 {
969 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
970 limit=DestroyString(limit);
971 }
972 files=(-1);
973#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
cristycee97112010-05-28 00:44:52 +0000974 files=(ssize_t) sysconf(_SC_OPEN_MAX);
cristyf34a1452009-10-24 22:29:27 +0000975#endif
976#if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
977 if (files < 0)
978 {
979 struct rlimit
980 resources;
981
982 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
cristybb503372010-05-27 20:51:26 +0000983 files=(ssize_t) resources.rlim_cur;
cristyf34a1452009-10-24 22:29:27 +0000984 }
985#endif
986#if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
987 if (files < 0)
cristy6d0ee3e2010-09-28 18:36:50 +0000988 files=(ssize_t) getdtablesize();
cristyf34a1452009-10-24 22:29:27 +0000989#endif
990 if (files < 0)
991 files=64;
cristybb503372010-05-27 20:51:26 +0000992 (void) SetMagickResourceLimit(FileResource,MagickMax((size_t)
cristyf34a1452009-10-24 22:29:27 +0000993 (3*files/4),64));
994 limit=GetEnvironmentValue("MAGICK_FILE_LIMIT");
995 if (limit == (char *) NULL)
996 limit=GetPolicyValue("file");
997 if (limit != (char *) NULL)
998 {
cristycfce4c92011-12-11 17:28:48 +0000999 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,
1000 100.0));
cristyf34a1452009-10-24 22:29:27 +00001001 limit=DestroyString(limit);
1002 }
1003 (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads());
1004 limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT");
1005 if (limit == (char *) NULL)
1006 limit=GetPolicyValue("thread");
1007 if (limit != (char *) NULL)
1008 {
cristyf34a1452009-10-24 22:29:27 +00001009 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
1010 100.0));
1011 limit=DestroyString(limit);
1012 }
1013 limit=GetEnvironmentValue("MAGICK_TIME_LIMIT");
1014 if (limit == (char *) NULL)
1015 limit=GetPolicyValue("time");
1016 if (limit != (char *) NULL)
1017 {
1018 (void) SetMagickResourceLimit(TimeResource,StringToSizeType(limit,100.0));
1019 limit=DestroyString(limit);
1020 }
1021 return(MagickTrue);
1022}
1023
1024/*
1025%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1026% %
1027% %
1028% %
1029+ 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 %
1030% %
1031% %
1032% %
1033%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1034%
1035% ResourceComponentTerminus() destroys the resource component.
1036%
1037% The format of the ResourceComponentTerminus() method is:
1038%
1039% ResourceComponentTerminus(void)
1040%
1041*/
cristy5ff4eaf2011-09-03 01:38:02 +00001042MagickPrivate void ResourceComponentTerminus(void)
cristyf34a1452009-10-24 22:29:27 +00001043{
cristy18b17442009-10-25 18:36:48 +00001044 if (resource_semaphore == (SemaphoreInfo *) NULL)
1045 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001046 LockSemaphoreInfo(resource_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001047 if (temporary_resources != (SplayTreeInfo *) NULL)
1048 temporary_resources=DestroySplayTree(temporary_resources);
1049 if (random_info != (RandomInfo *) NULL)
1050 random_info=DestroyRandomInfo(random_info);
cristyf84a1932010-01-03 18:00:18 +00001051 UnlockSemaphoreInfo(resource_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001052 DestroySemaphoreInfo(&resource_semaphore);
1053}
1054
1055/*
1056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1057% %
1058% %
1059% %
cristy3ed852e2009-09-05 21:47:34 +00001060% S e t M a g i c k R e s o u r c e L i m i t %
1061% %
1062% %
1063% %
1064%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1065%
1066% SetMagickResourceLimit() sets the limit for a particular resource.
1067%
1068% The format of the SetMagickResourceLimit() method is:
1069%
1070% MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1071% const MagickSizeType limit)
1072%
1073% A description of each parameter follows:
1074%
1075% o type: the type of resource.
1076%
1077% o limit: the maximum limit for the resource.
1078%
1079*/
cristy652316c2010-11-23 13:49:46 +00001080
cristy55a91cd2010-12-01 00:57:40 +00001081static inline MagickSizeType MagickMin(const MagickSizeType x,
1082 const MagickSizeType y)
cristy652316c2010-11-23 13:49:46 +00001083{
1084 if (x < y)
1085 return(x);
1086 return(y);
1087}
1088
cristy3ed852e2009-09-05 21:47:34 +00001089MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1090 const MagickSizeType limit)
1091{
cristy652316c2010-11-23 13:49:46 +00001092 char
1093 *value;
1094
cristy18b17442009-10-25 18:36:48 +00001095 if (resource_semaphore == (SemaphoreInfo *) NULL)
1096 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001097 LockSemaphoreInfo(resource_semaphore);
cristye2837ed2011-09-06 01:49:42 +00001098 value=(char *) NULL;
cristy3ed852e2009-09-05 21:47:34 +00001099 switch (type)
1100 {
1101 case AreaResource:
1102 {
1103 resource_info.area_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001104 value=GetPolicyValue("area");
1105 if (value != (char *) NULL)
1106 resource_info.area_limit=MagickMin(limit,StringToSizeType(value,100.0));
cristy3ed852e2009-09-05 21:47:34 +00001107 break;
1108 }
1109 case MemoryResource:
1110 {
1111 resource_info.memory_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001112 value=GetPolicyValue("memory");
1113 if (value != (char *) NULL)
1114 resource_info.memory_limit=MagickMin(limit,StringToSizeType(value,
1115 100.0));
cristy3ed852e2009-09-05 21:47:34 +00001116 break;
1117 }
1118 case MapResource:
1119 {
1120 resource_info.map_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001121 value=GetPolicyValue("map");
1122 if (value != (char *) NULL)
1123 resource_info.map_limit=MagickMin(limit,StringToSizeType(value,100.0));
cristy3ed852e2009-09-05 21:47:34 +00001124 break;
1125 }
1126 case DiskResource:
1127 {
1128 resource_info.disk_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001129 value=GetPolicyValue("disk");
1130 if (value != (char *) NULL)
1131 resource_info.disk_limit=MagickMin(limit,StringToSizeType(value,100.0));
cristy3ed852e2009-09-05 21:47:34 +00001132 break;
1133 }
1134 case FileResource:
1135 {
1136 resource_info.file_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001137 value=GetPolicyValue("file");
1138 if (value != (char *) NULL)
1139 resource_info.file_limit=MagickMin(limit,StringToSizeType(value,100.0));
cristy3ed852e2009-09-05 21:47:34 +00001140 break;
1141 }
1142 case ThreadResource:
1143 {
cristy01e36dc2010-10-21 17:26:42 +00001144 resource_info.thread_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001145 value=GetPolicyValue("thread");
1146 if (value != (char *) NULL)
1147 resource_info.thread_limit=MagickMin(limit,StringToSizeType(value,
1148 100.0));
1149 SetOpenMPMaximumThreads((int) resource_info.thread_limit);
cristy3ed852e2009-09-05 21:47:34 +00001150 break;
1151 }
1152 case TimeResource:
1153 {
1154 resource_info.time_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001155 value=GetPolicyValue("time");
1156 if (value != (char *) NULL)
1157 resource_info.time_limit=MagickMin(limit,StringToSizeType(value,100.0));
cristy3ed852e2009-09-05 21:47:34 +00001158 break;
1159 }
1160 default:
1161 break;
1162 }
cristye2837ed2011-09-06 01:49:42 +00001163 if (value != (char *) NULL)
1164 value=DestroyString(value);
cristyf84a1932010-01-03 18:00:18 +00001165 UnlockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001166 return(MagickTrue);
1167}