home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: SysTools
/
SysTools.zip
/
ft-beta.zip
/
freetype
/
lib
/
ttcache.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-10-06
|
4KB
|
178 lines
/*******************************************************************
*
* ttcache.c 1.0
*
* Generic object cache
*
* Copyright 1996, 1997 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.
*
******************************************************************/
#include "ttengine.h"
#include "ttcache.h"
#include "ttmemory.h"
#include "ttobjs.h"
TT_Error Cache_Create( PCache_Class clazz,
TCache* cache,
TMutex* lock )
{
MUTEX_Create( cache->lock );
cache->clazz = clazz;
cache->lock = lock;
cache->idle_count = 0;
ZERO_List( cache->active );
ZERO_List( cache->idle );
return TT_Err_Ok;
}
TT_Error Cache_Destroy( TCache* cache )
{
PDestructor destroy;
PList_Element current;
/* now destroy all active and idle listed objects */
destroy = cache->clazz->done;
/* active list */
current = List_Extract( &cache->active );
while (current)
{
destroy( current->data );
FREE( current->data );
Element_Done( current );
current = List_Extract( &cache->active );
}
/* idle list */
current = List_Extract( &cache->idle );
while (current)
{
destroy( current->data );
FREE( current->data );
Element_Done( current );
current = List_Extract( &cache->idle );
}
cache->clazz = NULL;
cache->idle_count = 0;
return TT_Err_Ok;
}
TT_Error Cache_New( TCache* cache,
void** new_object,
void* parent_object )
{
TT_Error error;
PList_Element current;
PConstructor build;
void* object;
MUTEX_Lock( *cache->lock );
current = List_Extract( &cache->idle );
if (current)
cache->idle_count--;
else
{
/* if no object was found in the cache, create a new one */
build = cache->clazz->init;
if ( MEM_Alloc( object, cache->clazz->object_size ) )
goto Memory_Fail;
current = Element_New();
if (!current)
goto Memory_Fail;
current->data = object;
error = build( object, parent_object );
if (error)
goto Fail;
}
List_Add( &cache->active, current );
*new_object = current->data;
error = TT_Err_Ok;
Exit:
MUTEX_Release( *cache->lock );
return error;
Memory_Fail:
error = TT_Err_Out_Of_Memory;
Fail:
FREE( object );
goto Exit;
}
TT_Error Cache_Done( TCache* cache, void* data )
{
TT_Error error;
PList_Element element;
int limit;
MUTEX_Lock( *cache->lock );
element = List_Find( &cache->active, data );
if ( !element )
{
error = TT_Err_Unlisted_Object;
goto Exit;
}
List_Remove( &cache->active, element );
limit = cache->clazz->idle_limit;
if ( cache->idle_count >= limit )
{
/* destroy the object when the cache is full */
cache->clazz->done( element->data );
FREE( element->data );
Element_Done( element );
}
else
{
/* simply add the object to the idle list */
List_Add( &cache->idle, element );
cache->idle_count++;
}
error = TT_Err_Ok;
Exit:
MUTEX_Release( *cache_lock );
return error;
}