Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*******************************************************************
  2.  *
  3.  *  ttcache.h                                                   1.1
  4.  *
  5.  *    Generic object cache
  6.  *
  7.  *  Copyright 1996-1999 by
  8.  *  David Turner, Robert Wilhelm, and Werner Lemberg.
  9.  *
  10.  *  This file is part of the FreeType project, and may only be used
  11.  *  modified and distributed under the terms of the FreeType project
  12.  *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
  13.  *  this file you indicate that you have read the license and
  14.  *  understand and accept it fully.
  15.  *
  16.  *
  17.  *  This component defines and implements object caches.
  18.  *
  19.  *  An object class is a structure layout that encapsulate one
  20.  *  given type of data used by the FreeType engine.  Each object
  21.  *  class is completely described by:
  22.  *
  23.  *    - a 'root' or 'leading' structure containing the first
  24.  *      important fields of the class.  The root structure is
  25.  *      always of fixed size.
  26.  *
  27.  *      It is implemented as a simple C structure, and may
  28.  *      contain several pointers to sub-tables that can be
  29.  *      sized and allocated dynamically.
  30.  *
  31.  *      Examples:  TFace, TInstance, TGlyph & TExecution_Context
  32.  *                 (defined in 'ttobjs.h')
  33.  *
  34.  *    - we make a difference between 'child' pointers and 'peer'
  35.  *      pointers.  A 'child' pointer points to a sub-table that is
  36.  *      owned by the object, while a 'peer' pointer points to any
  37.  *      other kind of data the object isn't responsible for.
  38.  *
  39.  *      An object class is thus usually a 'tree' of 'child' tables.
  40.  *
  41.  *    - each object class needs a constructor and a destructor.
  42.  *
  43.  *      A constructor is a function which receives the address of
  44.  *      freshly allocated and zeroed object root structure and
  45.  *      'builds' all the valid child data that must be associated
  46.  *      to the object before it becomes 'valid'.
  47.  *
  48.  *      A destructor does the inverse job: given the address of
  49.  *      a valid object, it must discard all its child data and
  50.  *      zero its main fields (essentially the pointers and array
  51.  *      sizes found in the root fields).
  52.  *
  53.  *
  54.  *  Important notes:
  55.  *
  56.  *      When the constructor fails to allocate an object, it must
  57.  *      return immediately with an error code, and not try to release
  58.  *      what it has previously allocated before the error.  The cache
  59.  *      manager detects the error and calls the destructor on the
  60.  *      partial object, before returning the error to the caller (along
  61.  *      with a NULL pointer for the "new" object).
  62.  *
  63.  *      The destructor must thus be able to deal with "partial objects",
  64.  *      i.e., objects where only part of the child tables are allocated,
  65.  *      and only release these ones.  As the TT_Free() function accepts
  66.  *      a NULL parameter (and returns successfuly in this case), no check
  67.  *      is really necessary when using the macro 'FREE()'.
  68.  *
  69.  *      Currently, there is no check in the cache manager to see if a
  70.  *      destructor fails (double error state!).
  71.  *
  72.  *      This scheme is more compact and more maintanable than the one
  73.  *      where de-allocation code is duplicated in the constructor
  74.  *      _and_ the destructor.
  75.  *
  76.  *
  77.  *
  78.  * Changes between 1.1 and 1.0:
  79.  *
  80.  *  - introduced the refreshed and finalizer class definition/implementation
  81.  *  - inserted an engine instance pointer in the cache structure
  82.  *
  83.  ******************************************************************/
  84.  
  85. #ifndef TTCACHE_H
  86. #define TTCACHE_H
  87.  
  88. #include "tttypes.h"
  89. #include "ttconfig.h"
  90. #include "ttmutex.h"
  91.  
  92. #ifdef __cplusplus
  93.   extern "C" {
  94. #endif
  95.  
  96.   typedef TT_Error  TConstructor( void*  object,
  97.                                   void*  parent );
  98.  
  99.   typedef TT_Error  TDestructor ( void*  object );
  100.  
  101.   typedef TConstructor  TRefresher;
  102.   typedef TDestructor   TFinalizer;
  103.  
  104.   typedef TConstructor*  PConstructor;
  105.   typedef TDestructor*   PDestructor;
  106.   typedef TRefresher*    PRefresher;
  107.   typedef TFinalizer*    PFinalizer;
  108.  
  109.  
  110.   /* A Cache class record holds the data necessary to define */
  111.   /* a cache kind.                                           */
  112.   struct  TCache_Class_
  113.   {
  114.     ULong         object_size;
  115.     Long          idle_limit;
  116.     PConstructor  init;
  117.     PDestructor   done;
  118.     PRefresher    reset;
  119.     PFinalizer    finalize;
  120.   };
  121.  
  122.   typedef struct TCache_Class_  TCache_Class;
  123.   typedef TCache_Class*         PCache_Class;
  124.  
  125.  
  126.  
  127.   /* Simple list node record.  A list element is said to be 'unlinked' */
  128.   /* when it doesn't belong to any list.                               */
  129.   struct  TList_Element_;
  130.  
  131.   typedef struct TList_Element_  TList_Element;
  132.   typedef TList_Element*         PList_Element;
  133.  
  134.   struct  TList_Element_
  135.   {
  136.     PList_Element  next;
  137.     void*          data;
  138.   };
  139.  
  140.  
  141.   /* Simple singly-linked list record - LIFO style, no tail field */
  142.   typedef PList_Element  TSingle_List;
  143.  
  144.   struct  TCache_
  145.   {
  146.     PEngine_Instance  engine;
  147.     PCache_Class      clazz;      /* 'class' is a reserved word in C++ */
  148.     TMutex*           lock;
  149.     TSingle_List      active;
  150.     TSingle_List      idle;
  151.     Long              idle_count;
  152.   };
  153.  
  154.   typedef struct TCache_  TCache;
  155.   typedef TCache*         PCache;
  156.  
  157.   /* Returns a new list element, either fresh or recycled. */
  158.   /* Note: the returned element is unlinked.               */
  159.  
  160.   /* An object cache holds two lists tracking the active and */
  161.   /* idle objects that are currently created and used by the */
  162.   /* engine.  It can also be 'protected' by a mutex.         */
  163.  
  164.   /* Initializes a new cache, of class 'clazz', pointed by 'cache', */
  165.   /* protected by the 'lock' mutex. Set 'lock' to NULL if the cache */
  166.   /* doesn't need protection                                        */
  167.  
  168.   LOCAL_DEF
  169.   TT_Error  Cache_Create( PEngine_Instance  engine,
  170.                           PCache_Class      clazz,
  171.                           TCache*           cache,
  172.                           TMutex*           lock );
  173.  
  174.   /* Destroys a cache and all its listed objects */
  175.  
  176.   LOCAL_DEF
  177.   TT_Error  Cache_Destroy( TCache*  cache );
  178.  
  179.  
  180.   /* Extracts a new object from the cache */
  181.  
  182.   LOCAL_DEF
  183.   TT_Error Cache_New( TCache*  cache,
  184.                       void**   new_object,
  185.                       void*    parent_object );
  186.  
  187.  
  188.   /* Returns an object to the cache, or discards it depending */
  189.   /* on the cache class' 'idle_limit' field                   */
  190.  
  191.   LOCAL_DEF
  192.   TT_Error  Cache_Done( TCache*  cache, void*  data );
  193.  
  194. #define CACHE_New( _cache, _newobj, _parent ) \
  195.           Cache_New( (TCache*)_cache, (void**)&_newobj, (void*)_parent )
  196.  
  197. #define CACHE_Done( _cache, _obj ) \
  198.           Cache_Done( (TCache*)_cache, (void*)_obj )
  199.  
  200.  
  201.  
  202.   LOCAL_DEF
  203.   TT_Error  TTCache_Init( PEngine_Instance  engine );
  204.  
  205.   LOCAL_DEF
  206.   TT_Error  TTCache_Done( PEngine_Instance  engine );
  207.  
  208.  
  209. #ifdef __cplusplus
  210.   }
  211. #endif
  212.  
  213. #endif /* TTCACHE_H */
  214.  
  215.  
  216. /* END */
  217.