diff options
author | David Turner <david@freetype.org> | 2005-05-23 13:04:53 +0000 |
---|---|---|
committer | David Turner <david@freetype.org> | 2005-05-23 13:04:53 +0000 |
commit | f9e05597780eae8db99a238319bbbee06f7cf738 (patch) | |
tree | 4c878b3002594739ce60450f9b461ab5e72e9dcd /src/cache/ftcsbits.c | |
parent | a4dbed30b2c9633c4dd5564afcca9923ab5c7583 (diff) | |
download | freetype-f9e05597780eae8db99a238319bbbee06f7cf738.tar.gz |
* include/freetype/cache/ftcache.h, src/cache/ftccache.c,
src/cache/ftcsbits.c: fixing bug #12213 (incorrect behaviour
of the cache sub-system in low-memory conditions).
Diffstat (limited to 'src/cache/ftcsbits.c')
-rw-r--r-- | src/cache/ftcsbits.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/src/cache/ftcsbits.c b/src/cache/ftcsbits.c index 71599717c..51ec34c31 100644 --- a/src/cache/ftcsbits.c +++ b/src/cache/ftcsbits.c @@ -85,6 +85,15 @@ } + /* this function tries to load a small bitmap within a given FTC_SNode + * note that it will return a non-zero error code _only_ in the case + * of out-of-memory condition. For all other errors (e.g. corresponding + * to a bad font file), this function will mark the sbit as "unavailable" + * and return a value of 0. + * + * you should also read the comment within the @ftc_snode_compare function + * below to see how out-of-memory is handled during a lookup + */ static FT_Error ftc_snode_load( FTC_SNode snode, FTC_Manager manager, @@ -315,16 +324,54 @@ FTC_SBit sbit = snode->sbits + ( gindex - gnode->gindex ); + /* the following code illustrates what to do when you want to + * perform operations that may fail within a lookup function. + * + * here, we want to load a small bitmap on-demand, we thus + * need to call the 'ftc_snode_load' function which may return + * a non-zero error code only when we're out of memory + * + * the correct thing to do is to use @FTC_CACHE_TRYLOOP and + * @FTC_CACHE_TRYLOOP_END in order to implement a retry loop + * that is capable of flushing the cache incrementally when + * OOM errors occur. + * + * however, we previously need to 'lock' the node to prevent it + * from being flushed in the loop. + * + * when we exit the loop, we unlock the node then check the 'error' + * variable. If it is non-zero, this means that the cache was + * completely flushed and that no usable memory was found to load + * the bitmap. + * + * we then prefer to return a value of 0 (i.e. NO MATCH). This + * will ensure that the caller will try to allocate a new node. + * this operation _will_ fail and the lookup function will return + * the OOM error code appropriately. + * + * note that 'buffer == NULL && width == 255' is a hack used to + * tag "unavailable" bitmaps in the array. We should never try + * to load these. + */ if ( sbit->buffer == NULL && sbit->width != 255 ) { FT_ULong size; + FT_Error error; + ftcsnode->ref_count++; /* lock node, prevent flushing in retry loop */ - if ( !ftc_snode_load( snode, cache->manager, - gindex, &size ) ) + FTC_CACHE_TRYLOOP(cache) { - cache->manager->cur_weight += size; + error = ftc_snode_load( snode, cache->manager, gindex, &size ); } + FTC_CACHE_TRYLOOP_END(); + + ftcsnode->ref_count--; /* unlock the node */ + + if ( error ) + result = 0; + else + cache->manager->cur_weight += size; } } |