resource.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %           RRRR    EEEEE   SSSSS   OOO   U   U  RRRR    CCCC  EEEEE          %
00007 %           R   R   E       SS     O   O  U   U  R   R  C      E              %
00008 %           RRRR    EEE      SSS   O   O  U   U  RRRR   C      EEE            %
00009 %           R R     E          SS  O   O  U   U  R R    C      E              %
00010 %           R  R    EEEEE   SSSSS   OOO    UUU   R  R    CCCC  EEEEE          %
00011 %                                                                             %
00012 %                                                                             %
00013 %                        Get/Set MagickCore Resources                         %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                               September 2002                                %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
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   Typedef declarations.
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   Global declarations.
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 %   A c q u i r e M a g i c k R e s o u r c e                                 %
00125 %                                                                             %
00126 %                                                                             %
00127 %                                                                             %
00128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00129 %
00130 %  AcquireMagickResource() acquires resources of the specified type.
00131 %  MagickFalse is returned if the specified resource is exhausted otherwise
00132 %  MagickTrue.
00133 %
00134 %  The format of the AcquireMagickResource() method is:
00135 %
00136 %      MagickBooleanType AcquireMagickResource(const ResourceType type,
00137 %        const MagickSizeType size)
00138 %
00139 %  A description of each parameter follows:
00140 %
00141 %    o type: the type of resource.
00142 %
00143 %    o size: the number of bytes needed from for this resource.
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 +   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 %
00271 %                                                                             %
00272 %                                                                             %
00273 %                                                                             %
00274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00275 %
00276 %  AsynchronousResourceComponentTerminus() destroys the resource environment.
00277 %  It differs from ResourceComponentTerminus() in that it can be called from a
00278 %  asynchronous signal handler.
00279 %
00280 %  The format of the ResourceComponentTerminus() method is:
00281 %
00282 %      ResourceComponentTerminus(void)
00283 %
00284 */
00285 MagickExport void AsynchronousResourceComponentTerminus(void)
00286 {
00287   const char
00288     *path;
00289 
00290   if (temporary_resources == (SplayTreeInfo *) NULL)
00291     return;
00292   /*
00293     Remove any lingering temporary files.
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 %   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                         %
00310 %                                                                             %
00311 %                                                                             %
00312 %                                                                             %
00313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00314 %
00315 %  AcquireUniqueFileResource() returns a unique file name, and returns a file
00316 %  descriptor for the file open for reading and writing.
00317 %
00318 %  The format of the AcquireUniqueFileResource() method is:
00319 %
00320 %      int AcquireUniqueFileResource(char *path)
00321 %
00322 %  A description of each parameter follows:
00323 %
00324 %   o  path:  Specifies a pointer to an array of characters.  The unique path
00325 %      name is returned in this array.
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       Get temporary pathname.
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 %   G e t M a g i c k R e s o u r c e                                         %
00490 %                                                                             %
00491 %                                                                             %
00492 %                                                                             %
00493 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00494 %
00495 %  GetMagickResource() returns the specified resource.
00496 %
00497 %  The format of the GetMagickResource() method is:
00498 %
00499 %      MagickSizeType GetMagickResource(const ResourceType type)
00500 %
00501 %  A description of each parameter follows:
00502 %
00503 %    o type: the type of resource.
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 %   G e t M a g i c k R e s o u r c e L i m i t                               %
00563 %                                                                             %
00564 %                                                                             %
00565 %                                                                             %
00566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00567 %
00568 %  GetMagickResource() returns the specified resource limit.
00569 %
00570 %  The format of the GetMagickResourceLimit() method is:
00571 %
00572 %      unsigned long GetMagickResourceLimit(const ResourceType type)
00573 %
00574 %  A description of each parameter follows:
00575 %
00576 %    o type: the type of resource.
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 %  L i s t M a g i c k R e s o u r c e I n f o                                %
00638 %                                                                             %
00639 %                                                                             %
00640 %                                                                             %
00641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00642 %
00643 %  ListMagickResourceInfo() lists the resource info to a file.
00644 %
00645 %  The format of the ListMagickResourceInfo method is:
00646 %
00647 %      MagickBooleanType ListMagickResourceInfo(FILE *file,
00648 %        ExceptionInfo *exception)
00649 %
00650 %  A description of each parameter follows.
00651 %
00652 %    o file:  An pointer to a FILE.
00653 %
00654 %    o exception: return any errors or warnings in this structure.
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 %   R e l i n q u i s h M a g i c k R e s o u r c e                           %
00698 %                                                                             %
00699 %                                                                             %
00700 %                                                                             %
00701 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00702 %
00703 %  RelinquishMagickResource() relinquishes resources of the specified type.
00704 %
00705 %  The format of the RelinquishMagickResource() method is:
00706 %
00707 %      void RelinquishMagickResource(const ResourceType type,
00708 %        const MagickSizeType size)
00709 %
00710 %  A description of each parameter follows:
00711 %
00712 %    o type: the type of resource.
00713 %
00714 %    o size: the size of the resource.
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 %    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                  %
00805 %                                                                             %
00806 %                                                                             %
00807 %                                                                             %
00808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00809 %
00810 %  RelinquishUniqueFileResource() relinquishes a unique file resource.
00811 %
00812 %  The format of the RelinquishUniqueFileResource() method is:
00813 %
00814 %      MagickBooleanType RelinquishUniqueFileResource(const char *path)
00815 %
00816 %  A description of each parameter follows:
00817 %
00818 %    o name: the name of the temporary resource.
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 +   R e s o u r c e C o m p o n e n t G e n e s i s                           %
00856 %                                                                             %
00857 %                                                                             %
00858 %                                                                             %
00859 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00860 %
00861 %  ResourceComponentGenesis() instantiates the resource component.
00862 %
00863 %  The format of the ResourceComponentGenesis method is:
00864 %
00865 %      MagickBooleanType ResourceComponentGenesis(void)
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     Set Magick resource limits.
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 +   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                         %
01011 %                                                                             %
01012 %                                                                             %
01013 %                                                                             %
01014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01015 %
01016 %  ResourceComponentTerminus() destroys the resource component.
01017 %
01018 %  The format of the ResourceComponentTerminus() method is:
01019 %
01020 %      ResourceComponentTerminus(void)
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 %   S e t M a g i c k R e s o u r c e L i m i t                               %
01042 %                                                                             %
01043 %                                                                             %
01044 %                                                                             %
01045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01046 %
01047 %  SetMagickResourceLimit() sets the limit for a particular resource.
01048 %
01049 %  The format of the SetMagickResourceLimit() method is:
01050 %
01051 %      MagickBooleanType SetMagickResourceLimit(const ResourceType type,
01052 %        const MagickSizeType limit)
01053 %
01054 %  A description of each parameter follows:
01055 %
01056 %    o type: the type of resource.
01057 %
01058 %    o limit: the maximum limit for the resource.
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 }

Generated on 19 Nov 2009 for MagickCore by  doxygen 1.6.1