Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
4973 right-hear 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 */