]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/resource.c
(no commit message)
[imagemagick] / MagickCore / resource.c
index 1a679d82ac1273ffe9d2d6facb6266273fa7187f..b28af7d478f17b56e901d770ded5ff4e9658cefa 100644 (file)
 %                        Get/Set MagickCore Resources                         %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                               September 2002                                %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -48,6 +48,7 @@
 #include "MagickCore/log.h"
 #include "MagickCore/image.h"
 #include "MagickCore/memory_.h"
+#include "MagickCore/nt-base-private.h"
 #include "MagickCore/option.h"
 #include "MagickCore/policy.h"
 #include "MagickCore/random_.h"
@@ -76,6 +77,7 @@ typedef struct _ResourceInfo
     disk,
     file,
     thread,
+    throttle,
     time;
 
   MagickSizeType
@@ -85,6 +87,7 @@ typedef struct _ResourceInfo
     disk_limit,
     file_limit,
     thread_limit,
+    throttle_limit,
     time_limit;
 } ResourceInfo;
 \f
@@ -97,20 +100,22 @@ static RandomInfo
 static ResourceInfo
   resource_info =
   {
-    MagickULLConstant(0),
-    MagickULLConstant(0),
-    MagickULLConstant(0),
-    MagickULLConstant(0),
-    MagickULLConstant(0),
-    MagickULLConstant(0),
-    MagickULLConstant(0),
-    MagickULLConstant(3072)*1024*1024,
-    MagickULLConstant(1536)*1024*1024,
-    MagickULLConstant(3072)*1024*1024,
-    MagickResourceInfinity,
-    MagickULLConstant(768),
-    MagickULLConstant(1),
-    MagickResourceInfinity
+    MagickULLConstant(0),              /* initial area */
+    MagickULLConstant(0),              /* initial memory */
+    MagickULLConstant(0),              /* initial map */
+    MagickULLConstant(0),              /* initial disk */
+    MagickULLConstant(0),              /* initial file */
+    MagickULLConstant(0),              /* initial thread */
+    MagickULLConstant(0),              /* initial throttle */
+    MagickULLConstant(0),              /* initial time */
+    MagickULLConstant(3072)*1024*1024, /* area limit */
+    MagickULLConstant(1536)*1024*1024, /* memory limit */
+    MagickULLConstant(3072)*1024*1024, /* map limit */
+    MagickResourceInfinity,            /* disk limit */
+    MagickULLConstant(768),            /* file limit */
+    MagickULLConstant(1),              /* thread limit */
+    MagickULLConstant(0),              /* throttle limit */
+    MagickResourceInfinity             /* time limit */
   };
 
 static SemaphoreInfo
@@ -163,7 +168,7 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
   status=MagickFalse;
   (void) FormatMagickSize(size,MagickFalse,resource_request);
   if (resource_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&resource_semaphore);
+    ActivateSemaphoreInfo(&resource_semaphore);
   LockSemaphoreInfo(resource_semaphore);
   switch (type)
   {
@@ -184,8 +189,8 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
       resource_info.memory+=size;
       limit=resource_info.memory_limit;
       status=(resource_info.memory_limit == MagickResourceInfinity) ||
-        ((MagickSizeType) resource_info.memory < limit) ?
-        MagickTrue : MagickFalse;
+        ((MagickSizeType) resource_info.memory < limit) ? MagickTrue :
+        MagickFalse;
       (void) FormatMagickSize((MagickSizeType) resource_info.memory,MagickTrue,
         resource_current);
       (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,
@@ -197,8 +202,7 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
       resource_info.map+=size;
       limit=resource_info.map_limit;
       status=(resource_info.map_limit == MagickResourceInfinity) ||
-        ((MagickSizeType) resource_info.map < limit) ?
-        MagickTrue : MagickFalse;
+        ((MagickSizeType) resource_info.map < limit) ? MagickTrue : MagickFalse;
       (void) FormatMagickSize((MagickSizeType) resource_info.map,MagickTrue,
         resource_current);
       (void) FormatMagickSize(resource_info.map_limit,MagickTrue,
@@ -210,8 +214,8 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
       resource_info.disk+=size;
       limit=resource_info.disk_limit;
       status=(resource_info.disk_limit == MagickResourceInfinity) ||
-        ((MagickSizeType) resource_info.disk < limit) ?
-        MagickTrue : MagickFalse;
+        ((MagickSizeType) resource_info.disk < limit) ? MagickTrue :
+        MagickFalse;
       (void) FormatMagickSize((MagickSizeType) resource_info.disk,MagickTrue,
         resource_current);
       (void) FormatMagickSize(resource_info.disk_limit,MagickTrue,
@@ -243,6 +247,18 @@ MagickExport MagickBooleanType AcquireMagickResource(const ResourceType type,
         MagickFalse,resource_limit);
       break;
     }
+    case ThrottleResource:
+    {
+      limit=resource_info.throttle_limit;
+      status=(resource_info.throttle_limit == MagickResourceInfinity) ||
+        ((MagickSizeType) resource_info.throttle < limit) ?
+        MagickTrue : MagickFalse;
+      (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
+        MagickFalse,resource_current);
+      (void) FormatMagickSize((MagickSizeType) resource_info.throttle_limit,
+        MagickFalse,resource_limit);
+      break;
+    }
     case TimeResource:
     {
       resource_info.time+=size;
@@ -300,7 +316,7 @@ MagickPrivate void AsynchronousResourceComponentTerminus(void)
   path=(const char *) GetNextKeyInSplayTree(temporary_resources);
   while (path != (const char *) NULL)
   {
-    (void) remove_utf8(path);
+    (void) ShredFile(path);
     path=(const char *) GetNextKeyInSplayTree(temporary_resources);
   }
 }
@@ -332,12 +348,12 @@ MagickPrivate void AsynchronousResourceComponentTerminus(void)
 
 static void *DestroyTemporaryResources(void *temporary_resource)
 {
-  (void) remove_utf8((char *) temporary_resource);
+  (void) ShredFile((char *) temporary_resource);
   temporary_resource=DestroyString((char *) temporary_resource);
   return((void *) NULL);
 }
 
-static MagickBooleanType GetPathTemplate(char *path)
+MagickExport MagickBooleanType GetPathTemplate(char *path)
 {
   char
     *directory,
@@ -349,9 +365,6 @@ static MagickBooleanType GetPathTemplate(char *path)
   MagickBooleanType
     status;
 
-  register char
-    *p;
-
   struct stat
     attributes;
 
@@ -401,13 +414,24 @@ static MagickBooleanType GetPathTemplate(char *path)
     (void) FormatLocaleString(path,MaxTextExtent,"%smagick-%.20gXXXXXXXXXXXX",
       directory,(double) getpid());
   else
-    (void) FormatLocaleString(path,MaxTextExtent,"%s%smagick-%.20gXXXXXXXXXXXX",
-      directory,DirectorySeparator,(double) getpid());
+    (void) FormatLocaleString(path,MaxTextExtent,
+      "%s%smagick-%.20gXXXXXXXXXXXX",directory,DirectorySeparator,
+      (double) getpid());
   directory=DestroyString(directory);
-  if (*DirectorySeparator != '/')
-    for (p=path; *p != '\0'; p++)
+#if defined(MAGICKCORE_WINDOWS_SUPPORT)
+  {
+    register char
+      *p;
+
+    /*
+      Ghostscript does not like backslashes so we need to replace them. The
+      forward slash also works under Windows.
+    */
+    for (p=(path[1] == *DirectorySeparator ? path+2 : path); *p != '\0'; p++)
       if (*p == *DirectorySeparator)
         *p='/';
+  }
+#endif
   return(MagickTrue);
 }
 
@@ -441,7 +465,7 @@ MagickExport int AcquireUniqueFileResource(char *path)
     *datum;
 
   assert(path != (char *) NULL);
-  (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"%s",path);
+  (void) LogMagickEvent(ResourceEvent,GetMagickModule(),"...");
   if (random_info == (RandomInfo *) NULL)
     random_info=AcquireRandomInfo();
   file=(-1);
@@ -486,7 +510,7 @@ MagickExport int AcquireUniqueFileResource(char *path)
   if (file == -1)
     return(file);
   if (resource_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&resource_semaphore);
+    ActivateSemaphoreInfo(&resource_semaphore);
   LockSemaphoreInfo(resource_semaphore);
   if (temporary_resources == (SplayTreeInfo *) NULL)
     temporary_resources=NewSplayTree(CompareSplayTreeString,
@@ -558,6 +582,11 @@ MagickExport MagickSizeType GetMagickResource(const ResourceType type)
       resource=(MagickSizeType) resource_info.thread;
       break;
     }
+    case ThrottleResource:
+    {
+      resource=(MagickSizeType) resource_info.throttle;
+      break;
+    }
     case TimeResource:
     {
       resource=(MagickSizeType) resource_info.time;
@@ -599,7 +628,7 @@ MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
 
   resource=0;
   if (resource_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&resource_semaphore);
+    ActivateSemaphoreInfo(&resource_semaphore);
   LockSemaphoreInfo(resource_semaphore);
   switch (type)
   {
@@ -633,6 +662,11 @@ MagickExport MagickSizeType GetMagickResourceLimit(const ResourceType type)
       resource=resource_info.thread_limit;
       break;
     }
+    case ThrottleResource:
+    {
+      resource=resource_info.throttle_limit;
+      break;
+    }
     case TimeResource:
     {
       resource=resource_info.time_limit;
@@ -683,7 +717,7 @@ MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
   if (file == (const FILE *) NULL)
     file=stdout;
   if (resource_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&resource_semaphore);
+    ActivateSemaphoreInfo(&resource_semaphore);
   LockSemaphoreInfo(resource_semaphore);
   (void) FormatMagickSize(resource_info.area_limit,MagickFalse,area_limit);
   (void) FormatMagickSize(resource_info.memory_limit,MagickTrue,memory_limit);
@@ -695,15 +729,16 @@ MagickExport MagickBooleanType ListMagickResourceInfo(FILE *file,
   if (resource_info.time_limit != MagickResourceInfinity)
     (void) FormatLocaleString(time_limit,MaxTextExtent,"%.20g",(double)
       ((MagickOffsetType) resource_info.time_limit));
-  (void) FormatLocaleFile(file,"  File        Area      Memory          Map"
-    "         Disk    Thread         Time\n");
+  (void) FormatLocaleFile(file,"  File       Area     Memory        Map"
+    "       Disk   Thread  Throttle       Time\n");
   (void) FormatLocaleFile(file,
     "--------------------------------------------------------"
-    "-----------------------\n");
-  (void) FormatLocaleFile(file,"%6g  %10s  %10s   %10s   %10s    %6g  %11s\n",
+    "------------------------\n");
+  (void) FormatLocaleFile(file,"%6g %10s %10s %10s %10s %8g  %8g %10s\n",
     (double) ((MagickOffsetType) resource_info.file_limit),area_limit,
     memory_limit,map_limit,disk_limit,(double) ((MagickOffsetType)
-    resource_info.thread_limit),time_limit);
+    resource_info.thread_limit),(double) ((MagickOffsetType)
+    resource_info.throttle_limit),time_limit);
   (void) fflush(file);
   UnlockSemaphoreInfo(resource_semaphore);
   return(MagickTrue);
@@ -744,7 +779,7 @@ MagickExport void RelinquishMagickResource(const ResourceType type,
 
   (void) FormatMagickSize(size,MagickFalse,resource_request);
   if (resource_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&resource_semaphore);
+               ActivateSemaphoreInfo(&resource_semaphore);
   LockSemaphoreInfo(resource_semaphore);
   switch (type)
   {
@@ -801,6 +836,14 @@ MagickExport void RelinquishMagickResource(const ResourceType type,
         MagickFalse,resource_limit);
       break;
     }
+    case ThrottleResource:
+    {
+      (void) FormatMagickSize((MagickSizeType) resource_info.throttle,
+        MagickFalse,resource_current);
+      (void) FormatMagickSize((MagickSizeType) resource_info.throttle_limit,
+        MagickFalse,resource_limit);
+      break;
+    }
     case TimeResource:
     {
       resource_info.time-=size;
@@ -866,8 +909,8 @@ MagickExport MagickBooleanType RelinquishUniqueFileResource(const char *path)
     }
   (void) CopyMagickString(cache_path,path,MaxTextExtent);
   AppendImageFormat("cache",cache_path);
-  (void) remove_utf8(cache_path);
-  return(remove_utf8(path) == 0 ? MagickTrue : MagickFalse);
+  (void) ShredFile(cache_path);
+  return(ShredFile(path));
 }
 \f
 /*
@@ -924,7 +967,8 @@ MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
   /*
     Set Magick resource limits.
   */
-  AcquireSemaphoreInfo(&resource_semaphore);
+  if (resource_semaphore == (SemaphoreInfo *) NULL)
+    resource_semaphore=AcquireSemaphoreInfo();
   pagesize=GetMagickPageSize();
   pages=(-1);
 #if defined(MAGICKCORE_HAVE_SYSCONF) && defined(_SC_PHYS_PAGES)
@@ -937,36 +981,29 @@ MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
   memory=PixelCacheThreshold;
 #endif
   (void) SetMagickResourceLimit(AreaResource,2*memory);
-  (void) SetMagickResourceLimit(MemoryResource,memory);
-  (void) SetMagickResourceLimit(MapResource,2*memory);
   limit=GetEnvironmentValue("MAGICK_AREA_LIMIT");
-  if (limit == (char *) NULL)
-    limit=GetPolicyValue("area");
   if (limit != (char *) NULL)
     {
       (void) SetMagickResourceLimit(AreaResource,StringToSizeType(limit,100.0));
       limit=DestroyString(limit);
     }
+  (void) SetMagickResourceLimit(MemoryResource,memory);
   limit=GetEnvironmentValue("MAGICK_MEMORY_LIMIT");
-  if (limit == (char *) NULL)
-    limit=GetPolicyValue("memory");
   if (limit != (char *) NULL)
     {
       (void) SetMagickResourceLimit(MemoryResource,
         StringToSizeType(limit,100.0));
       limit=DestroyString(limit);
     }
+  (void) SetMagickResourceLimit(MapResource,2*memory);
   limit=GetEnvironmentValue("MAGICK_MAP_LIMIT");
-  if (limit == (char *) NULL)
-    limit=GetPolicyValue("map");
   if (limit != (char *) NULL)
     {
       (void) SetMagickResourceLimit(MapResource,StringToSizeType(limit,100.0));
       limit=DestroyString(limit);
     }
+  (void) SetMagickResourceLimit(DiskResource,MagickResourceInfinity);
   limit=GetEnvironmentValue("MAGICK_DISK_LIMIT");
-  if (limit == (char *) NULL)
-    limit=GetPolicyValue("disk");
   if (limit != (char *) NULL)
     {
       (void) SetMagickResourceLimit(DiskResource,StringToSizeType(limit,100.0));
@@ -995,8 +1032,6 @@ MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
   (void) SetMagickResourceLimit(FileResource,MagickMax((size_t)
     (3*files/4),64));
   limit=GetEnvironmentValue("MAGICK_FILE_LIMIT");
-  if (limit == (char *) NULL)
-    limit=GetPolicyValue("file");
   if (limit != (char *) NULL)
     {
       (void) SetMagickResourceLimit(FileResource,StringToSizeType(limit,
@@ -1005,17 +1040,22 @@ MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
     }
   (void) SetMagickResourceLimit(ThreadResource,GetOpenMPMaximumThreads());
   limit=GetEnvironmentValue("MAGICK_THREAD_LIMIT");
-  if (limit == (char *) NULL)
-    limit=GetPolicyValue("thread");
   if (limit != (char *) NULL)
     {
       (void) SetMagickResourceLimit(ThreadResource,StringToSizeType(limit,
         100.0));
       limit=DestroyString(limit);
     }
+  (void) SetMagickResourceLimit(ThrottleResource,0);
+  limit=GetEnvironmentValue("MAGICK_THROTTLE_LIMIT");
+  if (limit != (char *) NULL)
+    {
+      (void) SetMagickResourceLimit(ThrottleResource,StringToSizeType(limit,
+        100.0));
+      limit=DestroyString(limit);
+    }
+  (void) SetMagickResourceLimit(TimeResource,MagickResourceInfinity);
   limit=GetEnvironmentValue("MAGICK_TIME_LIMIT");
-  if (limit == (char *) NULL)
-    limit=GetPolicyValue("time");
   if (limit != (char *) NULL)
     {
       (void) SetMagickResourceLimit(TimeResource,StringToSizeType(limit,100.0));
@@ -1045,14 +1085,14 @@ MagickPrivate MagickBooleanType ResourceComponentGenesis(void)
 MagickPrivate void ResourceComponentTerminus(void)
 {
   if (resource_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&resource_semaphore);
+    resource_semaphore=AcquireSemaphoreInfo();
   LockSemaphoreInfo(resource_semaphore);
   if (temporary_resources != (SplayTreeInfo *) NULL)
     temporary_resources=DestroySplayTree(temporary_resources);
   if (random_info != (RandomInfo *) NULL)
     random_info=DestroyRandomInfo(random_info);
   UnlockSemaphoreInfo(resource_semaphore);
-  DestroySemaphoreInfo(&resource_semaphore);
+  RelinquishSemaphoreInfo(&resource_semaphore);
 }
 \f
 /*
@@ -1096,7 +1136,7 @@ MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
     *value;
 
   if (resource_semaphore == (SemaphoreInfo *) NULL)
-    AcquireSemaphoreInfo(&resource_semaphore);
+    resource_semaphore=AcquireSemaphoreInfo();
   LockSemaphoreInfo(resource_semaphore);
   value=(char *) NULL;
   switch (type)
@@ -1153,6 +1193,17 @@ MagickExport MagickBooleanType SetMagickResourceLimit(const ResourceType type,
         resource_info.thread_limit=GetOpenMPMaximumThreads();
       break;
     }
+    case ThrottleResource:
+    {
+      resource_info.throttle_limit=limit;
+      value=GetPolicyValue("throttle");
+      if (value != (char *) NULL)
+        resource_info.throttle_limit=MagickMin(limit,StringToSizeType(value,
+          100.0));
+      if (resource_info.throttle_limit > GetOpenMPMaximumThreads())
+        resource_info.throttle_limit=GetOpenMPMaximumThreads();
+      break;
+    }
     case TimeResource:
     {
       resource_info.time_limit=limit;