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-2010 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   AcquireSemaphoreInfo(&resource_semaphore);
00163   switch (type)
00164   {
00165     case AreaResource:
00166     {
00167       resource_info.area=(MagickOffsetType) size;
00168       limit=resource_info.area_limit;
00169       status=(resource_info.area_limit == MagickResourceInfinity) ||
00170         (size < limit) ? MagickTrue : MagickFalse;
00171       (void) FormatMagickSize((MagickSizeType) resource_info.area,
00172         resource_current);
00173       (void) FormatMagickSize(resource_info.area_limit,resource_limit);
00174       break;
00175     }
00176     case MemoryResource:
00177     {
00178       resource_info.memory+=size;
00179       limit=resource_info.memory_limit;
00180       status=(resource_info.memory_limit == MagickResourceInfinity) ||
00181         ((MagickSizeType) resource_info.memory < limit) ?
00182         MagickTrue : MagickFalse;
00183       (void) FormatMagickSize((MagickSizeType) resource_info.memory,
00184         resource_current);
00185       (void) FormatMagickSize(resource_info.memory_limit,
00186         resource_limit);
00187       break;
00188     }
00189     case MapResource:
00190     {
00191       resource_info.map+=size;
00192       limit=resource_info.map_limit;
00193       status=(resource_info.map_limit == MagickResourceInfinity) ||
00194         ((MagickSizeType) resource_info.map < limit) ?
00195         MagickTrue : MagickFalse;
00196       (void) FormatMagickSize((MagickSizeType) resource_info.map,
00197         resource_current);
00198       (void) FormatMagickSize(resource_info.map_limit,
00199         resource_limit);
00200       break;
00201     }
00202     case DiskResource:
00203     {
00204       resource_info.disk+=size;
00205       limit=resource_info.disk_limit;
00206       status=(resource_info.disk_limit == MagickResourceInfinity) ||
00207         ((MagickSizeType) resource_info.disk < limit) ?
00208         MagickTrue : MagickFalse;
00209       (void) FormatMagickSize((MagickSizeType) resource_info.disk,
00210         resource_current);
00211       (void) FormatMagickSize(resource_info.disk_limit,resource_limit);
00212       break;
00213     }
00214     case FileResource:
00215     {
00216       resource_info.file+=size;
00217       limit=resource_info.file_limit;
00218       status=(resource_info.file_limit == MagickResourceInfinity) ||
00219         ((MagickSizeType) resource_info.file < limit) ?
00220         MagickTrue : MagickFalse;
00221       (void) FormatMagickSize((MagickSizeType) resource_info.file,
00222         resource_current);
00223       (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
00224         resource_limit);
00225       break;
00226     }
00227     case ThreadResource:
00228     {
00229       resource_info.thread+=size;
00230       limit=resource_info.thread_limit;
00231       status=(resource_info.thread_limit == MagickResourceInfinity) ||
00232         ((MagickSizeType) resource_info.thread < limit) ?
00233         MagickTrue : MagickFalse;
00234       (void) FormatMagickSize((MagickSizeType) resource_info.thread,
00235         resource_current);
00236       (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
00237         resource_limit);
00238       break;
00239     }
00240     case TimeResource:
00241     {
00242       resource_info.time+=size;
00243       limit=resource_info.time_limit;
00244       status=(resource_info.time_limit == MagickResourceInfinity) ||
00245         ((MagickSizeType) resource_info.time < limit) ?
00246         MagickTrue : MagickFalse;
00247       (void) FormatMagickSize((MagickSizeType) resource_info.time,
00248         resource_current);
00249       (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
00250         resource_limit);
00251       break;
00252     }
00253     default:
00254       break;
00255   }
00256   RelinquishSemaphoreInfo(resource_semaphore);
00257   (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
00258     MagickOptionToMnemonic(MagickResourceOptions,(long) type),resource_request,
00259     resource_current,resource_limit);
00260   return(status);
00261 }
00262 
00263 /*
00264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00265 %                                                                             %
00266 %                                                                             %
00267 %                                                                             %
00268 +   A s y n c h r o n o u s D e s t r o y M a g i c k R e s o u r c e s       %
00269 %                                                                             %
00270 %                                                                             %
00271 %                                                                             %
00272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00273 %
00274 %  AsynchronousDestroyMagickResources() destroys the resource environment.
00275 %  It differs from DestroyMagickResources() in that it can be called from a
00276 %  asynchronous signal handler.
00277 %
00278 %  The format of the DestroyMagickResources() method is:
00279 %
00280 %      DestroyMagickResources(void)
00281 %
00282 */
00283 MagickExport void AsynchronousDestroyMagickResources(void)
00284 {
00285   const char
00286     *path;
00287 
00288   if (temporary_resources == (SplayTreeInfo *) NULL)
00289     return;
00290   /*
00291     Remove any lingering temporary files.
00292   */
00293   ResetSplayTreeIterator(temporary_resources);
00294   path=(const char *) GetNextKeyInSplayTree(temporary_resources);
00295   while (path != (const char *) NULL)
00296   {
00297     (void) remove(path);
00298     path=(const char *) GetNextKeyInSplayTree(temporary_resources);
00299   }
00300 }
00301 
00302 /*
00303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00304 %                                                                             %
00305 %                                                                             %
00306 %                                                                             %
00307 %   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                         %
00308 %                                                                             %
00309 %                                                                             %
00310 %                                                                             %
00311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00312 %
00313 %  AcquireUniqueFileResource() returns a unique file name, and returns a file
00314 %  descriptor for the file open for reading and writing.
00315 %
00316 %  The format of the AcquireUniqueFileResource() method is:
00317 %
00318 %      int AcquireUniqueFileResource(char *path)
00319 %
00320 %  A description of each parameter follows:
00321 %
00322 %   o  path:  Specifies a pointer to an array of characters.  The unique path
00323 %      name is returned in this array.
00324 %
00325 */
00326 
00327 static void *DestroyTemporaryResources(void *temporary_resource)
00328 {
00329   (void) remove((char *) temporary_resource);
00330   return((void *) NULL);
00331 }
00332 
00333 static MagickBooleanType GetPathTemplate(char *path)
00334 {
00335   char
00336     *directory;
00337 
00338   ExceptionInfo
00339     *exception;
00340 
00341   MagickBooleanType
00342     status;
00343 
00344   register char
00345     *p;
00346 
00347   struct stat
00348     attributes;
00349 
00350   (void) CopyMagickString(path,"magick-XXXXXXXX",MaxTextExtent);
00351   exception=AcquireExceptionInfo();
00352   directory=(char *) GetImageRegistry(StringRegistryType,"temporary-path",
00353     exception);
00354   exception=DestroyExceptionInfo(exception);
00355   if (directory == (char *) NULL)
00356     directory=GetEnvironmentValue("MAGICK_TEMPORARY_PATH");
00357   if (directory == (char *) NULL)
00358     directory=GetEnvironmentValue("MAGICK_TMPDIR");
00359   if (directory == (char *) NULL)
00360     directory=GetPolicyValue("temporary-path");
00361   if (directory == (char *) NULL)
00362     directory=GetEnvironmentValue("TMPDIR");
00363 #if defined(__WINDOWS__) || defined(__OS2__)
00364   if (directory == (char *) NULL)
00365     directory=GetEnvironmentValue("TMP");
00366   if (directory == (char *) NULL)
00367     directory=GetEnvironmentValue("TEMP");
00368 #endif
00369 #if defined(__VMS)
00370   if (directory == (char *) NULL)
00371     directory=GetEnvironmentValue("MTMPDIR");
00372 #endif
00373 #if defined(P_tmpdir)
00374   if (directory == (char *) NULL)
00375     directory=ConstantString(P_tmpdir);
00376 #endif
00377   if (directory == (char *) NULL)
00378     return(MagickTrue);
00379   if (strlen(directory) > (MaxTextExtent-15))
00380     {
00381       directory=DestroyString(directory);
00382       return(MagickTrue);
00383     }
00384   status=GetPathAttributes(directory,&attributes);
00385   if ((status == MagickFalse) || !S_ISDIR(attributes.st_mode))
00386     {
00387       directory=DestroyString(directory);
00388       return(MagickTrue);
00389     }
00390   if (directory[strlen(directory)-1] == *DirectorySeparator)
00391     (void) FormatMagickString(path,MaxTextExtent,"%smagick-XXXXXXXX",directory);
00392   else
00393     (void) FormatMagickString(path,MaxTextExtent,"%s%smagick-XXXXXXXX",
00394       directory,DirectorySeparator);
00395   directory=DestroyString(directory);
00396   if (*DirectorySeparator != '/')
00397     for (p=path; *p != '\0'; p++)
00398       if (*p == *DirectorySeparator)
00399         *p='/';
00400   return(MagickTrue);
00401 }
00402 
00403 MagickExport int AcquireUniqueFileResource(char *path)
00404 {
00405 #if !defined(O_NOFOLLOW)
00406 #define O_NOFOLLOW 0
00407 #endif
00408 #if !defined(TMP_MAX)
00409 # define TMP_MAX  238328
00410 #endif
00411 
00412   char
00413     *resource;
00414 
00415   int
00416     c,
00417     file;
00418 
00419   register char
00420     *p;
00421 
00422   register long
00423     i;
00424 
00425   static const char
00426     portable_filename[65] =
00427       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
00428 
00429   StringInfo
00430     *key;
00431 
00432   unsigned char
00433     *datum;
00434 
00435   assert(path != (char *) NULL);
00436   (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
00437   if (random_info == (RandomInfo *) NULL)
00438     random_info=AcquireRandomInfo();
00439   file=(-1);
00440   for (i=0; i < TMP_MAX; i++)
00441   {
00442     /*
00443       Get temporary pathname.
00444     */
00445     (void) GetPathTemplate(path);
00446 #if defined(MAGICKCORE_HAVE_MKSTEMP)
00447     file=mkstemp(path);
00448 #if defined(__OS2__)
00449     setmode(file,O_BINARY);
00450 #endif
00451     if (file != -1)
00452       break;
00453 #endif
00454     key=GetRandomKey(random_info,8);
00455     p=path+strlen(path)-8;
00456     datum=GetStringInfoDatum(key);
00457     for (i=0; i < 8; i++)
00458     {
00459       c=(int) (datum[i] & 0x3f);
00460       *p++=portable_filename[c];
00461     }
00462     key=DestroyStringInfo(key);
00463     file=open(path,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,S_MODE);
00464     if ((file > 0) || (errno != EEXIST))
00465       break;
00466   }
00467   (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
00468   if (file == -1)
00469     return(file);
00470   AcquireSemaphoreInfo(&resource_semaphore);
00471   if (temporary_resources == (SplayTreeInfo *) NULL)
00472     temporary_resources=NewSplayTree(CompareSplayTreeString,
00473       RelinquishMagickMemory,DestroyTemporaryResources);
00474   RelinquishSemaphoreInfo(resource_semaphore);
00475   resource=ConstantString(path);
00476   (void) AddValueToSplayTree(temporary_resources,resource,resource);
00477   return(file);
00478 }
00479 
00480 /*
00481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00482 %                                                                             %
00483 %                                                                             %
00484 %                                                                             %
00485 +   D e s t r o y M a g i c k R e s o u r c e s                               %
00486 %                                                                             %
00487 %                                                                             %
00488 %                                                                             %
00489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00490 %
00491 %  DestroyMagickResources() destroys the resource environment.
00492 %
00493 %  The format of the DestroyMagickResources() method is:
00494 %
00495 %      DestroyMagickResources(void)
00496 %
00497 */
00498 MagickExport void DestroyMagickResources(void)
00499 {
00500   AcquireSemaphoreInfo(&resource_semaphore);
00501   if (temporary_resources != (SplayTreeInfo *) NULL)
00502     temporary_resources=DestroySplayTree(temporary_resources);
00503   if (random_info != (RandomInfo *) NULL)
00504     random_info=DestroyRandomInfo(random_info);
00505   RelinquishSemaphoreInfo(resource_semaphore);
00506   DestroySemaphoreInfo(&resource_semaphore);
00507 }
00508 
00509 /*
00510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00511 %                                                                             %
00512 %                                                                             %
00513 %                                                                             %
00514 %   G e t M a g i c k R e s o u r c e                                         %
00515 %                                                                             %
00516 %                                                                             %
00517 %                                                                             %
00518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00519 %
00520 %  GetMagickResource() returns the specified resource.
00521 %
00522 %  The format of the GetMagickResource() method is:
00523 %
00524 %      MagickSizeType GetMagickResource(const ResourceType type)
00525 %
00526 %  A description of each parameter follows:
00527 %
00528 %    o type: the type of resource.
00529 %
00530 */
00531 MagickExport MagickSizeType GetMagickResource(const ResourceType type)
00532 {
00533   MagickSizeType
00534     resource;
00535 
00536   resource=0;
00537   AcquireSemaphoreInfo(&resource_semaphore);
00538   switch (type)
00539   {
00540     case AreaResource:
00541     {
00542       resource=(MagickSizeType) resource_info.area;
00543       break;
00544     }
00545     case MemoryResource:
00546     {
00547       resource=(MagickSizeType) resource_info.memory;
00548       break;
00549     }
00550     case MapResource:
00551     {
00552       resource=(MagickSizeType) resource_info.map;
00553       break;
00554     }
00555     case DiskResource:
00556     {
00557       resource=(MagickSizeType) resource_info.disk;
00558       break;
00559     }
00560     case FileResource:
00561     {
00562       resource=(MagickSizeType) resource_info.file;
00563       break;
00564     }
00565     case ThreadResource:
00566     {
00567       resource=(MagickSizeType) resource_info.thread;
00568       break;
00569     }
00570     case TimeResource:
00571     {
00572       resource=(MagickSizeType) resource_info.time;
00573       break;
00574     }
00575     default:
00576       break;
00577   }
00578   RelinquishSemaphoreInfo(resource_semaphore);
00579   return(resource);
00580 }
00581 
00582 /*
00583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00584 %                                                                             %
00585 %                                                                             %
00586 %                                                                             %
00587 %   G e t M a g i c k R e s o u r c e L i m i t                               %
00588 %                                                                             %
00589 %                                                                             %
00590 %                                                                             %
00591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00592 %
00593 %  GetMagickResource() returns the specified resource limit.
00594 %
00595 %  The format of the GetMagickResourceLimit() method is:
00596 %
00597 %      unsigned long GetMagickResourceLimit(const ResourceType type)
00598 %
00599 %  A description of each parameter follows:
00600 %
00601 %    o type: the type of resource.
00602 %
00603 */
00604 MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
00605 {
00606   MagickSizeType
00607     resource;
00608 
00609   resource=0;
00610   AcquireSemaphoreInfo(&resource_semaphore);
00611   switch (type)
00612   {
00613     case AreaResource:
00614     {
00615       resource=resource_info.area_limit;
00616       break;
00617     }
00618     case MemoryResource:
00619     {
00620       resource=resource_info.memory_limit;
00621       break;
00622     }
00623     case MapResource:
00624     {
00625       resource=resource_info.map_limit;
00626       break;
00627     }
00628     case DiskResource:
00629     {
00630       resource=resource_info.disk_limit;
00631       break;
00632     }
00633     case FileResource:
00634     {
00635       resource=resource_info.file_limit;
00636       break;
00637     }
00638     case ThreadResource:
00639     {
00640       resource=resource_info.thread_limit;
00641       break;
00642     }
00643     case TimeResource:
00644     {
00645       resource=resource_info.time_limit;
00646       break;
00647     }
00648     default:
00649       break;
00650   }
00651   RelinquishSemaphoreInfo(resource_semaphore);
00652   return(resource);
00653 }
00654 
00655 /*
00656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00657 %                                                                             %
00658 %                                                                             %
00659 %                                                                             %
00660 +   I n i t i a l i z e M a g i c k R e s o u r c e s                         %
00661 %                                                                             %
00662 %                                                                             %
00663 %                                                                             %
00664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00665 %
00666 %  InitializeMagickResources() initializes the resource environment.
00667 %
00668 %  The format of the InitializeMagickResources() method is:
00669 %
00670 %      InitializeMagickResources(void)
00671 %
00672 */
00673 
00674 static inline unsigned long MagickMax(const unsigned long x,
00675   const unsigned long y)
00676 {
00677   if (x > y)
00678     return(x);
00679   return(y);
00680 }
00681 
00682 static inline MagickSizeType StringToSizeType(const char *string,
00683   const double interval)
00684 {
00685   double
00686     value;
00687 
00688   value=StringToDouble(string,interval);
00689   if (value >= (double) MagickULLConstant(~0))
00690     return(MagickULLConstant(~0));
00691   return((MagickSizeType) value);
00692 }
00693 
00694 MagickExport void InitializeMagickResources(void)
00695 {
00696   char
00697     *limit;
00698 
00699   long
00700     files,
00701     pages,
00702     pagesize;
00703 
00704   MagickSizeType
00705     memory;
00706 
00707   /*
00708     Set Magick resource limits.
00709   */
00710   pagesize=(-1);
00711 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PAGESIZE)
00712   pagesize=sysconf(_SC_PAGESIZE);
00713 #elif defined(MAGICKCORE_HAVE_GETPAGESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
00714   pagesize=getpagesize();
00715 #endif
00716   pages=(-1);
00717 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
00718   pages=sysconf(_SC_PHYS_PAGES);
00719 #endif
00720   memory=(MagickSizeType) pages*pagesize;
00721   if ((pagesize <= 0) || (pages <= 0))
00722     memory=2048UL*1024UL*1024UL;
00723 #if defined(PixelCacheThreshold)
00724   memory=PixelCacheThreshold;
00725 #endif
00726   (void) SetMagickResourceLimit(AreaResource,2UL*memory);
00727   (void) SetMagickResourceLimit(MemoryResource,3UL*memory/2UL);
00728   (void) SetMagickResourceLimit(MapResource,4UL*memory);
00729   limit=GetEnvironmentValue("MAGICK_AREA_LIMIT");
00730   if (limit == (char *) NULL)
00731     limit=GetPolicyValue("area");
00732   if (limit != (char *) NULL)
00733     {
00734       (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
00735       limit=DestroyString(limit);
00736     }
00737   limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT");
00738   if (limit == (char *) NULL)
00739     limit=GetPolicyValue("memory");
00740   if (limit != (char *) NULL)
00741     {
00742       (void) SetMagickResourceLimit(MemoryResource,
00743         StringToSizeType(limit,100.0));
00744       limit=DestroyString(limit);
00745     }
00746   limit=GetEnvironmentValue("MAGICK_MAP_LIMIT");
00747   if (limit == (char *) NULL)
00748     limit=GetPolicyValue("map");
00749   if (limit != (char *) NULL)
00750     {
00751       (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
00752       limit=DestroyString(limit);
00753     }
00754   limit=GetEnvironmentValue("MAGICK_DISK_LIMIT");
00755   if (limit == (char *) NULL)
00756     limit=GetPolicyValue("disk");
00757   if (limit != (char *) NULL)
00758     {
00759       (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
00760       limit=DestroyString(limit);
00761     }
00762   files=(-1);
00763 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
00764   files=sysconf(_SC_OPEN_MAX);
00765 #elif defined(MAGICKCORE_HAVE_GETDTABLESIZE) && defined(MAGICKCORE_POSIX_SUPPORT)
00766   files=getdtablesize();
00767 #endif
00768   (void) SetMagickResourceLimit(FileResource,MagickMax((unsigned long)
00769     (3*files/4),64));
00770   limit=GetEnvironmentValue("MAGICK_FILE_LIMIT");
00771   if (limit == (char *) NULL)
00772     limit=GetPolicyValue("file");
00773   if (limit != (char *) NULL)
00774     {
00775       (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,100.0));
00776       limit=DestroyString(limit);
00777     }
00778   (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads());
00779   limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT");
00780   if (limit == (char *) NULL)
00781     limit=GetPolicyValue("thread");
00782   if (limit != (char *) NULL)
00783     {
00784       SetOpenMPMaximumThreads((unsigned long) atol(limit));
00785       (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
00786         100.0));
00787       limit=DestroyString(limit);
00788     }
00789   limit=GetEnvironmentValue("MAGICK_TIME_LIMIT");
00790   if (limit == (char *) NULL)
00791     limit=GetPolicyValue("time");
00792   if (limit != (char *) NULL)
00793     {
00794       (void) SetMagickResourceLimit(TimeResource,StringToSizeType(limit,100.0));
00795       limit=DestroyString(limit);
00796     }
00797 }
00798 
00799 /*
00800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00801 %                                                                             %
00802 %                                                                             %
00803 %                                                                             %
00804 %  L i s t M a g i c k R e s o u r c e I n f o                                %
00805 %                                                                             %
00806 %                                                                             %
00807 %                                                                             %
00808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00809 %
00810 %  ListMagickResourceInfo() lists the resource info to a file.
00811 %
00812 %  The format of the ListMagickResourceInfo method is:
00813 %
00814 %      MagickBooleanType ListMagickResourceInfo(FILE *file,
00815 %        ExceptionInfo *exception)
00816 %
00817 %  A description of each parameter follows.
00818 %
00819 %    o file:  An pointer to a FILE.
00820 %
00821 %    o exception: return any errors or warnings in this structure.
00822 %
00823 */
00824 MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
00825   ExceptionInfo *magick_unused(exception))
00826 {
00827   char
00828     area_limit[MaxTextExtent],
00829     disk_limit[MaxTextExtent],
00830     map_limit[MaxTextExtent],
00831     memory_limit[MaxTextExtent],
00832     time_limit[MaxTextExtent];
00833 
00834   if (file == (const FILE *) NULL)
00835     file=stdout;
00836   AcquireSemaphoreInfo(&resource_semaphore);
00837   (void) FormatMagickSize(resource_info.area_limit,area_limit);
00838   (void) FormatMagickSize(resource_info.memory_limit,memory_limit);
00839   (void) FormatMagickSize(resource_info.map_limit,map_limit);
00840   (void) FormatMagickSize(resource_info.disk_limit,disk_limit);
00841   (void) CopyMagickString(time_limit,"unlimited",MaxTextExtent);
00842   if (resource_info.time_limit != MagickResourceInfinity)
00843     (void) FormatMagickString(time_limit,MaxTextExtent,"%lu",(unsigned long)
00844       resource_info.time_limit);
00845   (void) fprintf(file,"File       Area     Memory        Map"
00846     "       Disk  Thread       Time\n");
00847   (void) fprintf(file,"-----------------------------------------------------"
00848     "--------------\n");
00849   (void) fprintf(file,"%4lu  %9s  %9s  %9s  %9s  %6lu  %9s\n",(unsigned long)
00850     resource_info.file_limit,area_limit,memory_limit,map_limit,disk_limit,
00851     (unsigned long) resource_info.thread_limit,time_limit);
00852   (void) fflush(file);
00853   RelinquishSemaphoreInfo(resource_semaphore);
00854   return(MagickTrue);
00855 }
00856 
00857 /*
00858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00859 %                                                                             %
00860 %                                                                             %
00861 %                                                                             %
00862 %   R e l i n q u i s h M a g i c k R e s o u r c e                           %
00863 %                                                                             %
00864 %                                                                             %
00865 %                                                                             %
00866 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00867 %
00868 %  RelinquishMagickResource() relinquishes resources of the specified type.
00869 %
00870 %  The format of the RelinquishMagickResource() method is:
00871 %
00872 %      void RelinquishMagickResource(const ResourceType type,
00873 %        const MagickSizeType size)
00874 %
00875 %  A description of each parameter follows:
00876 %
00877 %    o type: the type of resource.
00878 %
00879 %    o size: the size of the resource.
00880 %
00881 */
00882 MagickExport void RelinquishMagickResource(const ResourceType type,
00883   const MagickSizeType size)
00884 {
00885   char
00886     resource_current[MaxTextExtent],
00887     resource_limit[MaxTextExtent],
00888     resource_request[MaxTextExtent];
00889 
00890   (void) FormatMagickSize(size,resource_request);
00891   AcquireSemaphoreInfo(&resource_semaphore);
00892   switch (type)
00893   {
00894     case AreaResource:
00895     {
00896       resource_info.area=(MagickOffsetType) size;
00897       (void) FormatMagickSize((MagickSizeType) resource_info.area,
00898         resource_current);
00899       (void) FormatMagickSize(resource_info.area_limit,resource_limit);
00900       break;
00901     }
00902     case MemoryResource:
00903     {
00904       resource_info.memory-=size;
00905       (void) FormatMagickSize((MagickSizeType) resource_info.memory,
00906         resource_current);
00907       (void) FormatMagickSize(resource_info.memory_limit,resource_limit);
00908       break;
00909     }
00910     case MapResource:
00911     {
00912       resource_info.map-=size;
00913       (void) FormatMagickSize((MagickSizeType) resource_info.map,
00914         resource_current);
00915       (void) FormatMagickSize(resource_info.map_limit,resource_limit);
00916       break;
00917     }
00918     case DiskResource:
00919     {
00920       resource_info.disk-=size;
00921       (void) FormatMagickSize((MagickSizeType) resource_info.disk,
00922         resource_current);
00923       (void) FormatMagickSize(resource_info.disk_limit,resource_limit);
00924       break;
00925     }
00926     case FileResource:
00927     {
00928       resource_info.file-=size;
00929       (void) FormatMagickSize((MagickSizeType) resource_info.file,
00930         resource_current);
00931       (void) FormatMagickSize((MagickSizeType) resource_info.file_limit,
00932         resource_limit);
00933       break;
00934     }
00935     case ThreadResource:
00936     {
00937       resource_info.thread-=size;
00938       (void) FormatMagickSize((MagickSizeType) resource_info.thread,
00939         resource_current);
00940       (void) FormatMagickSize((MagickSizeType) resource_info.thread_limit,
00941         resource_limit);
00942       break;
00943     }
00944     case TimeResource:
00945     {
00946       resource_info.time-=size;
00947       (void) FormatMagickSize((MagickSizeType) resource_info.time,
00948         resource_current);
00949       (void) FormatMagickSize((MagickSizeType) resource_info.time_limit,
00950         resource_limit);
00951       break;
00952     }
00953     default:
00954       break;
00955   }
00956   RelinquishSemaphoreInfo(resource_semaphore);
00957   (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s: %s/%s/%s",
00958     MagickOptionToMnemonic(MagickResourceOptions,(long) type),resource_request,
00959     resource_current,resource_limit);
00960 }
00961 
00962 /*
00963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00964 %                                                                             %
00965 %                                                                             %
00966 %                                                                             %
00967 %    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                  %
00968 %                                                                             %
00969 %                                                                             %
00970 %                                                                             %
00971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00972 %
00973 %  RelinquishUniqueFileResource() relinquishes a unique file resource.
00974 %
00975 %  The format of the RelinquishUniqueFileResource() method is:
00976 %
00977 %      MagickBooleanType RelinquishUniqueFileResource(const char *path)
00978 %
00979 %  A description of each parameter follows:
00980 %
00981 %    o name: the name of the temporary resource.
00982 %
00983 */
00984 MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
00985 {
00986   char
00987     cache_path[MaxTextExtent];
00988 
00989   assert(path != (const char *) NULL);
00990   (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
00991   if (temporary_resources != (SplayTreeInfo *) NULL)
00992     {
00993       register char
00994         *p;
00995 
00996       ResetSplayTreeIterator(temporary_resources);
00997       p=(char *) GetNextKeyInSplayTree(temporary_resources);
00998       while (p != (char *) NULL)
00999       {
01000         if (LocaleCompare(p,path) == 0)
01001           break;
01002         p=(char *) GetNextKeyInSplayTree(temporary_resources);
01003       }
01004       if (p != (char *) NULL)
01005         (void) DeleteNodeFromSplayTree(temporary_resources,p);
01006     }
01007   (void) CopyMagickString(cache_path,path,MaxTextExtent);
01008   AppendImageFormat("cache",cache_path);
01009   (void) remove(cache_path);
01010   return(remove(path) == 0 ? MagickTrue : MagickFalse);
01011 }
01012 
01013 /*
01014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01015 %                                                                             %
01016 %                                                                             %
01017 %                                                                             %
01018 %   S e t M a g i c k R e s o u r c e L i m i t                               %
01019 %                                                                             %
01020 %                                                                             %
01021 %                                                                             %
01022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01023 %
01024 %  SetMagickResourceLimit() sets the limit for a particular resource.
01025 %
01026 %  The format of the SetMagickResourceLimit() method is:
01027 %
01028 %      MagickBooleanType SetMagickResourceLimit(const ResourceType type,
01029 %        const MagickSizeType limit)
01030 %
01031 %  A description of each parameter follows:
01032 %
01033 %    o type: the type of resource.
01034 %
01035 %    o limit: the maximum limit for the resource.
01036 %
01037 */
01038 MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
01039   const MagickSizeType limit)
01040 {
01041   AcquireSemaphoreInfo(&resource_semaphore);
01042   switch (type)
01043   {
01044     case AreaResource:
01045     {
01046       resource_info.area_limit=limit;
01047       break;
01048     }
01049     case MemoryResource:
01050     {
01051       resource_info.memory_limit=limit;
01052       break;
01053     }
01054     case MapResource:
01055     {
01056       resource_info.map_limit=limit;
01057       break;
01058     }
01059     case DiskResource:
01060     {
01061       resource_info.disk_limit=limit;
01062       break;
01063     }
01064     case FileResource:
01065     {
01066       resource_info.file_limit=limit;
01067       break;
01068     }
01069     case ThreadResource:
01070     {
01071       SetOpenMPMaximumThreads((unsigned long) limit);
01072       resource_info.thread_limit=GetOpenMPMaximumThreads();
01073       break;
01074     }
01075     case TimeResource:
01076     {
01077       resource_info.time_limit=limit;
01078       break;
01079     }
01080     default:
01081       break;
01082   }
01083   RelinquishSemaphoreInfo(resource_semaphore);
01084   return(MagickTrue);
01085 }

Generated on Thu Jul 2 12:03:21 2009 for MagickCore by  doxygen 1.5.8