aboutsummaryrefslogtreecommitdiff
path: root/src/cache/ftcsbits.c
diff options
context:
space:
mode:
authorDavid Turner <david@freetype.org>2005-05-23 13:04:53 +0000
committerDavid Turner <david@freetype.org>2005-05-23 13:04:53 +0000
commitf9e05597780eae8db99a238319bbbee06f7cf738 (patch)
tree4c878b3002594739ce60450f9b461ab5e72e9dcd /src/cache/ftcsbits.c
parenta4dbed30b2c9633c4dd5564afcca9923ab5c7583 (diff)
downloadfreetype-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.c53
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;
}
}