blob: 30f8cd5572c88bf4a1b679ae0466a749ff97fb3d [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),
cristyc6e273e2012-09-10 22:49:21 +0000112 MagickULLConstant(1),
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 {
cristy3ed852e2009-09-05 21:47:34 +0000236 limit=resource_info.thread_limit;
237 status=(resource_info.thread_limit == MagickResourceInfinity) ||
238 ((MagickSizeType) resource_info.thread < limit) ?
239 MagickTrue : MagickFalse;
cristyb9080c92009-12-01 20:13:26 +0000240 (void) FormatMagickSize((MagickSizeType) resource_info.thread,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000241 resource_current);
242 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
cristyb9080c92009-12-01 20:13:26 +0000243 MagickFalse,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000244 break;
245 }
246 case TimeResource:
247 {
248 resource_info.time+=size;
249 limit=resource_info.time_limit;
250 status=(resource_info.time_limit == MagickResourceInfinity) ||
251 ((MagickSizeType) resource_info.time < limit) ?
252 MagickTrue : MagickFalse;
cristyb9080c92009-12-01 20:13:26 +0000253 (void) FormatMagickSize((MagickSizeType) resource_info.time,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000254 resource_current);
255 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
cristyb9080c92009-12-01 20:13:26 +0000256 MagickFalse,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000257 break;
258 }
259 default:
260 break;
261 }
cristyf84a1932010-01-03 18:00:18 +0000262 UnlockSemaphoreInfo(resource_semaphore);
cristy9bfdd582010-10-23 01:27:25 +0000263 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
cristy042ee782011-04-22 18:48:30 +0000264 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
cristya21afde2010-07-02 00:45:40 +0000265 resource_request,resource_current,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000266 return(status);
267}
268
269/*
270%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271% %
272% %
273% %
cristycfffdac2010-09-30 03:05:09 +0000274+ 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 +0000275% %
276% %
277% %
278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279%
cristyf34a1452009-10-24 22:29:27 +0000280% AsynchronousResourceComponentTerminus() destroys the resource environment.
281% It differs from ResourceComponentTerminus() in that it can be called from a
cristy3ed852e2009-09-05 21:47:34 +0000282% asynchronous signal handler.
283%
cristyf34a1452009-10-24 22:29:27 +0000284% The format of the ResourceComponentTerminus() method is:
cristy3ed852e2009-09-05 21:47:34 +0000285%
cristyf34a1452009-10-24 22:29:27 +0000286% ResourceComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000287%
288*/
cristy0a4d92f2011-08-31 19:25:00 +0000289MagickPrivate void AsynchronousResourceComponentTerminus(void)
cristy3ed852e2009-09-05 21:47:34 +0000290{
291 const char
292 *path;
293
294 if (temporary_resources == (SplayTreeInfo *) NULL)
295 return;
296 /*
297 Remove any lingering temporary files.
298 */
299 ResetSplayTreeIterator(temporary_resources);
300 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
301 while (path != (const char *) NULL)
302 {
cristy18c6c272011-09-23 14:40:37 +0000303 (void) remove_utf8(path);
cristy3ed852e2009-09-05 21:47:34 +0000304 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
305 }
306}
307
308/*
309%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
310% %
311% %
312% %
313% 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 %
314% %
315% %
316% %
317%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318%
319% AcquireUniqueFileResource() returns a unique file name, and returns a file
320% descriptor for the file open for reading and writing.
321%
322% The format of the AcquireUniqueFileResource() method is:
323%
324% int AcquireUniqueFileResource(char *path)
325%
326% A description of each parameter follows:
327%
328% o path: Specifies a pointer to an array of characters. The unique path
329% name is returned in this array.
330%
331*/
332
333static void *DestroyTemporaryResources(void *temporary_resource)
334{
cristy18c6c272011-09-23 14:40:37 +0000335 (void) remove_utf8((char *) temporary_resource);
cristycfbec6a2010-09-28 18:27:51 +0000336 temporary_resource=DestroyString((char *) temporary_resource);
cristy3ed852e2009-09-05 21:47:34 +0000337 return((void *) NULL);
338}
339
340static MagickBooleanType GetPathTemplate(char *path)
341{
342 char
343 *directory;
344
345 ExceptionInfo
346 *exception;
347
348 MagickBooleanType
349 status;
350
351 register char
352 *p;
353
354 struct stat
355 attributes;
356
cristy65a933a2012-10-18 11:58:05 +0000357 (void) FormatLocaleString(path,MaxTextExtent,"magick-%.20gXXXXXXXXXXXX",
cristy3080b912012-10-17 13:23:44 +0000358 (double) getpid());
cristy3ed852e2009-09-05 21:47:34 +0000359 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);
cristycdb573d2012-10-18 11:55:05 +0000387 if (strlen(directory) > (MaxTextExtent-25))
cristy3ed852e2009-09-05 21:47:34 +0000388 {
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)
cristy65a933a2012-10-18 11:58:05 +0000399 (void) FormatLocaleString(path,MaxTextExtent,"%smagick-%.20gXXXXXXXXXXXX",
cristy3080b912012-10-17 13:23:44 +0000400 directory,(double) getpid());
cristy3ed852e2009-09-05 21:47:34 +0000401 else
cristy65a933a2012-10-18 11:58:05 +0000402 (void) FormatLocaleString(path,MaxTextExtent,"%s%smagick-%.20gXXXXXXXXXXXX",
403 directory,DirectorySeparator,(double) getpid());
cristy3ed852e2009-09-05 21:47:34 +0000404 directory=DestroyString(directory);
405 if (*DirectorySeparator != '/')
406 for (p=path; *p != '\0'; p++)
407 if (*p == *DirectorySeparator)
408 *p='/';
409 return(MagickTrue);
410}
411
412MagickExport int AcquireUniqueFileResource(char *path)
413{
414#if !defined(O_NOFOLLOW)
415#define O_NOFOLLOW 0
416#endif
417#if !defined(TMP_MAX)
418# define TMP_MAX 238328
419#endif
420
cristy3ed852e2009-09-05 21:47:34 +0000421 int
422 c,
423 file;
424
425 register char
426 *p;
427
cristybb503372010-05-27 20:51:26 +0000428 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000429 i;
430
431 static const char
432 portable_filename[65] =
433 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
434
435 StringInfo
436 *key;
437
438 unsigned char
439 *datum;
440
441 assert(path != (char *) NULL);
442 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
443 if (random_info == (RandomInfo *) NULL)
444 random_info=AcquireRandomInfo();
445 file=(-1);
cristycee97112010-05-28 00:44:52 +0000446 for (i=0; i < (ssize_t) TMP_MAX; i++)
cristy3ed852e2009-09-05 21:47:34 +0000447 {
448 /*
449 Get temporary pathname.
450 */
451 (void) GetPathTemplate(path);
cristycb8cea72012-10-18 12:06:29 +0000452 key=GetRandomKey(random_info,6);
cristycdb573d2012-10-18 11:55:05 +0000453 p=path+strlen(path)-12;
cristy59ca45d2011-02-03 14:54:57 +0000454 datum=GetStringInfoDatum(key);
455 for (i=0; i < (ssize_t) GetStringInfoLength(key); i++)
456 {
457 c=(int) (datum[i] & 0x3f);
458 *p++=portable_filename[c];
459 }
460 key=DestroyStringInfo(key);
cristy3ed852e2009-09-05 21:47:34 +0000461#if defined(MAGICKCORE_HAVE_MKSTEMP)
462 file=mkstemp(path);
463#if defined(__OS2__)
464 setmode(file,O_BINARY);
465#endif
466 if (file != -1)
467 break;
468#endif
cristycdb573d2012-10-18 11:55:05 +0000469 key=GetRandomKey(random_info,12);
470 p=path+strlen(path)-12;
cristy3ed852e2009-09-05 21:47:34 +0000471 datum=GetStringInfoDatum(key);
cristy59ca45d2011-02-03 14:54:57 +0000472 for (i=0; i < (ssize_t) GetStringInfoLength(key); i++)
cristy3ed852e2009-09-05 21:47:34 +0000473 {
474 c=(int) (datum[i] & 0x3f);
475 *p++=portable_filename[c];
476 }
477 key=DestroyStringInfo(key);
cristycdb573d2012-10-18 11:55:05 +0000478 file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
479 S_MODE);
cristy59ca45d2011-02-03 14:54:57 +0000480 if ((file >= 0) || (errno != EEXIST))
cristy3ed852e2009-09-05 21:47:34 +0000481 break;
482 }
483 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
484 if (file == -1)
485 return(file);
cristy18b17442009-10-25 18:36:48 +0000486 if (resource_semaphore == (SemaphoreInfo *) NULL)
487 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000488 LockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000489 if (temporary_resources == (SplayTreeInfo *) NULL)
490 temporary_resources=NewSplayTree(CompareSplayTreeString,
cristyf77fa462010-09-28 18:35:53 +0000491 DestroyTemporaryResources,(void *(*)(void *)) NULL);
cristyf84a1932010-01-03 18:00:18 +0000492 UnlockSemaphoreInfo(resource_semaphore);
cristycfbec6a2010-09-28 18:27:51 +0000493 (void) AddValueToSplayTree(temporary_resources,ConstantString(path),
cristyf77fa462010-09-28 18:35:53 +0000494 (const void *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000495 return(file);
496}
497
498/*
499%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
500% %
501% %
502% %
cristy3ed852e2009-09-05 21:47:34 +0000503% G e t M a g i c k R e s o u r c e %
504% %
505% %
506% %
507%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
508%
509% GetMagickResource() returns the specified resource.
510%
511% The format of the GetMagickResource() method is:
512%
513% MagickSizeType GetMagickResource(const ResourceType type)
514%
515% A description of each parameter follows:
516%
517% o type: the type of resource.
518%
519*/
520MagickExport MagickSizeType GetMagickResource(const ResourceType type)
521{
522 MagickSizeType
523 resource;
524
525 resource=0;
cristyf84a1932010-01-03 18:00:18 +0000526 LockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000527 switch (type)
528 {
529 case AreaResource:
530 {
531 resource=(MagickSizeType) resource_info.area;
532 break;
533 }
534 case MemoryResource:
535 {
536 resource=(MagickSizeType) resource_info.memory;
537 break;
538 }
539 case MapResource:
540 {
541 resource=(MagickSizeType) resource_info.map;
542 break;
543 }
544 case DiskResource:
545 {
546 resource=(MagickSizeType) resource_info.disk;
547 break;
548 }
549 case FileResource:
550 {
551 resource=(MagickSizeType) resource_info.file;
552 break;
553 }
554 case ThreadResource:
555 {
556 resource=(MagickSizeType) resource_info.thread;
557 break;
558 }
559 case TimeResource:
560 {
561 resource=(MagickSizeType) resource_info.time;
562 break;
563 }
564 default:
565 break;
566 }
cristyf84a1932010-01-03 18:00:18 +0000567 UnlockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000568 return(resource);
569}
570
571/*
572%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
573% %
574% %
575% %
576% G e t M a g i c k R e s o u r c e L i m i t %
577% %
578% %
579% %
580%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
581%
cristy7a40ba82011-01-08 20:31:18 +0000582% GetMagickResourceLimit() returns the specified resource limit.
cristy3ed852e2009-09-05 21:47:34 +0000583%
584% The format of the GetMagickResourceLimit() method is:
585%
cristy50a10922010-02-15 18:35:25 +0000586% MagickSizeType GetMagickResourceLimit(const ResourceType type)
cristy3ed852e2009-09-05 21:47:34 +0000587%
588% A description of each parameter follows:
589%
590% o type: the type of resource.
591%
592*/
593MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
594{
595 MagickSizeType
596 resource;
597
598 resource=0;
cristy18b17442009-10-25 18:36:48 +0000599 if (resource_semaphore == (SemaphoreInfo *) NULL)
600 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000601 LockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000602 switch (type)
603 {
604 case AreaResource:
605 {
606 resource=resource_info.area_limit;
607 break;
608 }
609 case MemoryResource:
610 {
611 resource=resource_info.memory_limit;
612 break;
613 }
614 case MapResource:
615 {
616 resource=resource_info.map_limit;
617 break;
618 }
619 case DiskResource:
620 {
621 resource=resource_info.disk_limit;
622 break;
623 }
624 case FileResource:
625 {
626 resource=resource_info.file_limit;
627 break;
628 }
629 case ThreadResource:
630 {
631 resource=resource_info.thread_limit;
632 break;
633 }
634 case TimeResource:
635 {
636 resource=resource_info.time_limit;
637 break;
638 }
639 default:
640 break;
641 }
cristyf84a1932010-01-03 18:00:18 +0000642 UnlockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000643 return(resource);
644}
645
646/*
647%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
648% %
649% %
650% %
cristy3ed852e2009-09-05 21:47:34 +0000651% L i s t M a g i c k R e s o u r c e I n f o %
652% %
653% %
654% %
655%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
656%
657% ListMagickResourceInfo() lists the resource info to a file.
658%
659% The format of the ListMagickResourceInfo method is:
660%
661% MagickBooleanType ListMagickResourceInfo(FILE *file,
662% ExceptionInfo *exception)
663%
664% A description of each parameter follows.
665%
666% o file: An pointer to a FILE.
667%
668% o exception: return any errors or warnings in this structure.
669%
670*/
671MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
672 ExceptionInfo *magick_unused(exception))
673{
674 char
675 area_limit[MaxTextExtent],
676 disk_limit[MaxTextExtent],
677 map_limit[MaxTextExtent],
678 memory_limit[MaxTextExtent],
679 time_limit[MaxTextExtent];
680
681 if (file == (const FILE *) NULL)
682 file=stdout;
cristy18b17442009-10-25 18:36:48 +0000683 if (resource_semaphore == (SemaphoreInfo *) NULL)
684 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000685 LockSemaphoreInfo(resource_semaphore);
cristyb9080c92009-12-01 20:13:26 +0000686 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,area_limit);
687 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
688 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,map_limit);
cristy9bfdd582010-10-23 01:27:25 +0000689 (void) CopyMagickString(disk_limit,"unlimited",MaxTextExtent);
690 if (resource_info.disk_limit != MagickResourceInfinity)
cristy518d13d2011-01-04 15:25:24 +0000691 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,disk_limit);
cristy3ed852e2009-09-05 21:47:34 +0000692 (void) CopyMagickString(time_limit,"unlimited",MaxTextExtent);
693 if (resource_info.time_limit != MagickResourceInfinity)
cristyb51dff52011-05-19 16:55:47 +0000694 (void) FormatLocaleString(time_limit,MaxTextExtent,"%.20g",(double)
cristy54ea5732011-06-10 12:39:53 +0000695 ((MagickOffsetType) resource_info.time_limit));
cristyb51dff52011-05-19 16:55:47 +0000696 (void) FormatLocaleFile(file,"File Area Memory Map"
cristyf0bfc582009-12-05 15:09:34 +0000697 " Disk Thread Time\n");
cristy1e604812011-05-19 18:07:50 +0000698 (void) FormatLocaleFile(file,
699 "--------------------------------------------------------"
cristyb9080c92009-12-01 20:13:26 +0000700 "-----------------------\n");
cristy1e604812011-05-19 18:07:50 +0000701 (void) FormatLocaleFile(file,"%4g %10s %10s %10s %10s %6g %11s\n",
cristy54ea5732011-06-10 12:39:53 +0000702 (double) ((MagickOffsetType) resource_info.file_limit),area_limit,
703 memory_limit,map_limit,disk_limit,(double) ((MagickOffsetType)
704 resource_info.thread_limit),time_limit);
cristy3ed852e2009-09-05 21:47:34 +0000705 (void) fflush(file);
cristyf84a1932010-01-03 18:00:18 +0000706 UnlockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000707 return(MagickTrue);
708}
709
710/*
711%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
712% %
713% %
714% %
715% R e l i n q u i s h M a g i c k R e s o u r c e %
716% %
717% %
718% %
719%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
720%
721% RelinquishMagickResource() relinquishes resources of the specified type.
722%
723% The format of the RelinquishMagickResource() method is:
724%
725% void RelinquishMagickResource(const ResourceType type,
726% const MagickSizeType size)
727%
728% A description of each parameter follows:
729%
730% o type: the type of resource.
731%
732% o size: the size of the resource.
733%
734*/
735MagickExport void RelinquishMagickResource(const ResourceType type,
736 const MagickSizeType size)
737{
738 char
739 resource_current[MaxTextExtent],
740 resource_limit[MaxTextExtent],
741 resource_request[MaxTextExtent];
742
cristyb9080c92009-12-01 20:13:26 +0000743 (void) FormatMagickSize(size,MagickFalse,resource_request);
cristy18b17442009-10-25 18:36:48 +0000744 if (resource_semaphore == (SemaphoreInfo *) NULL)
745 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +0000746 LockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000747 switch (type)
748 {
749 case AreaResource:
750 {
751 resource_info.area=(MagickOffsetType) size;
cristyb9080c92009-12-01 20:13:26 +0000752 (void) FormatMagickSize((MagickSizeType) resource_info.area,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000753 resource_current);
cristyb9080c92009-12-01 20:13:26 +0000754 (void) FormatMagickSize(resource_info.area_limit,MagickFalse,
755 resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000756 break;
757 }
758 case MemoryResource:
759 {
760 resource_info.memory-=size;
761 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
cristyb9080c92009-12-01 20:13:26 +0000762 MagickTrue,resource_current);
763 (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
764 resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000765 break;
766 }
767 case MapResource:
768 {
769 resource_info.map-=size;
cristyb9080c92009-12-01 20:13:26 +0000770 (void) FormatMagickSize((MagickSizeType) resource_info.map,MagickTrue,
cristy3ed852e2009-09-05 21:47:34 +0000771 resource_current);
cristyb9080c92009-12-01 20:13:26 +0000772 (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
773 resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000774 break;
775 }
776 case DiskResource:
777 {
778 resource_info.disk-=size;
cristy518d13d2011-01-04 15:25:24 +0000779 (void) FormatMagickSize((MagickSizeType) resource_info.disk,MagickTrue,
cristy3ed852e2009-09-05 21:47:34 +0000780 resource_current);
cristy518d13d2011-01-04 15:25:24 +0000781 (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
cristyb9080c92009-12-01 20:13:26 +0000782 resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000783 break;
784 }
785 case FileResource:
786 {
787 resource_info.file-=size;
cristyb9080c92009-12-01 20:13:26 +0000788 (void) FormatMagickSize((MagickSizeType) resource_info.file,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000789 resource_current);
790 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
cristyb9080c92009-12-01 20:13:26 +0000791 MagickFalse,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000792 break;
793 }
794 case ThreadResource:
795 {
cristyb9080c92009-12-01 20:13:26 +0000796 (void) FormatMagickSize((MagickSizeType) resource_info.thread,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000797 resource_current);
798 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
cristyb9080c92009-12-01 20:13:26 +0000799 MagickFalse,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000800 break;
801 }
802 case TimeResource:
803 {
804 resource_info.time-=size;
cristyb9080c92009-12-01 20:13:26 +0000805 (void) FormatMagickSize((MagickSizeType) resource_info.time,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +0000806 resource_current);
807 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
cristyb9080c92009-12-01 20:13:26 +0000808 MagickFalse,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000809 break;
810 }
811 default:
812 break;
813 }
cristyf84a1932010-01-03 18:00:18 +0000814 UnlockSemaphoreInfo(resource_semaphore);
cristy9bfdd582010-10-23 01:27:25 +0000815 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
cristy042ee782011-04-22 18:48:30 +0000816 CommandOptionToMnemonic(MagickResourceOptions,(ssize_t) type),
cristya21afde2010-07-02 00:45:40 +0000817 resource_request,resource_current,resource_limit);
cristy3ed852e2009-09-05 21:47:34 +0000818}
819
820/*
821%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822% %
823% %
824% %
825% 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 %
826% %
827% %
828% %
829%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830%
831% RelinquishUniqueFileResource() relinquishes a unique file resource.
832%
833% The format of the RelinquishUniqueFileResource() method is:
834%
835% MagickBooleanType RelinquishUniqueFileResource(const char *path)
836%
837% A description of each parameter follows:
838%
839% o name: the name of the temporary resource.
840%
841*/
842MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
843{
844 char
845 cache_path[MaxTextExtent];
846
847 assert(path != (const char *) NULL);
848 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
849 if (temporary_resources != (SplayTreeInfo *) NULL)
850 {
851 register char
852 *p;
853
854 ResetSplayTreeIterator(temporary_resources);
855 p=(char *) GetNextKeyInSplayTree(temporary_resources);
856 while (p != (char *) NULL)
857 {
858 if (LocaleCompare(p,path) == 0)
859 break;
860 p=(char *) GetNextKeyInSplayTree(temporary_resources);
861 }
862 if (p != (char *) NULL)
863 (void) DeleteNodeFromSplayTree(temporary_resources,p);
864 }
865 (void) CopyMagickString(cache_path,path,MaxTextExtent);
866 AppendImageFormat("cache",cache_path);
cristy18c6c272011-09-23 14:40:37 +0000867 (void) remove_utf8(cache_path);
868 return(remove_utf8(path) == 0 ? MagickTrue : MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +0000869}
870
871/*
872%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
873% %
874% %
875% %
cristyf34a1452009-10-24 22:29:27 +0000876+ R e s o u r c e C o m p o n e n t G e n e s i s %
877% %
878% %
879% %
880%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
881%
882% ResourceComponentGenesis() instantiates the resource component.
883%
884% The format of the ResourceComponentGenesis method is:
885%
886% MagickBooleanType ResourceComponentGenesis(void)
887%
888*/
889
cristy652316c2010-11-23 13:49:46 +0000890static inline size_t MagickMax(const size_t x,const size_t y)
cristyf34a1452009-10-24 22:29:27 +0000891{
892 if (x > y)
893 return(x);
894 return(y);
895}
896
897static inline MagickSizeType StringToSizeType(const char *string,
898 const double interval)
899{
900 double
901 value;
902
cristy9b34e302011-11-05 02:15:45 +0000903 value=SiPrefixToDoubleInterval(string,interval);
cristyf34a1452009-10-24 22:29:27 +0000904 if (value >= (double) MagickULLConstant(~0))
905 return(MagickULLConstant(~0));
906 return((MagickSizeType) value);
907}
908
cristy5ff4eaf2011-09-03 01:38:02 +0000909MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
cristyf34a1452009-10-24 22:29:27 +0000910{
911 char
912 *limit;
913
cristy9d314ff2011-03-09 01:30:28 +0000914 MagickSizeType
915 memory;
916
cristybb503372010-05-27 20:51:26 +0000917 ssize_t
cristyf34a1452009-10-24 22:29:27 +0000918 files,
919 pages,
920 pagesize;
921
cristyf34a1452009-10-24 22:29:27 +0000922 /*
923 Set Magick resource limits.
924 */
cristy165b6092009-10-26 13:52:10 +0000925 AcquireSemaphoreInfo(&resource_semaphore);
cristyf34a1452009-10-24 22:29:27 +0000926 pagesize=GetMagickPageSize();
927 pages=(-1);
928#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
cristycee97112010-05-28 00:44:52 +0000929 pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
cristyf34a1452009-10-24 22:29:27 +0000930#endif
931 memory=(MagickSizeType) pages*pagesize;
932 if ((pagesize <= 0) || (pages <= 0))
933 memory=2048UL*1024UL*1024UL;
934#if defined(PixelCacheThreshold)
935 memory=PixelCacheThreshold;
936#endif
cristy2b97bd22011-10-04 18:12:42 +0000937 (void) SetMagickResourceLimit(AreaResource,2*memory);
cristyb0a27eb2010-10-23 23:34:32 +0000938 (void) SetMagickResourceLimit(MemoryResource,memory);
939 (void) SetMagickResourceLimit(MapResource,2*memory);
cristyf34a1452009-10-24 22:29:27 +0000940 limit=GetEnvironmentValue("MAGICK_AREA_LIMIT");
941 if (limit == (char *) NULL)
942 limit=GetPolicyValue("area");
943 if (limit != (char *) NULL)
944 {
945 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
946 limit=DestroyString(limit);
947 }
948 limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT");
949 if (limit == (char *) NULL)
950 limit=GetPolicyValue("memory");
951 if (limit != (char *) NULL)
952 {
953 (void) SetMagickResourceLimit(MemoryResource,
954 StringToSizeType(limit,100.0));
955 limit=DestroyString(limit);
956 }
957 limit=GetEnvironmentValue("MAGICK_MAP_LIMIT");
958 if (limit == (char *) NULL)
959 limit=GetPolicyValue("map");
960 if (limit != (char *) NULL)
961 {
962 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
963 limit=DestroyString(limit);
964 }
965 limit=GetEnvironmentValue("MAGICK_DISK_LIMIT");
966 if (limit == (char *) NULL)
967 limit=GetPolicyValue("disk");
968 if (limit != (char *) NULL)
969 {
970 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
971 limit=DestroyString(limit);
972 }
973 files=(-1);
974#if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
cristycee97112010-05-28 00:44:52 +0000975 files=(ssize_t) sysconf(_SC_OPEN_MAX);
cristyf34a1452009-10-24 22:29:27 +0000976#endif
977#if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
978 if (files < 0)
979 {
980 struct rlimit
981 resources;
982
983 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
cristybb503372010-05-27 20:51:26 +0000984 files=(ssize_t) resources.rlim_cur;
cristyf34a1452009-10-24 22:29:27 +0000985 }
986#endif
987#if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
988 if (files < 0)
cristy6d0ee3e2010-09-28 18:36:50 +0000989 files=(ssize_t) getdtablesize();
cristyf34a1452009-10-24 22:29:27 +0000990#endif
991 if (files < 0)
992 files=64;
cristybb503372010-05-27 20:51:26 +0000993 (void) SetMagickResourceLimit(FileResource,MagickMax((size_t)
cristyddacdd12012-05-07 23:08:14 +0000994 (3*files/4),64));
cristyf34a1452009-10-24 22:29:27 +0000995 limit=GetEnvironmentValue("MAGICK_FILE_LIMIT");
996 if (limit == (char *) NULL)
997 limit=GetPolicyValue("file");
998 if (limit != (char *) NULL)
999 {
cristycfce4c92011-12-11 17:28:48 +00001000 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,
1001 100.0));
cristyf34a1452009-10-24 22:29:27 +00001002 limit=DestroyString(limit);
1003 }
1004 (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads());
1005 limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT");
1006 if (limit == (char *) NULL)
1007 limit=GetPolicyValue("thread");
1008 if (limit != (char *) NULL)
1009 {
cristyf34a1452009-10-24 22:29:27 +00001010 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
1011 100.0));
1012 limit=DestroyString(limit);
1013 }
1014 limit=GetEnvironmentValue("MAGICK_TIME_LIMIT");
1015 if (limit == (char *) NULL)
1016 limit=GetPolicyValue("time");
1017 if (limit != (char *) NULL)
1018 {
1019 (void) SetMagickResourceLimit(TimeResource,StringToSizeType(limit,100.0));
1020 limit=DestroyString(limit);
1021 }
1022 return(MagickTrue);
1023}
1024
1025/*
1026%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1027% %
1028% %
1029% %
1030+ 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 %
1031% %
1032% %
1033% %
1034%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035%
1036% ResourceComponentTerminus() destroys the resource component.
1037%
1038% The format of the ResourceComponentTerminus() method is:
1039%
1040% ResourceComponentTerminus(void)
1041%
1042*/
cristy5ff4eaf2011-09-03 01:38:02 +00001043MagickPrivate void ResourceComponentTerminus(void)
cristyf34a1452009-10-24 22:29:27 +00001044{
cristy18b17442009-10-25 18:36:48 +00001045 if (resource_semaphore == (SemaphoreInfo *) NULL)
1046 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001047 LockSemaphoreInfo(resource_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001048 if (temporary_resources != (SplayTreeInfo *) NULL)
1049 temporary_resources=DestroySplayTree(temporary_resources);
1050 if (random_info != (RandomInfo *) NULL)
1051 random_info=DestroyRandomInfo(random_info);
cristyf84a1932010-01-03 18:00:18 +00001052 UnlockSemaphoreInfo(resource_semaphore);
cristyf34a1452009-10-24 22:29:27 +00001053 DestroySemaphoreInfo(&resource_semaphore);
1054}
1055
1056/*
1057%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1058% %
1059% %
1060% %
cristy3ed852e2009-09-05 21:47:34 +00001061% S e t M a g i c k R e s o u r c e L i m i t %
1062% %
1063% %
1064% %
1065%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1066%
1067% SetMagickResourceLimit() sets the limit for a particular resource.
1068%
1069% The format of the SetMagickResourceLimit() method is:
1070%
1071% MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1072% const MagickSizeType limit)
1073%
1074% A description of each parameter follows:
1075%
1076% o type: the type of resource.
1077%
1078% o limit: the maximum limit for the resource.
1079%
1080*/
cristy652316c2010-11-23 13:49:46 +00001081
cristy55a91cd2010-12-01 00:57:40 +00001082static inline MagickSizeType MagickMin(const MagickSizeType x,
1083 const MagickSizeType y)
cristy652316c2010-11-23 13:49:46 +00001084{
1085 if (x < y)
1086 return(x);
1087 return(y);
1088}
1089
cristy3ed852e2009-09-05 21:47:34 +00001090MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1091 const MagickSizeType limit)
1092{
cristy652316c2010-11-23 13:49:46 +00001093 char
1094 *value;
1095
cristy18b17442009-10-25 18:36:48 +00001096 if (resource_semaphore == (SemaphoreInfo *) NULL)
1097 AcquireSemaphoreInfo(&resource_semaphore);
cristyf84a1932010-01-03 18:00:18 +00001098 LockSemaphoreInfo(resource_semaphore);
cristye2837ed2011-09-06 01:49:42 +00001099 value=(char *) NULL;
cristy3ed852e2009-09-05 21:47:34 +00001100 switch (type)
1101 {
1102 case AreaResource:
1103 {
1104 resource_info.area_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001105 value=GetPolicyValue("area");
1106 if (value != (char *) NULL)
1107 resource_info.area_limit=MagickMin(limit,StringToSizeType(value,100.0));
cristy3ed852e2009-09-05 21:47:34 +00001108 break;
1109 }
1110 case MemoryResource:
1111 {
1112 resource_info.memory_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001113 value=GetPolicyValue("memory");
1114 if (value != (char *) NULL)
1115 resource_info.memory_limit=MagickMin(limit,StringToSizeType(value,
1116 100.0));
cristy3ed852e2009-09-05 21:47:34 +00001117 break;
1118 }
1119 case MapResource:
1120 {
1121 resource_info.map_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001122 value=GetPolicyValue("map");
1123 if (value != (char *) NULL)
1124 resource_info.map_limit=MagickMin(limit,StringToSizeType(value,100.0));
cristy3ed852e2009-09-05 21:47:34 +00001125 break;
1126 }
1127 case DiskResource:
1128 {
1129 resource_info.disk_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001130 value=GetPolicyValue("disk");
1131 if (value != (char *) NULL)
1132 resource_info.disk_limit=MagickMin(limit,StringToSizeType(value,100.0));
cristy3ed852e2009-09-05 21:47:34 +00001133 break;
1134 }
1135 case FileResource:
1136 {
1137 resource_info.file_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001138 value=GetPolicyValue("file");
1139 if (value != (char *) NULL)
1140 resource_info.file_limit=MagickMin(limit,StringToSizeType(value,100.0));
cristy3ed852e2009-09-05 21:47:34 +00001141 break;
1142 }
1143 case ThreadResource:
1144 {
cristy01e36dc2010-10-21 17:26:42 +00001145 resource_info.thread_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001146 value=GetPolicyValue("thread");
1147 if (value != (char *) NULL)
1148 resource_info.thread_limit=MagickMin(limit,StringToSizeType(value,
1149 100.0));
cristyfeeb98d2012-05-09 16:32:12 +00001150 if (resource_info.thread_limit > GetOpenMPMaximumThreads())
1151 resource_info.thread_limit=GetOpenMPMaximumThreads();
cristy3ed852e2009-09-05 21:47:34 +00001152 break;
1153 }
1154 case TimeResource:
1155 {
1156 resource_info.time_limit=limit;
cristy652316c2010-11-23 13:49:46 +00001157 value=GetPolicyValue("time");
1158 if (value != (char *) NULL)
1159 resource_info.time_limit=MagickMin(limit,StringToSizeType(value,100.0));
cristy3ed852e2009-09-05 21:47:34 +00001160 break;
1161 }
1162 default:
1163 break;
1164 }
cristye2837ed2011-09-06 01:49:42 +00001165 if (value != (char *) NULL)
1166 value=DestroyString(value);
cristyf84a1932010-01-03 18:00:18 +00001167 UnlockSemaphoreInfo(resource_semaphore);
cristy3ed852e2009-09-05 21:47:34 +00001168 return(MagickTrue);
1169}