WizardsToolkit  1.0.7
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 Wizard's Toolkit Resources.                       %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                               September 2002                                %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2011 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.wizards-toolkit.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 "wizard/studio.h"
00043 #include "wizard/exception.h"
00044 #include "wizard/exception-private.h"
00045 #include "wizard/hashmap.h"
00046 #include "wizard/log.h"
00047 #include "wizard/memory_.h"
00048 #include "wizard/option.h"
00049 #include "wizard/random_.h"
00050 #include "wizard/resource_.h"
00051 #include "wizard/semaphore.h"
00052 #include "wizard/signature.h"
00053 #include "wizard/splay-tree.h"
00054 #include "wizard/string_.h"
00055 #include "wizard/string-private.h"
00056 #include "wizard/token.h"
00057 #include "wizard/utility.h"
00058 #include "wizard/utility-private.h"
00059 
00060 /*
00061   Define  declarations.
00062 */
00063 #define WizardResourceInfinity  (~0UL)
00064 
00065 /*
00066   Typedef declarations.
00067 */
00068 typedef struct _ResourceInfo
00069 {
00070   WizardOffsetType
00071     area,
00072     memory,
00073     map,
00074     disk,
00075     file;
00076 
00077   WizardSizeType
00078     area_limit,
00079     memory_limit,
00080     map_limit,
00081     disk_limit,
00082     file_limit;
00083 } ResourceInfo;
00084 
00085 /*
00086   Global declarations.
00087 */
00088 static RandomInfo
00089   *random_info = (RandomInfo *) NULL;
00090 
00091 static ResourceInfo
00092   resource_info =
00093   {
00094     WizardULLConstant(0),
00095     WizardULLConstant(0),
00096     WizardULLConstant(0),
00097     WizardULLConstant(0),
00098     WizardULLConstant(0),
00099     WizardULLConstant(1536)*1024*1024/sizeof(void *),
00100     WizardULLConstant(1536)*1024*1024,
00101     WizardULLConstant(3072)*1024*1024,
00102     WizardResourceInfinity,
00103     WizardULLConstant(768)
00104   };
00105 
00106 static SemaphoreInfo
00107   *resource_semaphore = (SemaphoreInfo *) NULL;
00108 
00109 static SplayTreeInfo
00110   *temporary_resources = (SplayTreeInfo *) NULL;
00111 
00112 /*
00113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00114 %                                                                             %
00115 %                                                                             %
00116 %                                                                             %
00117 %   A c q u i r e U n i q u e F i l e n a m e                                 %
00118 %                                                                             %
00119 %                                                                             %
00120 %                                                                             %
00121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00122 %
00123 %  AcquireUniqueFilename() replaces the contents of path by a unique path name.
00124 %
00125 %  The format of the AcquireUniqueFilename method is:
00126 %
00127 %      WizardBooleanType AcquireUniqueFilename(char *path,Exception *exception)
00128 %
00129    A description of each parameter follows.
00130 %
00131 %   o  path:  Specifies a pointer to an array of characters.  The unique path
00132 %      name is returned in this array.
00133 %
00134 %    o exception: Return any errors or warnings in this structure.
00135 %
00136 */
00137 WizardExport WizardBooleanType AcquireUniqueFilename(char *path,
00138   ExceptionInfo *exception)
00139 {
00140   int
00141     file;
00142 
00143   file=AcquireUniqueFileResource("",path,exception);
00144   if (file == -1)
00145     return(WizardFalse);
00146   if (close(file) == -1)
00147     (void) ThrowWizardException(exception,GetWizardModule(),ResourceError,
00148       "unable to close file `%s': %s",path,strerror(errno));
00149   return(WizardTrue);
00150 }
00151 
00152 /*
00153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00154 %                                                                             %
00155 %                                                                             %
00156 %                                                                             %
00157 %   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                         %
00158 %                                                                             %
00159 %                                                                             %
00160 %                                                                             %
00161 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00162 %
00163 %  AcquireUniqueFileResource() returns a unique file name, and returns a file
00164 %  descriptor for the file open for reading and writing.
00165 %
00166 %  The format of the AcquireUniqueFileResource() method is:
00167 %
00168 %      int AcquireUniqueFileResource(const char *path,char *filename,
00169 %        ExceptionInfo *exception)
00170 %
00171 %  A description of each parameter follows:
00172 %
00173 %   o  path:  Open the file in this directory path.
00174 %
00175 %   o  filename:  The unique filename is returned in this array.
00176 %
00177 %    o exception: Return any errors or warnings in this structure.
00178 %
00179 */
00180 
00181 static void *DestroyTemporaryResources(void *temporary_resource)
00182 {
00183   remove_utf8((char *) temporary_resource);
00184   temporary_resource=DestroyString((char *) temporary_resource);
00185   return((void *) NULL);
00186 }
00187 
00188 static WizardBooleanType GetPathTemplate(const char *path,char *filename)
00189 {
00190   char
00191     *directory;
00192 
00193   int
00194     status;
00195 
00196   register char
00197     *p;
00198 
00199   struct stat
00200     file_info;
00201 
00202   (void) CopyWizardString(filename,"wizard-XXXXXXXX",MaxTextExtent);
00203   if (*path != '\0')
00204     directory=ConstantString(path);
00205   else
00206     {
00207       directory=GetEnvironmentValue("WIZARD_TMPDIR");
00208       if (directory == (char *) NULL)
00209         directory=GetEnvironmentValue("TMPDIR");
00210 #if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00211       if (directory == (char *) NULL)
00212         directory=GetEnvironmentValue("TMP");
00213       if (directory == (char *) NULL)
00214         directory=GetEnvironmentValue("TEMP");
00215 #endif
00216 #if defined(P_tmpdir)
00217       if (directory == (char *) NULL)
00218         directory=ConstantString(P_tmpdir);
00219 #endif
00220       if (directory == (char *) NULL)
00221         return(WizardTrue);
00222     }
00223   if (strlen(directory) > (MaxTextExtent-15))
00224     {
00225       directory=(char *) RelinquishWizardMemory(directory);
00226       return(WizardTrue);
00227     }
00228   status=stat_utf8(directory,&file_info);
00229   if ((status != 0) || !S_ISDIR(file_info.st_mode))
00230     {
00231       directory=(char *) RelinquishWizardMemory(directory);
00232       return(WizardTrue);
00233     }
00234   if (directory[strlen(directory)-1] == *DirectorySeparator)
00235     (void) FormatLocaleString(filename,MaxTextExtent,"%swizard-XXXXXXXX",
00236       directory);
00237   else
00238     (void) FormatLocaleString(filename,MaxTextExtent,"%s%swizard-XXXXXXXX",
00239       directory,DirectorySeparator);
00240   directory=(char *) RelinquishWizardMemory(directory);
00241   if (*DirectorySeparator != '/')
00242     for (p=filename; *p != '\0'; p++)
00243       if (*p == *DirectorySeparator)
00244         *p='/';
00245   return(WizardTrue);
00246 }
00247 
00248 WizardExport int AcquireUniqueFileResource(const char *path,char *filename,
00249   ExceptionInfo *exception)
00250 {
00251 #if !defined(O_NOFOLLOW)
00252 #define O_NOFOLLOW 0
00253 #endif
00254 #if !defined(TMP_MAX)
00255 # define TMP_MAX  238328
00256 #endif
00257 
00258   int
00259     c,
00260     file;
00261 
00262   register char
00263     *p;
00264 
00265   register ssize_t
00266     i;
00267 
00268   static const char
00269     portable_filename[] =
00270       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
00271 
00272   StringInfo
00273     *key;
00274 
00275   unsigned char
00276     *datum;
00277 
00278   WizardAssert(ResourceDomain,path != (const char *) NULL);
00279   WizardAssert(ResourceDomain,filename != (char *) NULL);
00280   (void) LogWizardEvent(ResourceEvent,GetWizardModule(),"%s",path);
00281   if (random_info == (RandomInfo *) NULL)
00282     random_info=AcquireRandomInfo(SHA256Hash);
00283   file=(-1);
00284   for (i=0; i < (ssize_t) TMP_MAX; i++)
00285   {
00286     /*
00287       Get temporary pathname.
00288     */
00289     (void) GetPathTemplate(path,filename);
00290     key=GetRandomKey(random_info,2);
00291     p=filename+strlen(filename)-8;
00292     datum=GetStringInfoDatum(key);
00293     for (i=0; i < (ssize_t) GetStringInfoLength(key); i++)
00294     {
00295       c=(int) (datum[i] & 0x3f);
00296       *p++=portable_filename[c];
00297     }
00298     key=DestroyStringInfo(key);
00299 #if defined(WIZARDSTOOLKIT_HAVE_MKSTEMP)
00300     file=mkstemp(filename);
00301 #if defined(__OS2__)
00302     setmode(file,O_BINARY);
00303 #endif
00304     if (file != -1)
00305       break;
00306 #endif
00307     key=GetRandomKey(random_info,6);
00308     p=filename+strlen(filename)-6;
00309     datum=GetStringInfoDatum(key);
00310     for (i=0; i < (ssize_t) GetStringInfoLength(key); i++)
00311     {
00312       c=(int) (datum[i] & 0x3f);
00313       *p++=portable_filename[c];
00314     }
00315     key=DestroyStringInfo(key);
00316     file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY | O_NOFOLLOW,
00317       S_MODE);
00318     if ((file >= 0) || (errno != EEXIST))
00319       break;
00320   }
00321   (void) LogWizardEvent(ResourceEvent,GetWizardModule(),"%s",filename);
00322   if (file == -1)
00323     return(file);
00324   if (AcquireWizardResource(FileResource,1) == WizardFalse)
00325     {
00326       if (close(file) == -1)
00327         (void) ThrowWizardException(exception,GetWizardModule(),ResourceError,
00328           "unable to close file `%s': %s",filename,strerror(errno));
00329       if (remove_utf8(path) == -1)
00330         (void) ThrowWizardException(exception,GetWizardModule(),ResourceError,
00331           "unable to remove file `%s': %s",filename,strerror(errno));
00332       return(-1);
00333     }
00334   if (resource_semaphore == (SemaphoreInfo *) NULL)
00335     AcquireSemaphoreInfo(&resource_semaphore);
00336   LockSemaphoreInfo(resource_semaphore);
00337   if (temporary_resources == (SplayTreeInfo *) NULL)
00338     temporary_resources=NewSplayTree(CompareSplayTreeString,
00339       DestroyTemporaryResources,(void *(*)(void *)) NULL);
00340   UnlockSemaphoreInfo(resource_semaphore);
00341   (void) AddValueToSplayTree(temporary_resources,ConstantString(filename),
00342     (const void *) NULL);
00343   return(file);
00344 }
00345 
00346 /*
00347 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00348 %                                                                             %
00349 %                                                                             %
00350 %                                                                             %
00351 %   A c q u i r e W i z a r d R e s o u r c e                                 %
00352 %                                                                             %
00353 %                                                                             %
00354 %                                                                             %
00355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00356 %
00357 %  AcquireWizardResource() acquires resources of the specified type.
00358 %  WizardFalse is returned if the specified resource is exhausted otherwise
00359 %  WizardTrue.
00360 %
00361 %  The format of the AcquireWizardResource() method is:
00362 %
00363 %      WizardBooleanType AcquireWizardResource(const ResourceType type,
00364 %        const WizardSizeType size)
00365 %
00366 %  A description of each parameter follows:
00367 %
00368 %    o type: The type of resource.
00369 %
00370 %    o size: The number of bytes needed from for this resource.
00371 %
00372 */
00373 WizardExport WizardBooleanType AcquireWizardResource(const ResourceType type,
00374   const WizardSizeType size)
00375 {
00376   char
00377     resource_current[MaxTextExtent],
00378     resource_limit[MaxTextExtent],
00379     resource_request[MaxTextExtent];
00380 
00381   WizardBooleanType
00382     status;
00383 
00384   WizardSizeType
00385     limit;
00386 
00387   status=WizardFalse;
00388   (void) FormatWizardSize(size,WizardFalse,resource_request);
00389   if (resource_semaphore == (SemaphoreInfo *) NULL)
00390     AcquireSemaphoreInfo(&resource_semaphore);
00391   LockSemaphoreInfo(resource_semaphore);
00392   switch (type)
00393   {
00394     case AreaResource:
00395     {
00396       resource_info.area=(WizardOffsetType) size;
00397       limit=resource_info.area_limit;
00398       status=(resource_info.area_limit == WizardResourceInfinity) ||
00399         (size < limit) ? WizardTrue : WizardFalse;
00400       (void) FormatWizardSize((WizardSizeType) resource_info.area,WizardFalse,
00401         resource_current);
00402       (void) FormatWizardSize(resource_info.area_limit,WizardFalse,
00403         resource_limit);
00404       break;
00405     }
00406     case MemoryResource:
00407     {
00408       resource_info.memory+=size;
00409       limit=resource_info.memory_limit;
00410       status=(resource_info.memory_limit == WizardResourceInfinity) ||
00411         ((WizardSizeType) resource_info.memory < limit) ?
00412         WizardTrue : WizardFalse;
00413       (void) FormatWizardSize((WizardSizeType) resource_info.memory,WizardTrue,
00414         resource_current);
00415       (void) FormatWizardSize(resource_info.memory_limit,WizardTrue,
00416         resource_limit);
00417       break;
00418     }
00419     case MapResource:
00420     {
00421       resource_info.map+=size;
00422       limit=resource_info.map_limit;
00423       status=(resource_info.map_limit == WizardResourceInfinity) ||
00424         ((WizardSizeType) resource_info.map < limit) ?
00425         WizardTrue : WizardFalse;
00426       (void) FormatWizardSize((WizardSizeType) resource_info.map,WizardTrue,
00427         resource_current);
00428       (void) FormatWizardSize(resource_info.map_limit,WizardTrue,
00429         resource_limit);
00430       break;
00431     }
00432     case DiskResource:
00433     {
00434       resource_info.disk+=size;
00435       limit=resource_info.disk_limit;
00436       status=(resource_info.disk_limit == WizardResourceInfinity) ||
00437         ((WizardSizeType) resource_info.disk < limit) ?
00438         WizardTrue : WizardFalse;
00439       (void) FormatWizardSize((WizardSizeType) resource_info.disk,WizardTrue,
00440         resource_current);
00441       (void) FormatWizardSize(resource_info.disk_limit,WizardTrue,
00442         resource_limit);
00443       break;
00444     }
00445     case FileResource:
00446     {
00447       resource_info.file+=size;
00448       limit=resource_info.file_limit;
00449       status=(resource_info.file_limit == WizardResourceInfinity) ||
00450         ((WizardSizeType) resource_info.file < limit) ?
00451         WizardTrue : WizardFalse;
00452       (void) FormatWizardSize((WizardSizeType) resource_info.file,WizardFalse,
00453         resource_current);
00454       (void) FormatWizardSize((WizardSizeType) resource_info.file_limit,
00455         WizardFalse,resource_limit);
00456       break;
00457     }
00458     default:
00459       break;
00460   }
00461   UnlockSemaphoreInfo(resource_semaphore);
00462   (void) LogWizardEvent(ResourceEvent,GetWizardModule(),"%s: %s/%s/%s",
00463     WizardOptionToMnemonic(WizardResourceOptions,(ssize_t) type),
00464     resource_request,resource_current,resource_limit);
00465   return(status);
00466 }
00467 
00468 /*
00469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00470 %                                                                             %
00471 %                                                                             %
00472 %                                                                             %
00473 +   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 %
00474 %                                                                             %
00475 %                                                                             %
00476 %                                                                             %
00477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00478 %
00479 %  AsynchronousResourceComponentTerminus() destroys the resource environment.
00480 %  It differs from ResourceComponentTerminus() in that it can be called from a
00481 %  asynchronous signal handler.
00482 %
00483 %  The format of the ResourceComponentTerminus() method is:
00484 %
00485 %      ResourceComponentTerminus(void)
00486 %
00487 */
00488 WizardExport void AsynchronousResourceComponentTerminus(void)
00489 {
00490   const char
00491     *path;
00492 
00493   if (temporary_resources == (SplayTreeInfo *) NULL)
00494     return;
00495   /*
00496     Remove any lingering temporary files.
00497   */
00498   ResetSplayTreeIterator(temporary_resources);
00499   path=(const char *) GetNextKeyInSplayTree(temporary_resources);
00500   while (path != (const char *) NULL)
00501   {
00502     (void) remove_utf8(path);
00503     path=(const char *) GetNextKeyInSplayTree(temporary_resources);
00504   }
00505   if (random_info != (RandomInfo *) NULL)
00506     random_info=DestroyRandomInfo(random_info);
00507 }
00508 
00509 /*
00510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00511 %                                                                             %
00512 %                                                                             %
00513 %                                                                             %
00514 %   G e t W i z a r d R e s o u r c e                                         %
00515 %                                                                             %
00516 %                                                                             %
00517 %                                                                             %
00518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00519 %
00520 %  GetWizardResource() returns the the specified resource in megabytes.
00521 %
00522 %  The format of the GetWizardResource() method is:
00523 %
00524 %      WizardSizeType GetWizardResource(const ResourceType type)
00525 %
00526 %  A description of each parameter follows:
00527 %
00528 %    o type: The type of resource.
00529 %
00530 */
00531 WizardExport WizardSizeType GetWizardResource(const ResourceType type)
00532 {
00533   WizardSizeType
00534     resource;
00535 
00536   resource=0;
00537   if (resource_semaphore == (SemaphoreInfo *) NULL)
00538     AcquireSemaphoreInfo(&resource_semaphore);
00539   LockSemaphoreInfo(resource_semaphore);
00540   switch (type)
00541   {
00542     case AreaResource:
00543     {
00544       resource=(WizardSizeType) resource_info.area;
00545       break;
00546     }
00547     case MemoryResource:
00548     {
00549       resource=(WizardSizeType) resource_info.memory;
00550       break;
00551     }
00552     case MapResource:
00553     {
00554       resource=(WizardSizeType) resource_info.map;
00555       break;
00556     }
00557     case DiskResource:
00558     {
00559       resource=(WizardSizeType) resource_info.disk;
00560       break;
00561     }
00562     case FileResource:
00563     {
00564       resource=(WizardSizeType) resource_info.file;
00565       break;
00566     }
00567     default:
00568       break;
00569   }
00570   UnlockSemaphoreInfo(resource_semaphore);
00571   return(resource);
00572 }
00573 
00574 /*
00575 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00576 %                                                                             %
00577 %                                                                             %
00578 %                                                                             %
00579 %   G e t W i z a r d R e s o u r c e L i m i t                               %
00580 %                                                                             %
00581 %                                                                             %
00582 %                                                                             %
00583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00584 %
00585 %  GetWizardResourceLimit() returns the the specified resource limit in
00586 %  megabytes.
00587 %
00588 %  The format of the GetWizardResourceLimit() method is:
00589 %
00590 %      size_t GetWizardResourceLimit(const ResourceType type)
00591 %
00592 %  A description of each parameter follows:
00593 %
00594 %    o type: The type of resource.
00595 %
00596 */
00597 WizardExport WizardSizeType GetWizardResourceLimit(const ResourceType type)
00598 {
00599   WizardSizeType
00600     resource;
00601 
00602   resource=0;
00603   if (resource_semaphore == (SemaphoreInfo *) NULL)
00604     AcquireSemaphoreInfo(&resource_semaphore);
00605   LockSemaphoreInfo(resource_semaphore);
00606   switch (type)
00607   {
00608     case AreaResource:
00609     {
00610       resource=(WizardSizeType) resource_info.area_limit;
00611       break;
00612     }
00613     case MemoryResource:
00614     {
00615       resource=(WizardSizeType) resource_info.memory_limit;
00616       break;
00617     }
00618     case MapResource:
00619     {
00620       resource=(WizardSizeType) resource_info.map_limit;
00621       break;
00622     }
00623     case DiskResource:
00624     {
00625       resource=(WizardSizeType) resource_info.disk_limit;
00626       break;
00627     }
00628     case FileResource:
00629     {
00630       resource=(WizardSizeType) resource_info.file_limit;
00631       break;
00632     }
00633     default:
00634       break;
00635   }
00636   UnlockSemaphoreInfo(resource_semaphore);
00637   return(resource);
00638 }
00639 
00640 /*
00641 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00642 %                                                                             %
00643 %                                                                             %
00644 %                                                                             %
00645 %  L i s t W i z a r d R e s o u r c e I n f o                                %
00646 %                                                                             %
00647 %                                                                             %
00648 %                                                                             %
00649 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00650 %
00651 %  ListWizardResourceInfo() lists the resource info to a file.
00652 %
00653 %  The format of the ListWizardResourceInfo method is:
00654 %
00655 %      WizardBooleanType ListWizardResourceInfo(FILE *file,
00656 %        ExceptionInfo *exception)
00657 %
00658 %  A description of each parameter follows.
00659 %
00660 %    o file:  An pointer to a FILE.
00661 %
00662 %    o exception: Return any errors or warnings in this structure.
00663 %
00664 */
00665 WizardExport WizardBooleanType ListWizardResourceInfo(FILE *file,
00666   ExceptionInfo *wizard_unused(exception))
00667 {
00668   char
00669     area_limit[MaxTextExtent],
00670     disk_limit[MaxTextExtent],
00671     map_limit[MaxTextExtent],
00672     memory_limit[MaxTextExtent];
00673 
00674   if (file == (const FILE *) NULL)
00675     file=stdout;
00676   if (resource_semaphore == (SemaphoreInfo *) NULL)
00677     AcquireSemaphoreInfo(&resource_semaphore);
00678   LockSemaphoreInfo(resource_semaphore);
00679   (void) FormatWizardSize(resource_info.area_limit,WizardFalse,area_limit);
00680   (void) FormatWizardSize(resource_info.map_limit,WizardTrue,map_limit);
00681   (void) FormatWizardSize(resource_info.memory_limit,WizardTrue,memory_limit);
00682   (void) CopyWizardString(disk_limit,"unlimited",MaxTextExtent);
00683   if (resource_info.disk_limit != WizardResourceInfinity)
00684     (void) FormatWizardSize(resource_info.disk_limit,WizardTrue,disk_limit);
00685   (void) fprintf(file,"File        Area      Memory         Map        Disk\n");
00686   (void) fprintf(file,"----------------------------------------------------\n");
00687   (void) fprintf(file,"%4g   %9s   %9s   %9s   %9s\n",(double)
00688     resource_info.file_limit,area_limit,memory_limit,map_limit,disk_limit);
00689   (void) fflush(file);
00690   UnlockSemaphoreInfo(resource_semaphore);
00691   return(WizardTrue);
00692 }
00693 
00694 /*
00695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00696 %                                                                             %
00697 %                                                                             %
00698 %                                                                             %
00699 %   R e l i n q u i s h W i z a r d R e s o u r c e                           %
00700 %                                                                             %
00701 %                                                                             %
00702 %                                                                             %
00703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00704 %
00705 %  RelinquishWizardResource() relinquishes resources of the specified type.
00706 %
00707 %  The format of the RelinquishWizardResource() method is:
00708 %
00709 %      void RelinquishWizardResource(const ResourceType type,
00710 %        const WizardSizeType size)
00711 %
00712 %  A description of each parameter follows:
00713 %
00714 %    o type: The type of resource.
00715 %
00716 %    o size: The size of the resource.
00717 %
00718 */
00719 WizardExport void RelinquishWizardResource(const ResourceType type,
00720   const WizardSizeType size)
00721 {
00722   char
00723     resource_current[MaxTextExtent],
00724     resource_limit[MaxTextExtent],
00725     resource_request[MaxTextExtent];
00726 
00727   (void) FormatWizardSize(size,WizardFalse,resource_request);
00728   if (resource_semaphore == (SemaphoreInfo *) NULL)
00729     AcquireSemaphoreInfo(&resource_semaphore);
00730   LockSemaphoreInfo(resource_semaphore);
00731   switch (type)
00732   {
00733     case AreaResource:
00734     {
00735       resource_info.area=(WizardOffsetType) size;
00736       (void) FormatWizardSize((WizardSizeType) resource_info.area,
00737         WizardFalse,resource_current);
00738       (void) FormatWizardSize(resource_info.area_limit,
00739         WizardFalse,resource_limit);
00740       break;
00741     }
00742     case MemoryResource:
00743     {
00744       resource_info.memory-=size;
00745       (void) FormatWizardSize((WizardSizeType) resource_info.memory,WizardTrue,
00746         resource_current);
00747       (void) FormatWizardSize(resource_info.memory_limit,WizardTrue,
00748         resource_limit);
00749       break;
00750     }
00751     case MapResource:
00752     {
00753       resource_info.map-=size;
00754       (void) FormatWizardSize((WizardSizeType) resource_info.map,WizardTrue,
00755         resource_current);
00756       (void) FormatWizardSize(resource_info.map_limit,WizardTrue,
00757         resource_limit);
00758       break;
00759     }
00760     case DiskResource:
00761     {
00762       resource_info.disk-=size;
00763       (void) FormatWizardSize((WizardSizeType) resource_info.disk,WizardTrue,
00764         resource_current);
00765       (void) FormatWizardSize(resource_info.disk_limit,WizardTrue,
00766         resource_limit);
00767       break;
00768     }
00769     case FileResource:
00770     {
00771       resource_info.file-=size;
00772       (void) FormatWizardSize((WizardSizeType) resource_info.file,WizardFalse,
00773         resource_current);
00774       (void) FormatWizardSize((WizardSizeType) resource_info.file_limit,
00775         WizardFalse,resource_limit);
00776       break;
00777     }
00778     default:
00779       break;
00780   }
00781   UnlockSemaphoreInfo(resource_semaphore);
00782   (void) LogWizardEvent(ResourceEvent,GetWizardModule(),"%s: %s/%s/%s",
00783     WizardOptionToMnemonic(WizardResourceOptions,(ssize_t) type),
00784     resource_request,resource_current,resource_limit);
00785 }
00786 
00787 /*
00788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00789 %                                                                             %
00790 %                                                                             %
00791 %                                                                             %
00792 %    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                  %
00793 %                                                                             %
00794 %                                                                             %
00795 %                                                                             %
00796 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00797 %
00798 %  RelinquishUniqueFileResource() relinquishes a unique file resource.
00799 %
00800 %  The format of the RelinquishUniqueFileResource() method is:
00801 %
00802 %      WizardBooleanType RelinquishUniqueFileResource(const char *path,
00803 %        const WizardBooleanType trash))
00804 %
00805 %  A description of each parameter follows:
00806 %
00807 %    o name: the name of the temporary resource.
00808 %
00809 %    o trash: a value other than 0 trashs the file at the specified path.
00810 %
00811 */
00812 WizardExport WizardBooleanType RelinquishUniqueFileResource(const char *path,
00813   const WizardBooleanType trash)
00814 {
00815   WizardAssert(ResourceDomain,path != (const char *) NULL);
00816   (void) LogWizardEvent(ResourceEvent,GetWizardModule(),"%s",path);
00817   if (temporary_resources != (SplayTreeInfo *) NULL)
00818     {
00819       register char
00820         *p;
00821 
00822       ResetSplayTreeIterator(temporary_resources);
00823       p=(char *) GetNextKeyInSplayTree(temporary_resources);
00824       while (p != (char *) NULL)
00825       {
00826         if (LocaleCompare(p,path) == 0)
00827           break;
00828         p=(char *) GetNextKeyInSplayTree(temporary_resources);
00829       }
00830       if (p != (char *) NULL)
00831         (void) DeleteNodeFromSplayTree(temporary_resources,p);
00832     }
00833   if (trash == WizardFalse)
00834     return(WizardTrue);
00835   return(remove_utf8(path) == 0 ? WizardTrue : WizardFalse);
00836 }
00837 
00838 /*
00839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00840 %                                                                             %
00841 %                                                                             %
00842 %                                                                             %
00843 +   R e s o u r c e C o m p o n e n t G e n e s i s                           %
00844 %                                                                             %
00845 %                                                                             %
00846 %                                                                             %
00847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00848 %
00849 %  ResourceComponentGenesis() instantiates the resource component.
00850 %
00851 %  The format of the ResourceComponentGenesis method is:
00852 %
00853 %      WizardBooleanType ResourceComponentGenesis(void)
00854 %
00855 */
00856 
00857 static inline ssize_t WizardMax(const ssize_t x,const ssize_t y)
00858 {
00859   if (x > y)
00860     return(x);
00861   return(y);
00862 }
00863 
00864 WizardExport WizardBooleanType ResourceComponentGenesis(void)
00865 {
00866   char
00867     *limit;
00868 
00869   ssize_t
00870     files,
00871     pages,
00872     pagesize;
00873 
00874   size_t
00875     memory;
00876 
00877   /*
00878     Set Wizard resource limits.
00879   */
00880   AcquireSemaphoreInfo(&resource_semaphore);
00881   pagesize=(-1);
00882 #if defined(WIZARDSTOOLKIT_HAVE_SYSCONF) && defined(_SC_PAGESIZE)
00883   pagesize=sysconf(_SC_PAGESIZE);
00884 #elif defined(WIZARDSTOOLKIT_HAVE_GETPAGESIZE) && defined(POSIX)
00885   pagesize=getpagesize();
00886 #endif
00887   pages=(-1);
00888 #if defined(WIZARDSTOOLKIT_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
00889   pages=sysconf(_SC_PHYS_PAGES);
00890 #endif
00891   memory=(size_t) ((pages+512)/1024)*((pagesize+512)/1024);
00892   if ((pagesize <= 0) || (pages <= 0))
00893     memory=2048UL;
00894 #if defined(PixelCacheThreshold)
00895   memory=PixelCacheThreshold;
00896 #endif
00897   (void) SetWizardResourceLimit(AreaResource,memory/sizeof(void *));
00898   (void) SetWizardResourceLimit(MemoryResource,memory);
00899   (void) SetWizardResourceLimit(MapResource,2*memory);
00900   limit=GetEnvironmentValue("WIZARD_AREA_LIMIT");
00901   if (limit != (char *) NULL)
00902     {
00903       (void) SetWizardResourceLimit(AreaResource,StringToUnsignedLong(limit));
00904       limit=DestroyString(limit);
00905     }
00906   limit=GetEnvironmentValue("WIZARD_MEMORY_LIMIT");
00907   if (limit != (char *) NULL)
00908     {
00909       (void) SetWizardResourceLimit(MemoryResource,StringToUnsignedLong(limit));
00910       limit=DestroyString(limit);
00911     }
00912   limit=GetEnvironmentValue("WIZARD_MAP_LIMIT");
00913   if (limit != (char *) NULL)
00914     {
00915       (void) SetWizardResourceLimit(MapResource,StringToUnsignedLong(limit));
00916       limit=DestroyString(limit);
00917     }
00918   limit=GetEnvironmentValue("WIZARD_DISK_LIMIT");
00919   if (limit != (char *) NULL)
00920     {
00921       (void) SetWizardResourceLimit(DiskResource,StringToUnsignedLong(limit));
00922       limit=DestroyString(limit);
00923     }
00924   files=(-1);
00925 #if defined(WIZARDSTOOLKIT_HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
00926   files=sysconf(_SC_OPEN_MAX);
00927 #elif defined(WIZARDSTOOLKIT_HAVE_GETDTABLESIZE) && defined(POSIX)
00928   files=getdtablesize();
00929 #endif
00930   (void) SetWizardResourceLimit(FileResource,(size_t)
00931     WizardMax(3L*files/4L,64L));
00932   limit=GetEnvironmentValue("WIZARD_FILE_LIMIT");
00933   if (limit != (char *) NULL)
00934     {
00935       (void) SetWizardResourceLimit(FileResource,StringToUnsignedLong(limit));
00936       limit=DestroyString(limit);
00937     }
00938   return(WizardTrue);
00939 }
00940 
00941 /*
00942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00943 %                                                                             %
00944 %                                                                             %
00945 %                                                                             %
00946 +   R e s o u r c e C o m p o n e n t G e n e s i s                           %
00947 %                                                                             %
00948 %                                                                             %
00949 %                                                                             %
00950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00951 %
00952 %  ResourceComponentTerminus() destroys the resource component.
00953 %
00954 %  The format of the ResourceComponentTerminus() method is:
00955 %
00956 %      ResourceComponentTerminus(void)
00957 %
00958 */
00959 WizardExport void ResourceComponentTerminus(void)
00960 {
00961   if (resource_semaphore == (SemaphoreInfo *) NULL)
00962     AcquireSemaphoreInfo(&resource_semaphore);
00963   LockSemaphoreInfo(resource_semaphore);
00964   if (temporary_resources != (SplayTreeInfo *) NULL)
00965     temporary_resources=DestroySplayTree(temporary_resources);
00966   UnlockSemaphoreInfo(resource_semaphore);
00967   DestroySemaphoreInfo(&resource_semaphore);
00968 }
00969 
00970 /*
00971 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00972 %                                                                             %
00973 %                                                                             %
00974 %                                                                             %
00975 %   S e t W i z a r d R e s o u r c e L i m i t                               %
00976 %                                                                             %
00977 %                                                                             %
00978 %                                                                             %
00979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00980 %
00981 %  SetWizardResourceLimit() sets the limit for a particular resource in bytes.
00982 %
00983 %  The format of the SetWizardResourceLimit() method is:
00984 %
00985 %      WizardBooleanType SetWizardResourceLimit(const ResourceType type,
00986 %        const WizardResourceType limit)
00987 %
00988 %  A description of each parameter follows:
00989 %
00990 %    o type: The type of resource.
00991 %
00992 %    o limit: The maximum limit for the resource.
00993 %
00994 */
00995 WizardExport WizardBooleanType SetWizardResourceLimit(const ResourceType type,
00996   const WizardSizeType limit)
00997 {
00998   if (resource_semaphore == (SemaphoreInfo *) NULL)
00999     AcquireSemaphoreInfo(&resource_semaphore);
01000   LockSemaphoreInfo(resource_semaphore);
01001   switch (type)
01002   {
01003     case AreaResource:
01004     {
01005       resource_info.area_limit=limit;
01006       break;
01007     }
01008     case MemoryResource:
01009     {
01010       resource_info.memory_limit=limit;
01011       break;
01012     }
01013     case MapResource:
01014     {
01015       resource_info.map_limit=limit;
01016       break;
01017     }
01018     case DiskResource:
01019     {
01020       resource_info.disk_limit=limit;
01021       break;
01022     }
01023     case FileResource:
01024     {
01025       resource_info.file_limit=limit;
01026       break;
01027     }
01028     default:
01029       break;
01030   }
01031   UnlockSemaphoreInfo(resource_semaphore);
01032   return(WizardTrue);
01033 }