diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5C.c | 20 | ||||
-rw-r--r-- | src/H5Cpkg.h | 18 |
2 files changed, 38 insertions, 0 deletions
@@ -386,6 +386,7 @@ H5C_create(size_t max_cache_size, cache_ptr->cache_full = FALSE; cache_ptr->size_decreased = FALSE; cache_ptr->resize_in_progress = FALSE; + cache_ptr->msic_in_progress = FALSE; (cache_ptr->resize_ctl).version = H5C__CURR_AUTO_SIZE_CTL_VER; (cache_ptr->resize_ctl).rpt_fcn = NULL; @@ -6904,6 +6905,7 @@ H5C__make_space_in_cache(H5F_t *f, hid_t dxpl_id, size_t space_needed, uint32_t entries_examined = 0; uint32_t initial_list_len; size_t empty_space; + hbool_t reentrant_call = FALSE; hbool_t prev_is_dirty = FALSE; hbool_t didnt_flush_entry = FALSE; hbool_t restart_scan; @@ -6921,6 +6923,18 @@ H5C__make_space_in_cache(H5F_t *f, hid_t dxpl_id, size_t space_needed, HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); HDassert(cache_ptr->index_size == (cache_ptr->clean_index_size + cache_ptr->dirty_index_size)); + /* check to see if cache_ptr->msic_in_progress is TRUE. If it, this + * is a re-entrant call via a client callback called in the make + * space in cache process. To avoid an infinite recursion, set + * reentrant_call to TRUE, and goto done. + */ + if(cache_ptr->msic_in_progress) { + reentrant_call = TRUE; + HGOTO_DONE(SUCCEED); + } /* end if */ + + cache_ptr->msic_in_progress = TRUE; + if ( write_permitted ) { restart_scan = FALSE; initial_list_len = cache_ptr->LRU_list_len; @@ -7180,6 +7194,12 @@ H5C__make_space_in_cache(H5F_t *f, hid_t dxpl_id, size_t space_needed, } done: + /* Sanity checks */ + HDassert(cache_ptr->msic_in_progress); + if(!reentrant_call) + cache_ptr->msic_in_progress = FALSE; + HDassert((!reentrant_call) || (cache_ptr->msic_in_progress)); + FUNC_LEAVE_NOAPI(ret_value) } /* H5C__make_space_in_cache() */ diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index 3ea5144..321f1fb 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -4104,6 +4104,23 @@ typedef struct H5C_tag_info_t { * of changes to the file driver info superblock extension * management code needed to support rings. * + * msic_in_progress: As the metadata cache has become re-entrant, and as + * the free space manager code has become more tightly + * integrated with the metadata cache, it is possible that + * a call to H5C_insert_entry() may trigger a call to + * H5C_make_space_in_cache(), which, via H5C__flush_single_entry() + * and client callbacks, may trigger an infinite regression + * of calls to H5C_make_space_in_cache(). + * + * The msic_in_progress boolean flag is used to detect this, + * and prevent the infinite regression that would otherwise + * occur. + * + * Note that this is issue is not hypothetical -- this field + * was added 2/16/17 to address this issue when it was + * exposed by modifications to test/fheap.c to cause it to + * use paged allocation. + * * resize_ctl: Instance of H5C_auto_size_ctl_t containing configuration * data for automatic cache resizing. * @@ -4743,6 +4760,7 @@ struct H5C_t { hbool_t cache_full; hbool_t size_decreased; hbool_t resize_in_progress; + hbool_t msic_in_progress; H5C_auto_size_ctl_t resize_ctl; /* Fields for epoch markers used in automatic cache size adjustment */ |