forked from KolibriOS/kolibrios
6496d04506
This version of menuetlibc was taken from revision 4743, right before I made any changes git-svn-id: svn://kolibrios.org@4973 a494cfbc-eb01-0410-851d-a64ba20cac60
217 lines
6.7 KiB
C
217 lines
6.7 KiB
C
/*******************************************************************
|
|
*
|
|
* ttcache.h 1.1
|
|
*
|
|
* Generic object cache
|
|
*
|
|
* Copyright 1996-1999 by
|
|
* David Turner, Robert Wilhelm, and Werner Lemberg.
|
|
*
|
|
* This file is part of the FreeType project, and may only be used
|
|
* modified and distributed under the terms of the FreeType project
|
|
* license, LICENSE.TXT. By continuing to use, modify, or distribute
|
|
* this file you indicate that you have read the license and
|
|
* understand and accept it fully.
|
|
*
|
|
*
|
|
* This component defines and implements object caches.
|
|
*
|
|
* An object class is a structure layout that encapsulate one
|
|
* given type of data used by the FreeType engine. Each object
|
|
* class is completely described by:
|
|
*
|
|
* - a 'root' or 'leading' structure containing the first
|
|
* important fields of the class. The root structure is
|
|
* always of fixed size.
|
|
*
|
|
* It is implemented as a simple C structure, and may
|
|
* contain several pointers to sub-tables that can be
|
|
* sized and allocated dynamically.
|
|
*
|
|
* Examples: TFace, TInstance, TGlyph & TExecution_Context
|
|
* (defined in 'ttobjs.h')
|
|
*
|
|
* - we make a difference between 'child' pointers and 'peer'
|
|
* pointers. A 'child' pointer points to a sub-table that is
|
|
* owned by the object, while a 'peer' pointer points to any
|
|
* other kind of data the object isn't responsible for.
|
|
*
|
|
* An object class is thus usually a 'tree' of 'child' tables.
|
|
*
|
|
* - each object class needs a constructor and a destructor.
|
|
*
|
|
* A constructor is a function which receives the address of
|
|
* freshly allocated and zeroed object root structure and
|
|
* 'builds' all the valid child data that must be associated
|
|
* to the object before it becomes 'valid'.
|
|
*
|
|
* A destructor does the inverse job: given the address of
|
|
* a valid object, it must discard all its child data and
|
|
* zero its main fields (essentially the pointers and array
|
|
* sizes found in the root fields).
|
|
*
|
|
*
|
|
* Important notes:
|
|
*
|
|
* When the constructor fails to allocate an object, it must
|
|
* return immediately with an error code, and not try to release
|
|
* what it has previously allocated before the error. The cache
|
|
* manager detects the error and calls the destructor on the
|
|
* partial object, before returning the error to the caller (along
|
|
* with a NULL pointer for the "new" object).
|
|
*
|
|
* The destructor must thus be able to deal with "partial objects",
|
|
* i.e., objects where only part of the child tables are allocated,
|
|
* and only release these ones. As the TT_Free() function accepts
|
|
* a NULL parameter (and returns successfuly in this case), no check
|
|
* is really necessary when using the macro 'FREE()'.
|
|
*
|
|
* Currently, there is no check in the cache manager to see if a
|
|
* destructor fails (double error state!).
|
|
*
|
|
* This scheme is more compact and more maintanable than the one
|
|
* where de-allocation code is duplicated in the constructor
|
|
* _and_ the destructor.
|
|
*
|
|
*
|
|
*
|
|
* Changes between 1.1 and 1.0:
|
|
*
|
|
* - introduced the refreshed and finalizer class definition/implementation
|
|
* - inserted an engine instance pointer in the cache structure
|
|
*
|
|
******************************************************************/
|
|
|
|
#ifndef TTCACHE_H
|
|
#define TTCACHE_H
|
|
|
|
#include "tttypes.h"
|
|
#include "ttconfig.h"
|
|
#include "ttmutex.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef TT_Error TConstructor( void* object,
|
|
void* parent );
|
|
|
|
typedef TT_Error TDestructor ( void* object );
|
|
|
|
typedef TConstructor TRefresher;
|
|
typedef TDestructor TFinalizer;
|
|
|
|
typedef TConstructor* PConstructor;
|
|
typedef TDestructor* PDestructor;
|
|
typedef TRefresher* PRefresher;
|
|
typedef TFinalizer* PFinalizer;
|
|
|
|
|
|
/* A Cache class record holds the data necessary to define */
|
|
/* a cache kind. */
|
|
struct TCache_Class_
|
|
{
|
|
ULong object_size;
|
|
Long idle_limit;
|
|
PConstructor init;
|
|
PDestructor done;
|
|
PRefresher reset;
|
|
PFinalizer finalize;
|
|
};
|
|
|
|
typedef struct TCache_Class_ TCache_Class;
|
|
typedef TCache_Class* PCache_Class;
|
|
|
|
|
|
|
|
/* Simple list node record. A list element is said to be 'unlinked' */
|
|
/* when it doesn't belong to any list. */
|
|
struct TList_Element_;
|
|
|
|
typedef struct TList_Element_ TList_Element;
|
|
typedef TList_Element* PList_Element;
|
|
|
|
struct TList_Element_
|
|
{
|
|
PList_Element next;
|
|
void* data;
|
|
};
|
|
|
|
|
|
/* Simple singly-linked list record - LIFO style, no tail field */
|
|
typedef PList_Element TSingle_List;
|
|
|
|
struct TCache_
|
|
{
|
|
PEngine_Instance engine;
|
|
PCache_Class clazz; /* 'class' is a reserved word in C++ */
|
|
TMutex* lock;
|
|
TSingle_List active;
|
|
TSingle_List idle;
|
|
Long idle_count;
|
|
};
|
|
|
|
typedef struct TCache_ TCache;
|
|
typedef TCache* PCache;
|
|
|
|
/* Returns a new list element, either fresh or recycled. */
|
|
/* Note: the returned element is unlinked. */
|
|
|
|
/* An object cache holds two lists tracking the active and */
|
|
/* idle objects that are currently created and used by the */
|
|
/* engine. It can also be 'protected' by a mutex. */
|
|
|
|
/* Initializes a new cache, of class 'clazz', pointed by 'cache', */
|
|
/* protected by the 'lock' mutex. Set 'lock' to NULL if the cache */
|
|
/* doesn't need protection */
|
|
|
|
LOCAL_DEF
|
|
TT_Error Cache_Create( PEngine_Instance engine,
|
|
PCache_Class clazz,
|
|
TCache* cache,
|
|
TMutex* lock );
|
|
|
|
/* Destroys a cache and all its listed objects */
|
|
|
|
LOCAL_DEF
|
|
TT_Error Cache_Destroy( TCache* cache );
|
|
|
|
|
|
/* Extracts a new object from the cache */
|
|
|
|
LOCAL_DEF
|
|
TT_Error Cache_New( TCache* cache,
|
|
void** new_object,
|
|
void* parent_object );
|
|
|
|
|
|
/* Returns an object to the cache, or discards it depending */
|
|
/* on the cache class' 'idle_limit' field */
|
|
|
|
LOCAL_DEF
|
|
TT_Error Cache_Done( TCache* cache, void* data );
|
|
|
|
#define CACHE_New( _cache, _newobj, _parent ) \
|
|
Cache_New( (TCache*)_cache, (void**)&_newobj, (void*)_parent )
|
|
|
|
#define CACHE_Done( _cache, _obj ) \
|
|
Cache_Done( (TCache*)_cache, (void*)_obj )
|
|
|
|
|
|
|
|
LOCAL_DEF
|
|
TT_Error TTCache_Init( PEngine_Instance engine );
|
|
|
|
LOCAL_DEF
|
|
TT_Error TTCache_Done( PEngine_Instance engine );
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* TTCACHE_H */
|
|
|
|
|
|
/* END */
|