MagickCore  7.0.3
resource.c
Go to the documentation of this file.
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-2019 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"
45 #include "MagickCore/configure.h"
46 #include "MagickCore/exception.h"
48 #include "MagickCore/linked-list.h"
49 #include "MagickCore/log.h"
50 #include "MagickCore/image.h"
52 #include "MagickCore/memory_.h"
54 #include "MagickCore/option.h"
55 #include "MagickCore/policy.h"
56 #include "MagickCore/random_.h"
57 #include "MagickCore/registry.h"
58 #include "MagickCore/resource_.h"
60 #include "MagickCore/semaphore.h"
62 #include "MagickCore/string_.h"
64 #include "MagickCore/splay-tree.h"
66 #include "MagickCore/token.h"
67 #include "MagickCore/utility.h"
69 
70 /*
71  Define declarations.
72 */
73 #define MagickPathTemplate "XXXXXXXXXXXX"
74 #define NumberOfResourceTypes \
75  (sizeof(resource_semaphore)/sizeof(*resource_semaphore))
76 
77 /*
78  Typedef declarations.
79 */
80 typedef struct _ResourceInfo
81 {
84  height,
86  area,
87  memory,
88  map,
89  disk,
90  file,
91  thread,
92  throttle,
93  time;
94 
99  area_limit,
100  memory_limit,
101  map_limit,
102  disk_limit,
103  file_limit,
104  thread_limit,
106  time_limit;
107 } ResourceInfo;
108 
109 /*
110  Global declarations.
111 */
112 static RandomInfo
113  *random_info = (RandomInfo *) NULL;
114 
115 static ResourceInfo
117  {
118  MagickULLConstant(0), /* initial width */
119  MagickULLConstant(0), /* initial height */
120  MagickULLConstant(0), /* initial list length */
121  MagickULLConstant(0), /* initial area */
122  MagickULLConstant(0), /* initial memory */
123  MagickULLConstant(0), /* initial map */
124  MagickULLConstant(0), /* initial disk */
125  MagickULLConstant(0), /* initial file */
126  MagickULLConstant(0), /* initial thread */
127  MagickULLConstant(0), /* initial throttle */
128  MagickULLConstant(0), /* initial time */
129  (INT_MAX/(5*sizeof(Quantum))), /* width limit */
130  (INT_MAX/(5*sizeof(Quantum))), /* height limit */
131  MagickResourceInfinity, /* list length limit */
132  MagickULLConstant(3072)*1024*1024, /* area limit */
133  MagickULLConstant(1536)*1024*1024, /* memory limit */
134  MagickULLConstant(3072)*1024*1024, /* map limit */
135  MagickResourceInfinity, /* disk limit */
136  MagickULLConstant(768), /* file limit */
137  MagickULLConstant(1), /* thread limit */
138  MagickULLConstant(0), /* throttle limit */
139  MagickResourceInfinity /* time limit */
140  };
141 
142 static SemaphoreInfo
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  (SemaphoreInfo *) NULL
156  };
157 
158 static SplayTreeInfo
160 
161 /*
162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163 % %
164 % %
165 % %
166 % A c q u i r e M a g i c k R e s o u r c e %
167 % %
168 % %
169 % %
170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171 %
172 % AcquireMagickResource() acquires resources of the specified type.
173 % MagickFalse is returned if the specified resource is exhausted otherwise
174 % MagickTrue.
175 %
176 % The format of the AcquireMagickResource() method is:
177 %
178 % MagickBooleanType AcquireMagickResource(const ResourceType type,
179 % const MagickSizeType size)
180 %
181 % A description of each parameter follows:
182 %
183 % o type: the type of resource.
184 %
185 % o size: the number of bytes needed from for this resource.
186 %
187 */
189  const MagickSizeType size)
190 {
192  bi,
193  status;
194 
196  current,
197  request;
198 
200  limit;
201 
202  request=(MagickOffsetType) size;
203  if (request < 0)
204  return(MagickFalse);
205  limit=0;
206  current=0;
207  bi=MagickFalse;
208  status=MagickFalse;
209  switch (type)
210  {
211  case DiskResource:
212  case FileResource:
213  case MapResource:
214  case MemoryResource:
215  case TimeResource:
216  {
217  if (resource_semaphore[type] == (SemaphoreInfo *) NULL)
220  break;
221  }
222  default: ;
223  }
224  switch (type)
225  {
226  case AreaResource:
227  {
228  bi=MagickTrue;
229  resource_info.area=request;
231  break;
232  }
233  case DiskResource:
234  {
235  bi=MagickTrue;
237  if ((resource_info.disk+request) > resource_info.disk)
238  {
239  resource_info.disk+=request;
240  if ((limit == MagickResourceInfinity) ||
241  (resource_info.disk < (MagickOffsetType) limit))
242  status=MagickTrue;
243  else
244  resource_info.disk-=request;
245  }
246  current=resource_info.disk;
247  break;
248  }
249  case FileResource:
250  {
252  if ((resource_info.file+request) > resource_info.file)
253  {
254  resource_info.file+=request;
255  if ((limit == MagickResourceInfinity) ||
256  (resource_info.file < (MagickOffsetType) limit))
257  status=MagickTrue;
258  }
259  current=resource_info.file;
260  break;
261  }
262  case HeightResource:
263  {
264  bi=MagickTrue;
265  resource_info.height=request;
267  break;
268  }
269  case ListLengthResource:
270  {
271  resource_info.list_length=request;
273  break;
274  }
275  case ThreadResource:
276  {
278  break;
279  }
280  case MapResource:
281  {
282  bi=MagickTrue;
283  limit=resource_info.map_limit;
284  if ((resource_info.map+request) > 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;
300  if ((resource_info.memory+request) > resource_info.memory)
301  {
302  resource_info.memory+=request;
303  if ((limit == MagickResourceInfinity) ||
305  status=MagickTrue;
306  else
307  resource_info.memory-=request;
308  }
309  current=resource_info.memory;
310  break;
311  }
312  case ThrottleResource:
313  {
315  break;
316  }
317  case TimeResource:
318  {
320  if ((resource_info.time+request) > resource_info.time)
321  {
322  resource_info.time+=request;
323  if ((limit == MagickResourceInfinity) ||
324  (resource_info.time < (MagickOffsetType) limit))
325  status=MagickTrue;
326  else
327  resource_info.time-=request;
328  }
329  current=resource_info.time;
330  break;
331  }
332  case WidthResource:
333  {
334  bi=MagickTrue;
335  resource_info.width=request;
337  break;
338  }
339  default:
340  {
341  current=0;
342  break;
343  }
344  }
345  switch (type)
346  {
347  case DiskResource:
348  case FileResource:
349  case MapResource:
350  case MemoryResource:
351  case TimeResource:
352  {
354  break;
355  }
356  default: ;
357  }
358  if ((limit == MagickResourceInfinity) || (size < limit))
359  status=MagickTrue;
360  if (IsEventLogging() != MagickFalse)
361  {
362  char
363  resource_current[MagickFormatExtent],
364  resource_limit[MagickFormatExtent],
365  resource_request[MagickFormatExtent];
366 
367  (void) FormatMagickSize(size,bi,(bi != MagickFalse) ? "B" :
368  (const char *) NULL,MagickFormatExtent,resource_request);
369  (void) FormatMagickSize((MagickSizeType) current,bi,(bi != MagickFalse) ?
370  "B" : (const char *) NULL,MagickFormatExtent,resource_current);
371  (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ? "B" :
372  (const char *) NULL,MagickFormatExtent,resource_limit);
373  (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
375  resource_request,resource_current,resource_limit);
376  }
377  return(status);
378 }
379 
380 /*
381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382 % %
383 % %
384 % %
385 + 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 %
386 % %
387 % %
388 % %
389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
390 %
391 % AsynchronousResourceComponentTerminus() destroys the resource environment.
392 % It differs from ResourceComponentTerminus() in that it can be called from a
393 % asynchronous signal handler.
394 %
395 % The format of the ResourceComponentTerminus() method is:
396 %
397 % ResourceComponentTerminus(void)
398 %
399 */
401 {
402  const char
403  *path;
404 
405  if (temporary_resources == (SplayTreeInfo *) NULL)
406  return;
407  /*
408  Remove any lingering temporary files.
409  */
411  path=(const char *) GetNextKeyInSplayTree(temporary_resources);
412  while (path != (const char *) NULL)
413  {
414  (void) ShredFile(path);
415  path=(const char *) GetNextKeyInSplayTree(temporary_resources);
416  }
417 }
418 
419 /*
420 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
421 % %
422 % %
423 % %
424 % 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 %
425 % %
426 % %
427 % %
428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
429 %
430 % AcquireUniqueFileResource() returns a unique file name, and returns a file
431 % descriptor for the file open for reading and writing.
432 %
433 % The format of the AcquireUniqueFileResource() method is:
434 %
435 % int AcquireUniqueFileResource(char *path)
436 %
437 % A description of each parameter follows:
438 %
439 % o path: Specifies a pointer to an array of characters. The unique path
440 % name is returned in this array.
441 %
442 */
443 
444 static void *DestroyTemporaryResources(void *temporary_resource)
445 {
446  (void) ShredFile((char *) temporary_resource);
447  temporary_resource=DestroyString((char *) temporary_resource);
448  return((void *) NULL);
449 }
450 
452 {
453  char
454  *directory,
455  *value;
456 
458  *exception;
459 
461  status;
462 
463  struct stat
464  attributes;
465 
466  (void) FormatLocaleString(path,MagickPathExtent,"magick-%.20g"
467  MagickPathTemplate,(double) getpid());
468  exception=AcquireExceptionInfo();
469  directory=(char *) GetImageRegistry(StringRegistryType,"temporary-path",
470  exception);
471  exception=DestroyExceptionInfo(exception);
472  if (directory == (char *) NULL)
473  directory=GetEnvironmentValue("MAGICK_TEMPORARY_PATH");
474  if (directory == (char *) NULL)
475  directory=GetEnvironmentValue("MAGICK_TMPDIR");
476  if (directory == (char *) NULL)
477  directory=GetEnvironmentValue("TMPDIR");
478 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) || defined(__CYGWIN__)
479  if (directory == (char *) NULL)
480  directory=GetEnvironmentValue("TMP");
481  if (directory == (char *) NULL)
482  directory=GetEnvironmentValue("TEMP");
483 #endif
484 #if defined(__VMS)
485  if (directory == (char *) NULL)
486  directory=GetEnvironmentValue("MTMPDIR");
487 #endif
488 #if defined(P_tmpdir)
489  if (directory == (char *) NULL)
490  directory=ConstantString(P_tmpdir);
491 #endif
492  if (directory == (char *) NULL)
493  return(MagickTrue);
494  value=GetPolicyValue("resource:temporary-path");
495  if (value != (char *) NULL)
496  {
497  (void) CloneString(&directory,value);
498  value=DestroyString(value);
499  }
500  if (strlen(directory) > (MagickPathExtent-25))
501  {
502  directory=DestroyString(directory);
503  return(MagickFalse);
504  }
505  status=GetPathAttributes(directory,&attributes);
506  if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
507  {
508  directory=DestroyString(directory);
509  return(MagickFalse);
510  }
511  if (directory[strlen(directory)-1] == *DirectorySeparator)
513  "%smagick-%.20g" MagickPathTemplate,directory,(double) getpid());
514  else
516  "%s%smagick-%.20g" MagickPathTemplate,directory,DirectorySeparator,
517  (double) getpid());
518  directory=DestroyString(directory);
519 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
520  {
521  register char
522  *p;
523 
524  /*
525  Ghostscript does not like backslashes so we need to replace them. The
526  forward slash also works under Windows.
527  */
528  for (p=(path[1] == *DirectorySeparator ? path+2 : path); *p != '\0'; p++)
529  if (*p == *DirectorySeparator)
530  *p='/';
531  }
532 #endif
533  return(MagickTrue);
534 }
535 
537 {
538 #if !defined(O_NOFOLLOW)
539 #define O_NOFOLLOW 0
540 #endif
541 #if !defined(TMP_MAX)
542 # define TMP_MAX 238328
543 #endif
544 
545  int
546  c,
547  file;
548 
549  register char
550  *p;
551 
552  register ssize_t
553  i;
554 
555  static const char
556  portable_filename[65] =
557  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
558 
559  StringInfo
560  *key;
561 
562  unsigned char
563  *datum;
564 
565  assert(path != (char *) NULL);
567  if (random_info == (RandomInfo *) NULL)
568  {
571  LockSemaphoreInfo(resource_semaphore[FileResource]);
572  if (random_info == (RandomInfo *) NULL)
575  }
576  file=(-1);
577  for (i=0; i < (ssize_t) TMP_MAX; i++)
578  {
579  register ssize_t
580  j;
581 
582  /*
583  Get temporary pathname.
584  */
585  (void) GetPathTemplate(path);
586  key=GetRandomKey(random_info,6);
587  p=path+strlen(path)-strlen(MagickPathTemplate);
588  datum=GetStringInfoDatum(key);
589  for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
590  {
591  c=(int) (datum[j] & 0x3f);
592  *p++=portable_filename[c];
593  }
594  key=DestroyStringInfo(key);
595 #if defined(MAGICKCORE_HAVE_MKSTEMP)
596  file=mkstemp(path);
597  if (file != -1)
598  {
599 #if defined(MAGICKCORE_HAVE_FCHMOD)
600  (void) fchmod(file,0600);
601 #endif
602 #if defined(__OS2__)
603  setmode(file,O_BINARY);
604 #endif
605  break;
606  }
607 #endif
609  p=path+strlen(path)-strlen(MagickPathTemplate);
610  datum=GetStringInfoDatum(key);
611  for (j=0; j < (ssize_t) GetStringInfoLength(key); j++)
612  {
613  c=(int) (datum[j] & 0x3f);
614  *p++=portable_filename[c];
615  }
616  key=DestroyStringInfo(key);
617  file=open_utf8(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
618  S_MODE);
619  if ((file >= 0) || (errno != EEXIST))
620  break;
621  }
622  (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
623  if (file == -1)
624  return(file);
627  LockSemaphoreInfo(resource_semaphore[FileResource]);
628  if (temporary_resources == (SplayTreeInfo *) NULL)
630  DestroyTemporaryResources,(void *(*)(void *)) NULL);
633  (const void *) NULL);
634  return(file);
635 }
636 
637 /*
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639 % %
640 % %
641 % %
642 % G e t M a g i c k R e s o u r c e %
643 % %
644 % %
645 % %
646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
647 %
648 % GetMagickResource() returns the specified resource.
649 %
650 % The format of the GetMagickResource() method is:
651 %
652 % MagickSizeType GetMagickResource(const ResourceType type)
653 %
654 % A description of each parameter follows:
655 %
656 % o type: the type of resource.
657 %
658 */
660 {
662  resource;
663 
664  resource=0;
665  switch (type)
666  {
667  case DiskResource:
668  case FileResource:
669  case MapResource:
670  case MemoryResource:
671  case TimeResource:
672  {
673  if (resource_semaphore[type] == (SemaphoreInfo *) NULL)
676  break;
677  }
678  default: ;
679  }
680  switch (type)
681  {
682  case AreaResource:
683  {
684  resource=(MagickSizeType) resource_info.area;
685  break;
686  }
687  case DiskResource:
688  {
689  resource=(MagickSizeType) resource_info.disk;
690  break;
691  }
692  case FileResource:
693  {
694  resource=(MagickSizeType) resource_info.file;
695  break;
696  }
697  case HeightResource:
698  {
700  break;
701  }
702  case ListLengthResource:
703  {
705  break;
706  }
707  case MapResource:
708  {
709  resource=(MagickSizeType) resource_info.map;
710  break;
711  }
712  case MemoryResource:
713  {
715  break;
716  }
717  case TimeResource:
718  {
719  resource=(MagickSizeType) resource_info.time;
720  break;
721  }
722  case ThreadResource:
723  {
725  break;
726  }
727  case ThrottleResource:
728  {
730  break;
731  }
732  case WidthResource:
733  {
735  break;
736  }
737  default:
738  break;
739  }
740  switch (type)
741  {
742  case DiskResource:
743  case FileResource:
744  case MapResource:
745  case MemoryResource:
746  case TimeResource:
747  {
749  break;
750  }
751  default: ;
752  }
753  return(resource);
754 }
755 
756 /*
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
758 % %
759 % %
760 % %
761 % G e t M a g i c k R e s o u r c e L i m i t %
762 % %
763 % %
764 % %
765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
766 %
767 % GetMagickResourceLimit() returns the specified resource limit.
768 %
769 % The format of the GetMagickResourceLimit() method is:
770 %
771 % MagickSizeType GetMagickResourceLimit(const ResourceType type)
772 %
773 % A description of each parameter follows:
774 %
775 % o type: the type of resource.
776 %
777 */
779 {
781  resource;
782 
783  resource=0;
784  if (resource_semaphore[type] == (SemaphoreInfo *) NULL)
787  switch (type)
788  {
789  case AreaResource:
790  {
791  resource=resource_info.area_limit;
792  break;
793  }
794  case DiskResource:
795  {
796  resource=resource_info.disk_limit;
797  break;
798  }
799  case FileResource:
800  {
801  resource=resource_info.file_limit;
802  break;
803  }
804  case HeightResource:
805  {
806  resource=resource_info.height_limit;
807  break;
808  }
809  case ListLengthResource:
810  {
812  break;
813  }
814  case MemoryResource:
815  {
816  resource=resource_info.memory_limit;
817  break;
818  }
819  case MapResource:
820  {
821  resource=resource_info.map_limit;
822  break;
823  }
824  case ThreadResource:
825  {
826  resource=resource_info.thread_limit;
827  break;
828  }
829  case ThrottleResource:
830  {
831  resource=resource_info.throttle_limit;
832  break;
833  }
834  case TimeResource:
835  {
836  resource=resource_info.time_limit;
837  break;
838  }
839  case WidthResource:
840  {
841  resource=resource_info.width_limit;
842  break;
843  }
844  default:
845  break;
846  }
848  return(resource);
849 }
850 
851 /*
852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
853 % %
854 % %
855 % %
856 % L i s t M a g i c k R e s o u r c e I n f o %
857 % %
858 % %
859 % %
860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
861 %
862 % ListMagickResourceInfo() lists the resource info to a file.
863 %
864 % The format of the ListMagickResourceInfo method is:
865 %
866 % MagickBooleanType ListMagickResourceInfo(FILE *file,
867 % ExceptionInfo *exception)
868 %
869 % A description of each parameter follows.
870 %
871 % o file: An pointer to a FILE.
872 %
873 % o exception: return any errors or warnings in this structure.
874 %
875 */
877  ExceptionInfo *magick_unused(exception))
878 {
879  char
880  area_limit[MagickFormatExtent],
881  disk_limit[MagickFormatExtent],
882  height_limit[MagickFormatExtent],
883  list_length_limit[MagickFormatExtent],
884  map_limit[MagickFormatExtent],
885  memory_limit[MagickFormatExtent],
886  time_limit[MagickFormatExtent],
887  width_limit[MagickFormatExtent];
888 
889  magick_unreferenced(exception);
890 
891  if (file == (const FILE *) NULL)
892  file=stdout;
895  LockSemaphoreInfo(resource_semaphore[FileResource]);
897  MagickFormatExtent,width_limit);
899  MagickFormatExtent,height_limit);
901  MagickFormatExtent,area_limit);
902  (void) CopyMagickString(list_length_limit,"unlimited",MagickFormatExtent);
905  MagickFormatExtent,list_length_limit);
907  MagickFormatExtent,memory_limit);
909  MagickFormatExtent,map_limit);
910  (void) CopyMagickString(disk_limit,"unlimited",MagickFormatExtent);
913  MagickFormatExtent,disk_limit);
914  (void) CopyMagickString(time_limit,"unlimited",MagickFormatExtent);
916  (void) FormatLocaleString(time_limit,MagickFormatExtent,"%.20g",(double)
918  (void) FormatLocaleFile(file,"Resource limits:\n");
919  (void) FormatLocaleFile(file," Width: %s\n",width_limit);
920  (void) FormatLocaleFile(file," Height: %s\n",height_limit);
921  (void) FormatLocaleFile(file," Area: %s\n",area_limit);
922  (void) FormatLocaleFile(file," List length: %s\n",list_length_limit);
923  (void) FormatLocaleFile(file," Memory: %s\n",memory_limit);
924  (void) FormatLocaleFile(file," Map: %s\n",map_limit);
925  (void) FormatLocaleFile(file," Disk: %s\n",disk_limit);
926  (void) FormatLocaleFile(file," File: %.20g\n",(double) ((MagickOffsetType)
928  (void) FormatLocaleFile(file," Thread: %.20g\n",(double) ((MagickOffsetType)
930  (void) FormatLocaleFile(file," Throttle: %.20g\n",(double)
932  (void) FormatLocaleFile(file," Time: %s\n",time_limit);
933  (void) fflush(file);
935  return(MagickTrue);
936 }
937 
938 /*
939 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
940 % %
941 % %
942 % %
943 % R e l i n q u i s h M a g i c k R e s o u r c e %
944 % %
945 % %
946 % %
947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
948 %
949 % RelinquishMagickResource() relinquishes resources of the specified type.
950 %
951 % The format of the RelinquishMagickResource() method is:
952 %
953 % void RelinquishMagickResource(const ResourceType type,
954 % const MagickSizeType size)
955 %
956 % A description of each parameter follows:
957 %
958 % o type: the type of resource.
959 %
960 % o size: the size of the resource.
961 %
962 */
964  const MagickSizeType size)
965 {
967  bi;
968 
970  current,
971  limit;
972 
973  bi=MagickFalse;
974  limit=0;
975  current=0;
976  switch (type)
977  {
978  case DiskResource:
979  case FileResource:
980  case MapResource:
981  case MemoryResource:
982  case TimeResource:
983  {
984  if (resource_semaphore[type] == (SemaphoreInfo *) NULL)
987  break;
988  }
989  default: ;
990  }
991  switch (type)
992  {
993  case DiskResource:
994  {
995  bi=MagickTrue;
996  resource_info.disk-=size;
999  assert(resource_info.disk >= 0);
1000  break;
1001  }
1002  case FileResource:
1003  {
1004  resource_info.file-=size;
1005  current=(MagickSizeType) resource_info.file;
1006  limit=resource_info.file_limit;
1007  assert(resource_info.file >= 0);
1008  break;
1009  }
1010  case MapResource:
1011  {
1012  bi=MagickTrue;
1013  resource_info.map-=size;
1014  current=(MagickSizeType) resource_info.map;
1015  limit=resource_info.map_limit;
1016  assert(resource_info.map >= 0);
1017  break;
1018  }
1019  case MemoryResource:
1020  {
1021  bi=MagickTrue;
1022  resource_info.memory-=size;
1025  assert(resource_info.memory >= 0);
1026  break;
1027  }
1028  case TimeResource:
1029  {
1030  bi=MagickTrue;
1031  resource_info.time-=size;
1032  current=(MagickSizeType) resource_info.time;
1033  limit=resource_info.time_limit;
1034  assert(resource_info.time >= 0);
1035  break;
1036  }
1037  default:
1038  {
1039  current=0;
1040  break;
1041  }
1042  }
1043  switch (type)
1044  {
1045  case DiskResource:
1046  case FileResource:
1047  case MapResource:
1048  case MemoryResource:
1049  case TimeResource:
1050  {
1052  break;
1053  }
1054  default: ;
1055  }
1056  if (IsEventLogging() != MagickFalse)
1057  {
1058  char
1059  resource_current[MagickFormatExtent],
1060  resource_limit[MagickFormatExtent],
1061  resource_request[MagickFormatExtent];
1062 
1063  (void) FormatMagickSize(size,bi,(bi != MagickFalse) ? "B" :
1064  (const char *) NULL,MagickFormatExtent,resource_request);
1065  (void) FormatMagickSize(current,bi,(bi != MagickFalse) ? "B" :
1066  (const char *) NULL,MagickFormatExtent,resource_current);
1067  (void) FormatMagickSize(limit,bi,(bi != MagickFalse) ? "B" :
1068  (const char *) NULL,MagickFormatExtent,resource_limit);
1069  (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
1071  resource_request,resource_current,resource_limit);
1072  }
1073 }
1074 
1075 /*
1076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1077 % %
1078 % %
1079 % %
1080 % 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 %
1081 % %
1082 % %
1083 % %
1084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1085 %
1086 % RelinquishUniqueFileResource() relinquishes a unique file resource.
1087 %
1088 % The format of the RelinquishUniqueFileResource() method is:
1089 %
1090 % MagickBooleanType RelinquishUniqueFileResource(const char *path)
1091 %
1092 % A description of each parameter follows:
1093 %
1094 % o name: the name of the temporary resource.
1095 %
1096 */
1098 {
1099  char
1100  cache_path[MagickPathExtent];
1101 
1103  status;
1104 
1105  assert(path != (const char *) NULL);
1106  status=MagickFalse;
1107  (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
1110  LockSemaphoreInfo(resource_semaphore[FileResource]);
1111  if (temporary_resources != (SplayTreeInfo *) NULL)
1112  status=DeleteNodeFromSplayTree(temporary_resources,(const void *) path);
1113  UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1114  (void) CopyMagickString(cache_path,path,MagickPathExtent);
1115  AppendImageFormat("cache",cache_path);
1116  if (access_utf8(cache_path,F_OK) == 0)
1117  (void) ShredFile(cache_path);
1118  if (status == MagickFalse)
1119  status=ShredFile(path);
1120  return(status);
1121 }
1122 
1123 /*
1124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1125 % %
1126 % %
1127 % %
1128 + R e s o u r c e C o m p o n e n t G e n e s i s %
1129 % %
1130 % %
1131 % %
1132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1133 %
1134 % ResourceComponentGenesis() instantiates the resource component.
1135 %
1136 % The format of the ResourceComponentGenesis method is:
1137 %
1138 % MagickBooleanType ResourceComponentGenesis(void)
1139 %
1140 */
1141 
1143 {
1144  char
1145  *limit;
1146 
1148  memory;
1149 
1150  register ssize_t
1151  i;
1152 
1153  ssize_t
1154  files,
1155  pages,
1156  pagesize;
1157 
1158  /*
1159  Set Magick resource limits.
1160  */
1161  for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1162  if (resource_semaphore[i] == (SemaphoreInfo *) NULL)
1165  limit=GetEnvironmentValue("MAGICK_WIDTH_LIMIT");
1166  if (limit != (char *) NULL)
1167  {
1169  100.0));
1170  limit=DestroyString(limit);
1171  }
1173  limit=GetEnvironmentValue("MAGICK_HEIGHT_LIMIT");
1174  if (limit != (char *) NULL)
1175  {
1177  limit,100.0));
1178  limit=DestroyString(limit);
1179  }
1180  pagesize=GetMagickPageSize();
1181  pages=(-1);
1182 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
1183  pages=(ssize_t) sysconf(_SC_PHYS_PAGES);
1184 #endif
1185  memory=(MagickSizeType) pages*pagesize;
1186  if ((pagesize <= 0) || (pages <= 0))
1187  memory=2048UL*1024UL*1024UL;
1188 #if defined(PixelCacheThreshold)
1189  memory=PixelCacheThreshold;
1190 #endif
1191  (void) SetMagickResourceLimit(AreaResource,2*memory);
1192  limit=GetEnvironmentValue("MAGICK_AREA_LIMIT");
1193  if (limit != (char *) NULL)
1194  {
1196  100.0));
1197  limit=DestroyString(limit);
1198  }
1199  (void) SetMagickResourceLimit(MemoryResource,memory);
1200  limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT");
1201  if (limit != (char *) NULL)
1202  {
1204  limit,100.0));
1205  limit=DestroyString(limit);
1206  }
1207  (void) SetMagickResourceLimit(MapResource,2*memory);
1208  limit=GetEnvironmentValue("MAGICK_MAP_LIMIT");
1209  if (limit != (char *) NULL)
1210  {
1212  100.0));
1213  limit=DestroyString(limit);
1214  }
1216  limit=GetEnvironmentValue("MAGICK_DISK_LIMIT");
1217  if (limit != (char *) NULL)
1218  {
1220  100.0));
1221  limit=DestroyString(limit);
1222  }
1223  files=(-1);
1224 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
1225  files=(ssize_t) sysconf(_SC_OPEN_MAX);
1226 #endif
1227 #if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
1228  if (files < 0)
1229  {
1230  struct rlimit
1231  resources;
1232 
1233  if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
1234  files=(ssize_t) resources.rlim_cur;
1235  }
1236 #endif
1237 #if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
1238  if (files < 0)
1239  files=(ssize_t) getdtablesize();
1240 #endif
1241  if (files < 0)
1242  files=64;
1244  (3*files/4),64));
1245  limit=GetEnvironmentValue("MAGICK_FILE_LIMIT");
1246  if (limit != (char *) NULL)
1247  {
1249  100.0));
1250  limit=DestroyString(limit);
1251  }
1253  limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT");
1254  if (limit != (char *) NULL)
1255  {
1257  limit,100.0));
1258  limit=DestroyString(limit);
1259  }
1261  limit=GetEnvironmentValue("MAGICK_THROTTLE_LIMIT");
1262  if (limit != (char *) NULL)
1263  {
1265  limit,100.0));
1266  limit=DestroyString(limit);
1267  }
1269  limit=GetEnvironmentValue("MAGICK_TIME_LIMIT");
1270  if (limit != (char *) NULL)
1271  {
1273  100.0));
1274  limit=DestroyString(limit);
1275  }
1277  limit=GetEnvironmentValue("MAGICK_LIST_LENGTH_LIMIT");
1278  if (limit != (char *) NULL)
1279  {
1281  StringToMagickSizeType(limit,100.0));
1282  limit=DestroyString(limit);
1283  }
1284  return(MagickTrue);
1285 }
1286 
1287 /*
1288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1289 % %
1290 % %
1291 % %
1292 + 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 %
1293 % %
1294 % %
1295 % %
1296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1297 %
1298 % ResourceComponentTerminus() destroys the resource component.
1299 %
1300 % The format of the ResourceComponentTerminus() method is:
1301 %
1302 % ResourceComponentTerminus(void)
1303 %
1304 */
1306 {
1307  register ssize_t
1308  i;
1309 
1310  for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1311  if (resource_semaphore[i] == (SemaphoreInfo *) NULL)
1314  if (temporary_resources != (SplayTreeInfo *) NULL)
1316  if (random_info != (RandomInfo *) NULL)
1318  UnlockSemaphoreInfo(resource_semaphore[FileResource]);
1319  for (i=0; i < (ssize_t) NumberOfResourceTypes; i++)
1321 }
1322 
1323 /*
1324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1325 % %
1326 % %
1327 % %
1328 % S e t M a g i c k R e s o u r c e L i m i t %
1329 % %
1330 % %
1331 % %
1332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1333 %
1334 % SetMagickResourceLimit() sets the limit for a particular resource.
1335 %
1336 % The format of the SetMagickResourceLimit() method is:
1337 %
1338 % MagickBooleanType SetMagickResourceLimit(const ResourceType type,
1339 % const MagickSizeType limit)
1340 %
1341 % A description of each parameter follows:
1342 %
1343 % o type: the type of resource.
1344 %
1345 % o limit: the maximum limit for the resource.
1346 %
1347 */
1349  const MagickSizeType limit)
1350 {
1351  char
1352  *value;
1353 
1355  status;
1356 
1357  status=MagickTrue;
1358  value=(char *) NULL;
1359  if (resource_semaphore[type] == (SemaphoreInfo *) NULL)
1362  switch (type)
1363  {
1364  case AreaResource:
1365  {
1366  value=GetPolicyValue("resource:area");
1367  if (value == (char *) NULL)
1368  resource_info.area_limit=limit;
1369  else
1371  100.0));
1372  break;
1373  }
1374  case DiskResource:
1375  {
1376  value=GetPolicyValue("resource:disk");
1377  if (value == (char *) NULL)
1378  resource_info.disk_limit=limit;
1379  else
1381  100.0));
1382  break;
1383  }
1384  case FileResource:
1385  {
1386  value=GetPolicyValue("resource:file");
1387  if (value == (char *) NULL)
1388  resource_info.file_limit=limit;
1389  else
1391  100.0));
1392  break;
1393  }
1394  case HeightResource:
1395  {
1396  value=GetPolicyValue("resource:height");
1397  if (value == (char *) NULL)
1399  else
1401  value,100.0));
1402  break;
1403  }
1404  case ListLengthResource:
1405  {
1406  value=GetPolicyValue("resource:list-length");
1407  if (value == (char *) NULL)
1409  else
1411  StringToMagickSizeType(value,100.0));
1412  break;
1413  }
1414  case MapResource:
1415  {
1416  value=GetPolicyValue("resource:map");
1417  if (value == (char *) NULL)
1418  resource_info.map_limit=limit;
1419  else
1421  value,100.0));
1422  break;
1423  }
1424  case MemoryResource:
1425  {
1426  value=GetPolicyValue("resource:memory");
1427  if (value == (char *) NULL)
1429  else
1431  value,100.0));
1432  break;
1433  }
1434  case ThreadResource:
1435  {
1436  value=GetPolicyValue("resource:thread");
1437  if (value == (char *) NULL)
1439  else
1441  value,100.0));
1444  else
1445  if (resource_info.thread_limit == 0)
1447  break;
1448  }
1449  case ThrottleResource:
1450  {
1451  value=GetPolicyValue("resource:throttle");
1452  if (value == (char *) NULL)
1454  else
1456  value,100.0));
1457  break;
1458  }
1459  case TimeResource:
1460  {
1461  value=GetPolicyValue("resource:time");
1462  if (value == (char *) NULL)
1463  resource_info.time_limit=limit;
1464  else
1466  100.0));
1468  break;
1469  }
1470  case WidthResource:
1471  {
1472  value=GetPolicyValue("resource:width");
1473  if (value == (char *) NULL)
1474  resource_info.width_limit=limit;
1475  else
1477  100.0));
1478  break;
1479  }
1480  default:
1481  {
1482  status=MagickFalse;
1483  break;
1484  }
1485  }
1487  if (value != (char *) NULL)
1488  value=DestroyString(value);
1489  return(status);
1490 }
MagickExport ssize_t FormatMagickSize(const MagickSizeType size, const MagickBooleanType bi, const char *suffix, const size_t length, char *format)
Definition: string.c:1093
MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
Definition: resource.c:1142
MagickOffsetType map
Definition: resource.c:83
MagickExport MagickBooleanType GetPathAttributes(const char *path, void *attributes)
Definition: utility.c:1165
MagickExport MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree, const void *key, const void *value)
Definition: splay-tree.c:154
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:450
MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file, ExceptionInfo *magick_unused(exception))
Definition: resource.c:876
static void * DestroyTemporaryResources(void *temporary_resource)
Definition: resource.c:444
#define MagickULLConstant(c)
Definition: magick-type.h:36
struct _ResourceInfo ResourceInfo
MagickOffsetType file
Definition: resource.c:83
static size_t GetOpenMPMaximumThreads(void)
MagickOffsetType thread
Definition: resource.c:83
MagickSizeType height_limit
Definition: resource.c:96
static SemaphoreInfo * resource_semaphore[]
Definition: resource.c:143
MagickExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition: semaphore.c:192
static ResourceInfo resource_info
Definition: resource.c:116
MagickSizeType map_limit
Definition: resource.c:96
MagickOffsetType memory
Definition: resource.c:83
MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type, const MagickSizeType limit)
Definition: resource.c:1348
MagickOffsetType area
Definition: resource.c:83
#define S_ISDIR(mode)
Definition: studio.h:200
MagickSizeType area_limit
Definition: resource.c:96
MagickExport ExceptionInfo * AcquireExceptionInfo(void)
Definition: exception.c:115
MagickOffsetType time
Definition: resource.c:83
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
Definition: locale.c:499
MagickExport void RelinquishMagickResource(const ResourceType type, const MagickSizeType size)
Definition: resource.c:963
#define O_BINARY
Definition: studio.h:325
MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type, const MagickSizeType size)
Definition: resource.c:188
ssize_t MagickOffsetType
Definition: magick-type.h:129
MagickOffsetType disk
Definition: resource.c:83
MagickExport RandomInfo * DestroyRandomInfo(RandomInfo *random_info)
Definition: random.c:274
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:293
MagickExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition: string.c:1295
MagickSizeType memory_limit
Definition: resource.c:96
MagickExport ssize_t FormatLocaleFile(FILE *file, const char *magick_restrict format,...)
Definition: locale.c:404
MagickBooleanType
Definition: magick-type.h:158
#define DirectorySeparator
Definition: studio.h:259
MagickExport int AcquireUniqueFileResource(char *path)
Definition: resource.c:536
MagickPrivate ssize_t GetMagickPageSize(void)
Definition: utility.c:1122
MagickPrivate void AsynchronousResourceComponentTerminus(void)
MagickExport const char * CommandOptionToMnemonic(const CommandOption option, const ssize_t type)
Definition: option.c:2680
static SplayTreeInfo * temporary_resources
Definition: resource.c:159
MagickExport StringInfo * DestroyStringInfo(StringInfo *string_info)
Definition: string.c:850
MagickOffsetType list_length
Definition: resource.c:83
MagickSizeType time_limit
Definition: resource.c:96
MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
Definition: resource.c:1097
#define magick_unused(x)
MagickExport SplayTreeInfo * DestroySplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:682
size_t MagickSizeType
Definition: magick-type.h:130
#define MagickPathExtent
MagickOffsetType width
Definition: resource.c:83
MagickExport MagickBooleanType IsEventLogging(void)
Definition: log.c:717
MagickExport SplayTreeInfo * NewSplayTree(int(*compare)(const void *, const void *), void *(*relinquish_key)(void *), void *(*relinquish_value)(void *))
Definition: splay-tree.c:1141
#define O_NOFOLLOW
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1398
static int open_utf8(const char *path, int flags, mode_t mode)
MagickExport RandomInfo * AcquireRandomInfo(void)
Definition: random.c:164
MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
Definition: resource.c:778
MagickExport char * GetEnvironmentValue(const char *name)
Definition: string.c:1262
MagickExport size_t CopyMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:755
MagickPrivate MagickBooleanType ShredFile(const char *)
Definition: utility.c:1809
#define S_MODE
Definition: studio.h:239
#define MagickMax(x, y)
Definition: image-private.h:26
MagickExport void AppendImageFormat(const char *format, char *filename)
Definition: utility.c:281
MagickPrivate void ResourceComponentTerminus(void)
Definition: resource.c:1305
ResourceType
Definition: resource_.h:25
MagickSizeType throttle_limit
Definition: resource.c:96
#define MagickFormatExtent
#define GetMagickModule()
Definition: log.h:28
MagickExport int CompareSplayTreeString(const void *target, const void *source)
Definition: splay-tree.c:412
MagickExport MagickSizeType GetMagickResource(const ResourceType type)
Definition: resource.c:659
#define MagickResourceInfinity
Definition: resource_.h:41
MagickExport const void * GetNextKeyInSplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:769
unsigned short Quantum
Definition: magick-type.h:82
MagickExport char * DestroyString(char *string)
Definition: string.c:823
MagickExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:97
MagickOffsetType throttle
Definition: resource.c:83
static MagickSizeType StringToMagickSizeType(const char *string, const double interval)
static int access_utf8(const char *path, int mode)
MagickSizeType list_length_limit
Definition: resource.c:96
MagickExport MagickBooleanType DeleteNodeFromSplayTree(SplayTreeInfo *splay_tree, const void *key)
Definition: splay-tree.c:603
#define MagickMin(x, y)
Definition: image-private.h:27
MagickExport char * GetPolicyValue(const char *name)
Definition: policy.c:505
MagickSizeType thread_limit
Definition: resource.c:96
MagickExport void ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:1472
static RandomInfo * random_info
Definition: resource.c:113
MagickPrivate void ResetPixelCacheEpoch(void)
#define magick_unreferenced(x)
#define MagickPathTemplate
Definition: resource.c:73
MagickSizeType width_limit
Definition: resource.c:96
MagickExport void * GetImageRegistry(const RegistryType type, const char *key, ExceptionInfo *exception)
Definition: registry.c:187
MagickExport char * CloneString(char **destination, const char *source)
Definition: string.c:286
#define MagickPrivate
#define MagickExport
MagickOffsetType height
Definition: resource.c:83
MagickExport StringInfo * GetRandomKey(RandomInfo *random_info, const size_t length)
Definition: random.c:710
#define TMP_MAX
MagickSizeType file_limit
Definition: resource.c:96
MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
Definition: string.c:1324
#define NumberOfResourceTypes
Definition: resource.c:74
MagickSizeType disk_limit
Definition: resource.c:96
MagickExport MagickBooleanType GetPathTemplate(char *path)
Definition: resource.c:451
MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:351
MagickExport char * ConstantString(const char *source)
Definition: string.c:700
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:418