00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "magick/studio.h"
00043 #include "magick/cache.h"
00044 #include "magick/configure.h"
00045 #include "magick/exception.h"
00046 #include "magick/exception-private.h"
00047 #include "magick/hashmap.h"
00048 #include "magick/log.h"
00049 #include "magick/image.h"
00050 #include "magick/memory_.h"
00051 #include "magick/option.h"
00052 #include "magick/policy.h"
00053 #include "magick/random_.h"
00054 #include "magick/registry.h"
00055 #include "magick/resource_.h"
00056 #include "magick/semaphore.h"
00057 #include "magick/signature-private.h"
00058 #include "magick/string_.h"
00059 #include "magick/splay-tree.h"
00060 #include "magick/thread-private.h"
00061 #include "magick/token.h"
00062 #include "magick/utility.h"
00063
00064
00065
00066
00067 typedef struct _ResourceInfo
00068 {
00069 MagickOffsetType
00070 area,
00071 memory,
00072 map,
00073 disk,
00074 file,
00075 thread,
00076 time;
00077
00078 MagickSizeType
00079 area_limit,
00080 memory_limit,
00081 map_limit,
00082 disk_limit,
00083 file_limit,
00084 thread_limit,
00085 time_limit;
00086 } ResourceInfo;
00087
00088
00089
00090
00091 static RandomInfo
00092 *random_info = (RandomInfo *) NULL;
00093
00094 static ResourceInfo
00095 resource_info =
00096 {
00097 MagickULLConstant(0),
00098 MagickULLConstant(0),
00099 MagickULLConstant(0),
00100 MagickULLConstant(0),
00101 MagickULLConstant(0),
00102 MagickULLConstant(0),
00103 MagickULLConstant(0),
00104 MagickULLConstant(2048)*1024*1024,
00105 MagickULLConstant(1536)*1024*1024,
00106 MagickULLConstant(8192)*1024*1024,
00107 MagickResourceInfinity,
00108 MagickULLConstant(768),
00109 MagickULLConstant(8),
00110 MagickResourceInfinity
00111 };
00112
00113 static SemaphoreInfo
00114 *resource_semaphore = (SemaphoreInfo *) NULL;
00115
00116 static SplayTreeInfo
00117 *temporary_resources = (SplayTreeInfo *) NULL;
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
00147 const MagickSizeType size)
00148 {
00149 char
00150 resource_current[MaxTextExtent],
00151 resource_limit[MaxTextExtent],
00152 resource_request[MaxTextExtent];
00153
00154 MagickBooleanType
00155 status;
00156
00157 MagickSizeType
00158 limit;
00159
00160 status=MagickFalse;
00161 (void) FormatMagickSize(size,resource_request);
00162 if (resource_semaphore == (SemaphoreInfo *) NULL)
00163 AcquireSemaphoreInfo(&resource_semaphore);
00164 (void) LockSemaphoreInfo(resource_semaphore);
00165 switch (type)
00166 {
00167 case AreaResource:
00168 {
00169 resource_info.area=(MagickOffsetType) size;
00170 limit=resource_info.area_limit;
00171 status=(resource_info.area_limit == MagickResourceInfinity) ||
00172 (size < limit) ? MagickTrue : MagickFalse;
00173 (void) FormatMagickSize((MagickSizeType) resource_info.area,
00174 resource_current);
00175 (void) FormatMagickSize(resource_info.area_limit,resource_limit);
00176 break;
00177 }
00178 case MemoryResource:
00179 {
00180 resource_info.memory+=size;
00181 limit=resource_info.memory_limit;
00182 status=(resource_info.memory_limit == MagickResourceInfinity) ||
00183 ((MagickSizeType) resource_info.memory < limit) ?
00184 MagickTrue : MagickFalse;
00185 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
00186 resource_current);
00187 (void) FormatMagickSize(resource_info.memory_limit,
00188 resource_limit);
00189 break;
00190 }
00191 case MapResource:
00192 {
00193 resource_info.map+=size;
00194 limit=resource_info.map_limit;
00195 status=(resource_info.map_limit == MagickResourceInfinity) ||
00196 ((MagickSizeType) resource_info.map < limit) ?
00197 MagickTrue : MagickFalse;
00198 (void) FormatMagickSize((MagickSizeType) resource_info.map,
00199 resource_current);
00200 (void) FormatMagickSize(resource_info.map_limit,
00201 resource_limit);
00202 break;
00203 }
00204 case DiskResource:
00205 {
00206 resource_info.disk+=size;
00207 limit=resource_info.disk_limit;
00208 status=(resource_info.disk_limit == MagickResourceInfinity) ||
00209 ((MagickSizeType) resource_info.disk < limit) ?
00210 MagickTrue : MagickFalse;
00211 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
00212 resource_current);
00213 (void) FormatMagickSize(resource_info.disk_limit,resource_limit);
00214 break;
00215 }
00216 case FileResource:
00217 {
00218 resource_info.file+=size;
00219 limit=resource_info.file_limit;
00220 status=(resource_info.file_limit == MagickResourceInfinity) ||
00221 ((MagickSizeType) resource_info.file < limit) ?
00222 MagickTrue : MagickFalse;
00223 (void) FormatMagickSize((MagickSizeType) resource_info.file,
00224 resource_current);
00225 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
00226 resource_limit);
00227 break;
00228 }
00229 case ThreadResource:
00230 {
00231 resource_info.thread+=size;
00232 limit=resource_info.thread_limit;
00233 status=(resource_info.thread_limit == MagickResourceInfinity) ||
00234 ((MagickSizeType) resource_info.thread < limit) ?
00235 MagickTrue : MagickFalse;
00236 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
00237 resource_current);
00238 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
00239 resource_limit);
00240 break;
00241 }
00242 case TimeResource:
00243 {
00244 resource_info.time+=size;
00245 limit=resource_info.time_limit;
00246 status=(resource_info.time_limit == MagickResourceInfinity) ||
00247 ((MagickSizeType) resource_info.time < limit) ?
00248 MagickTrue : MagickFalse;
00249 (void) FormatMagickSize((MagickSizeType) resource_info.time,
00250 resource_current);
00251 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
00252 resource_limit);
00253 break;
00254 }
00255 default:
00256 break;
00257 }
00258 (void) UnlockSemaphoreInfo(resource_semaphore);
00259 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
00260 MagickOptionToMnemonic(MagickResourceOptions,(long) type),resource_request,
00261 resource_current,resource_limit);
00262 return(status);
00263 }
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 MagickExport void AsynchronousResourceComponentTerminus(void)
00286 {
00287 const char
00288 *path;
00289
00290 if (temporary_resources == (SplayTreeInfo *) NULL)
00291 return;
00292
00293
00294
00295 ResetSplayTreeIterator(temporary_resources);
00296 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
00297 while (path != (const char *) NULL)
00298 {
00299 (void) remove(path);
00300 path=(const char *) GetNextKeyInSplayTree(temporary_resources);
00301 }
00302 }
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 static void *DestroyTemporaryResources(void *temporary_resource)
00330 {
00331 (void) remove((char *) temporary_resource);
00332 return((void *) NULL);
00333 }
00334
00335 static MagickBooleanType GetPathTemplate(char *path)
00336 {
00337 char
00338 *directory;
00339
00340 ExceptionInfo
00341 *exception;
00342
00343 MagickBooleanType
00344 status;
00345
00346 register char
00347 *p;
00348
00349 struct stat
00350 attributes;
00351
00352 (void) CopyMagickString(path,"magick-XXXXXXXX",MaxTextExtent);
00353 exception=AcquireExceptionInfo();
00354 directory=(char *) GetImageRegistry(StringRegistryType,"temporary-path",
00355 exception);
00356 exception=DestroyExceptionInfo(exception);
00357 if (directory == (char *) NULL)
00358 directory=GetEnvironmentValue("MAGICK_TEMPORARY_PATH");
00359 if (directory == (char *) NULL)
00360 directory=GetEnvironmentValue("MAGICK_TMPDIR");
00361 if (directory == (char *) NULL)
00362 directory=GetPolicyValue("temporary-path");
00363 if (directory == (char *) NULL)
00364 directory=GetEnvironmentValue("TMPDIR");
00365 #if defined(__WINDOWS__) || defined(__OS2__)
00366 if (directory == (char *) NULL)
00367 directory=GetEnvironmentValue("TMP");
00368 if (directory == (char *) NULL)
00369 directory=GetEnvironmentValue("TEMP");
00370 #endif
00371 #if defined(__VMS)
00372 if (directory == (char *) NULL)
00373 directory=GetEnvironmentValue("MTMPDIR");
00374 #endif
00375 #if defined(P_tmpdir)
00376 if (directory == (char *) NULL)
00377 directory=ConstantString(P_tmpdir);
00378 #endif
00379 if (directory == (char *) NULL)
00380 return(MagickTrue);
00381 if (strlen(directory) > (MaxTextExtent-15))
00382 {
00383 directory=DestroyString(directory);
00384 return(MagickTrue);
00385 }
00386 status=GetPathAttributes(directory,&attributes);
00387 if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
00388 {
00389 directory=DestroyString(directory);
00390 return(MagickTrue);
00391 }
00392 if (directory[strlen(directory)-1] == *DirectorySeparator)
00393 (void) FormatMagickString(path,MaxTextExtent,"%smagick-XXXXXXXX",directory);
00394 else
00395 (void) FormatMagickString(path,MaxTextExtent,"%s%smagick-XXXXXXXX",
00396 directory,DirectorySeparator);
00397 directory=DestroyString(directory);
00398 if (*DirectorySeparator != '/')
00399 for (p=path; *p != '\0'; p++)
00400 if (*p == *DirectorySeparator)
00401 *p='/';
00402 return(MagickTrue);
00403 }
00404
00405 MagickExport int AcquireUniqueFileResource(char *path)
00406 {
00407 #if !defined(O_NOFOLLOW)
00408 #define O_NOFOLLOW 0
00409 #endif
00410 #if !defined(TMP_MAX)
00411 # define TMP_MAX 238328
00412 #endif
00413
00414 char
00415 *resource;
00416
00417 int
00418 c,
00419 file;
00420
00421 register char
00422 *p;
00423
00424 register long
00425 i;
00426
00427 static const char
00428 portable_filename[65] =
00429 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
00430
00431 StringInfo
00432 *key;
00433
00434 unsigned char
00435 *datum;
00436
00437 assert(path != (char *) NULL);
00438 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
00439 if (random_info == (RandomInfo *) NULL)
00440 random_info=AcquireRandomInfo();
00441 file=(-1);
00442 for (i=0; i < TMP_MAX; i++)
00443 {
00444
00445
00446
00447 (void) GetPathTemplate(path);
00448 #if defined(MAGICKCORE_HAVE_MKSTEMP)
00449 file=mkstemp(path);
00450 #if defined(__OS2__)
00451 setmode(file,O_BINARY);
00452 #endif
00453 if (file != -1)
00454 break;
00455 #endif
00456 key=GetRandomKey(random_info,8);
00457 p=path+strlen(path)-8;
00458 datum=GetStringInfoDatum(key);
00459 for (i=0; i < 8; i++)
00460 {
00461 c=(int) (datum[i] & 0x3f);
00462 *p++=portable_filename[c];
00463 }
00464 key=DestroyStringInfo(key);
00465 file=open(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,S_MODE);
00466 if ((file > 0) || (errno != EEXIST))
00467 break;
00468 }
00469 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
00470 if (file == -1)
00471 return(file);
00472 if (resource_semaphore == (SemaphoreInfo *) NULL)
00473 AcquireSemaphoreInfo(&resource_semaphore);
00474 (void) LockSemaphoreInfo(resource_semaphore);
00475 if (temporary_resources == (SplayTreeInfo *) NULL)
00476 temporary_resources=NewSplayTree(CompareSplayTreeString,
00477 RelinquishMagickMemory,DestroyTemporaryResources);
00478 (void) UnlockSemaphoreInfo(resource_semaphore);
00479 resource=ConstantString(path);
00480 (void) AddValueToSplayTree(temporary_resources,resource,resource);
00481 return(file);
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 MagickExport MagickSizeType GetMagickResource(const ResourceType type)
00507 {
00508 MagickSizeType
00509 resource;
00510
00511 resource=0;
00512 (void) LockSemaphoreInfo(resource_semaphore);
00513 switch (type)
00514 {
00515 case AreaResource:
00516 {
00517 resource=(MagickSizeType) resource_info.area;
00518 break;
00519 }
00520 case MemoryResource:
00521 {
00522 resource=(MagickSizeType) resource_info.memory;
00523 break;
00524 }
00525 case MapResource:
00526 {
00527 resource=(MagickSizeType) resource_info.map;
00528 break;
00529 }
00530 case DiskResource:
00531 {
00532 resource=(MagickSizeType) resource_info.disk;
00533 break;
00534 }
00535 case FileResource:
00536 {
00537 resource=(MagickSizeType) resource_info.file;
00538 break;
00539 }
00540 case ThreadResource:
00541 {
00542 resource=(MagickSizeType) resource_info.thread;
00543 break;
00544 }
00545 case TimeResource:
00546 {
00547 resource=(MagickSizeType) resource_info.time;
00548 break;
00549 }
00550 default:
00551 break;
00552 }
00553 (void) UnlockSemaphoreInfo(resource_semaphore);
00554 return(resource);
00555 }
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
00580 {
00581 MagickSizeType
00582 resource;
00583
00584 resource=0;
00585 if (resource_semaphore == (SemaphoreInfo *) NULL)
00586 AcquireSemaphoreInfo(&resource_semaphore);
00587 (void) LockSemaphoreInfo(resource_semaphore);
00588 switch (type)
00589 {
00590 case AreaResource:
00591 {
00592 resource=resource_info.area_limit;
00593 break;
00594 }
00595 case MemoryResource:
00596 {
00597 resource=resource_info.memory_limit;
00598 break;
00599 }
00600 case MapResource:
00601 {
00602 resource=resource_info.map_limit;
00603 break;
00604 }
00605 case DiskResource:
00606 {
00607 resource=resource_info.disk_limit;
00608 break;
00609 }
00610 case FileResource:
00611 {
00612 resource=resource_info.file_limit;
00613 break;
00614 }
00615 case ThreadResource:
00616 {
00617 resource=resource_info.thread_limit;
00618 break;
00619 }
00620 case TimeResource:
00621 {
00622 resource=resource_info.time_limit;
00623 break;
00624 }
00625 default:
00626 break;
00627 }
00628 (void) UnlockSemaphoreInfo(resource_semaphore);
00629 return(resource);
00630 }
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
00658 ExceptionInfo *magick_unused(exception))
00659 {
00660 char
00661 area_limit[MaxTextExtent],
00662 disk_limit[MaxTextExtent],
00663 map_limit[MaxTextExtent],
00664 memory_limit[MaxTextExtent],
00665 time_limit[MaxTextExtent];
00666
00667 if (file == (const FILE *) NULL)
00668 file=stdout;
00669 if (resource_semaphore == (SemaphoreInfo *) NULL)
00670 AcquireSemaphoreInfo(&resource_semaphore);
00671 (void) LockSemaphoreInfo(resource_semaphore);
00672 (void) FormatMagickSize(resource_info.area_limit,area_limit);
00673 (void) FormatMagickSize(resource_info.memory_limit,memory_limit);
00674 (void) FormatMagickSize(resource_info.map_limit,map_limit);
00675 (void) FormatMagickSize(resource_info.disk_limit,disk_limit);
00676 (void) CopyMagickString(time_limit,"unlimited",MaxTextExtent);
00677 if (resource_info.time_limit != MagickResourceInfinity)
00678 (void) FormatMagickString(time_limit,MaxTextExtent,"%lu",(unsigned long)
00679 resource_info.time_limit);
00680 (void) fprintf(file,"File Area Memory Map"
00681 " Disk Thread Time\n");
00682 (void) fprintf(file,"------------------------------------------------------"
00683 "------------------\n");
00684 (void) fprintf(file,"%4lu %10s %10s %10s %10s %6lu %10s\n",
00685 (unsigned long) resource_info.file_limit,area_limit,memory_limit,map_limit,
00686 disk_limit,(unsigned long) resource_info.thread_limit,time_limit);
00687 (void) fflush(file);
00688 (void) UnlockSemaphoreInfo(resource_semaphore);
00689 return(MagickTrue);
00690 }
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717 MagickExport void RelinquishMagickResource(const ResourceType type,
00718 const MagickSizeType size)
00719 {
00720 char
00721 resource_current[MaxTextExtent],
00722 resource_limit[MaxTextExtent],
00723 resource_request[MaxTextExtent];
00724
00725 (void) FormatMagickSize(size,resource_request);
00726 if (resource_semaphore == (SemaphoreInfo *) NULL)
00727 AcquireSemaphoreInfo(&resource_semaphore);
00728 (void) LockSemaphoreInfo(resource_semaphore);
00729 switch (type)
00730 {
00731 case AreaResource:
00732 {
00733 resource_info.area=(MagickOffsetType) size;
00734 (void) FormatMagickSize((MagickSizeType) resource_info.area,
00735 resource_current);
00736 (void) FormatMagickSize(resource_info.area_limit,resource_limit);
00737 break;
00738 }
00739 case MemoryResource:
00740 {
00741 resource_info.memory-=size;
00742 (void) FormatMagickSize((MagickSizeType) resource_info.memory,
00743 resource_current);
00744 (void) FormatMagickSize(resource_info.memory_limit,resource_limit);
00745 break;
00746 }
00747 case MapResource:
00748 {
00749 resource_info.map-=size;
00750 (void) FormatMagickSize((MagickSizeType) resource_info.map,
00751 resource_current);
00752 (void) FormatMagickSize(resource_info.map_limit,resource_limit);
00753 break;
00754 }
00755 case DiskResource:
00756 {
00757 resource_info.disk-=size;
00758 (void) FormatMagickSize((MagickSizeType) resource_info.disk,
00759 resource_current);
00760 (void) FormatMagickSize(resource_info.disk_limit,resource_limit);
00761 break;
00762 }
00763 case FileResource:
00764 {
00765 resource_info.file-=size;
00766 (void) FormatMagickSize((MagickSizeType) resource_info.file,
00767 resource_current);
00768 (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
00769 resource_limit);
00770 break;
00771 }
00772 case ThreadResource:
00773 {
00774 resource_info.thread-=size;
00775 (void) FormatMagickSize((MagickSizeType) resource_info.thread,
00776 resource_current);
00777 (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
00778 resource_limit);
00779 break;
00780 }
00781 case TimeResource:
00782 {
00783 resource_info.time-=size;
00784 (void) FormatMagickSize((MagickSizeType) resource_info.time,
00785 resource_current);
00786 (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
00787 resource_limit);
00788 break;
00789 }
00790 default:
00791 break;
00792 }
00793 (void) UnlockSemaphoreInfo(resource_semaphore);
00794 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
00795 MagickOptionToMnemonic(MagickResourceOptions,(long) type),resource_request,
00796 resource_current,resource_limit);
00797 }
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821 MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
00822 {
00823 char
00824 cache_path[MaxTextExtent];
00825
00826 assert(path != (const char *) NULL);
00827 (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
00828 if (temporary_resources != (SplayTreeInfo *) NULL)
00829 {
00830 register char
00831 *p;
00832
00833 ResetSplayTreeIterator(temporary_resources);
00834 p=(char *) GetNextKeyInSplayTree(temporary_resources);
00835 while (p != (char *) NULL)
00836 {
00837 if (LocaleCompare(p,path) == 0)
00838 break;
00839 p=(char *) GetNextKeyInSplayTree(temporary_resources);
00840 }
00841 if (p != (char *) NULL)
00842 (void) DeleteNodeFromSplayTree(temporary_resources,p);
00843 }
00844 (void) CopyMagickString(cache_path,path,MaxTextExtent);
00845 AppendImageFormat("cache",cache_path);
00846 (void) remove(cache_path);
00847 return(remove(path) == 0 ? MagickTrue : MagickFalse);
00848 }
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 static inline unsigned long MagickMax(const unsigned long x,
00870 const unsigned long y)
00871 {
00872 if (x > y)
00873 return(x);
00874 return(y);
00875 }
00876
00877 static inline MagickSizeType StringToSizeType(const char *string,
00878 const double interval)
00879 {
00880 double
00881 value;
00882
00883 value=StringToDouble(string,interval);
00884 if (value >= (double) MagickULLConstant(~0))
00885 return(MagickULLConstant(~0));
00886 return((MagickSizeType) value);
00887 }
00888
00889 MagickExport MagickBooleanType ResourceComponentGenesis(void)
00890 {
00891 char
00892 *limit;
00893
00894 long
00895 files,
00896 pages,
00897 pagesize;
00898
00899 MagickSizeType
00900 memory;
00901
00902
00903
00904
00905 AcquireSemaphoreInfo(&resource_semaphore);
00906 pagesize=GetMagickPageSize();
00907 pages=(-1);
00908 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
00909 pages=sysconf(_SC_PHYS_PAGES);
00910 #endif
00911 memory=(MagickSizeType) pages*pagesize;
00912 if ((pagesize <= 0) || (pages <= 0))
00913 memory=2048UL*1024UL*1024UL;
00914 #if defined(PixelCacheThreshold)
00915 memory=PixelCacheThreshold;
00916 #endif
00917 (void) SetMagickResourceLimit(AreaResource,2UL*memory);
00918 (void) SetMagickResourceLimit(MemoryResource,3UL*memory/2UL);
00919 (void) SetMagickResourceLimit(MapResource,4UL*memory);
00920 limit=GetEnvironmentValue("MAGICK_AREA_LIMIT");
00921 if (limit == (char *) NULL)
00922 limit=GetPolicyValue("area");
00923 if (limit != (char *) NULL)
00924 {
00925 (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
00926 limit=DestroyString(limit);
00927 }
00928 limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT");
00929 if (limit == (char *) NULL)
00930 limit=GetPolicyValue("memory");
00931 if (limit != (char *) NULL)
00932 {
00933 (void) SetMagickResourceLimit(MemoryResource,
00934 StringToSizeType(limit,100.0));
00935 limit=DestroyString(limit);
00936 }
00937 limit=GetEnvironmentValue("MAGICK_MAP_LIMIT");
00938 if (limit == (char *) NULL)
00939 limit=GetPolicyValue("map");
00940 if (limit != (char *) NULL)
00941 {
00942 (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
00943 limit=DestroyString(limit);
00944 }
00945 limit=GetEnvironmentValue("MAGICK_DISK_LIMIT");
00946 if (limit == (char *) NULL)
00947 limit=GetPolicyValue("disk");
00948 if (limit != (char *) NULL)
00949 {
00950 (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
00951 limit=DestroyString(limit);
00952 }
00953 files=(-1);
00954 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
00955 files=sysconf(_SC_OPEN_MAX);
00956 #endif
00957 #if defined(MAGICKCORE_HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)
00958 if (files < 0)
00959 {
00960 struct rlimit
00961 resources;
00962
00963 if (getrlimit(RLIMIT_NOFILE,&resources) != -1)
00964 files=resources.rlim_cur;
00965 }
00966 #endif
00967 #if defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
00968 if (files < 0)
00969 files=getdtablesize();
00970 #endif
00971 if (files < 0)
00972 files=64;
00973 (void) SetMagickResourceLimit(FileResource,MagickMax((unsigned long)
00974 (3*files/4),64));
00975 limit=GetEnvironmentValue("MAGICK_FILE_LIMIT");
00976 if (limit == (char *) NULL)
00977 limit=GetPolicyValue("file");
00978 if (limit != (char *) NULL)
00979 {
00980 (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
00981 limit=DestroyString(limit);
00982 }
00983 (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads());
00984 limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT");
00985 if (limit == (char *) NULL)
00986 limit=GetPolicyValue("thread");
00987 if (limit != (char *) NULL)
00988 {
00989 SetOpenMPMaximumThreads((unsigned long) atol(limit));
00990 (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
00991 100.0));
00992 limit=DestroyString(limit);
00993 }
00994 limit=GetEnvironmentValue("MAGICK_TIME_LIMIT");
00995 if (limit == (char *) NULL)
00996 limit=GetPolicyValue("time");
00997 if (limit != (char *) NULL)
00998 {
00999 (void) SetMagickResourceLimit(TimeResource,StringToSizeType(limit,100.0));
01000 limit=DestroyString(limit);
01001 }
01002 return(MagickTrue);
01003 }
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023 MagickExport void ResourceComponentTerminus(void)
01024 {
01025 if (resource_semaphore == (SemaphoreInfo *) NULL)
01026 AcquireSemaphoreInfo(&resource_semaphore);
01027 (void) LockSemaphoreInfo(resource_semaphore);
01028 if (temporary_resources != (SplayTreeInfo *) NULL)
01029 temporary_resources=DestroySplayTree(temporary_resources);
01030 if (random_info != (RandomInfo *) NULL)
01031 random_info=DestroyRandomInfo(random_info);
01032 (void) UnlockSemaphoreInfo(resource_semaphore);
01033 DestroySemaphoreInfo(&resource_semaphore);
01034 }
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061 MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
01062 const MagickSizeType limit)
01063 {
01064 if (resource_semaphore == (SemaphoreInfo *) NULL)
01065 AcquireSemaphoreInfo(&resource_semaphore);
01066 (void) LockSemaphoreInfo(resource_semaphore);
01067 switch (type)
01068 {
01069 case AreaResource:
01070 {
01071 resource_info.area_limit=limit;
01072 break;
01073 }
01074 case MemoryResource:
01075 {
01076 resource_info.memory_limit=limit;
01077 break;
01078 }
01079 case MapResource:
01080 {
01081 resource_info.map_limit=limit;
01082 break;
01083 }
01084 case DiskResource:
01085 {
01086 resource_info.disk_limit=limit;
01087 break;
01088 }
01089 case FileResource:
01090 {
01091 resource_info.file_limit=limit;
01092 break;
01093 }
01094 case ThreadResource:
01095 {
01096 SetOpenMPMaximumThreads((unsigned long) limit);
01097 resource_info.thread_limit=GetOpenMPMaximumThreads();
01098 break;
01099 }
01100 case TimeResource:
01101 {
01102 resource_info.time_limit=limit;
01103 break;
01104 }
01105 default:
01106 break;
01107 }
01108 (void) UnlockSemaphoreInfo(resource_semaphore);
01109 return(MagickTrue);
01110 }