diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2002-01-27 05:20:16 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2002-01-27 05:20:16 (GMT) |
commit | 0a612f0a6133363cecf86afe7c872706a200876e (patch) | |
tree | 3365abc3e26775be6871c9196c8e4fd4ee63e1c4 | |
parent | 613d63ba73500e79b247f0bf3a9c053437265428 (diff) | |
download | hdf5-0a612f0a6133363cecf86afe7c872706a200876e.zip hdf5-0a612f0a6133363cecf86afe7c872706a200876e.tar.gz hdf5-0a612f0a6133363cecf86afe7c872706a200876e.tar.bz2 |
[svn-r4868] Purpose:
Bug fixes
Description:
This checkin addresses two separate bugs:
#1 - When a compound datatype with a VL datatype as a field is used
to read or write data, the datatype conversion paths added to
the table of paths were treating the VL datatypes somewhat too
genericly - they weren't dicriminating between VL datatypes used
in different files and therefore there was the possibility that
a path in the table having information for one file could get used
with a second file, causing errors or core dumps (if the first
file was closed before the later file used the path).
#2 - When composite (compound, array or VL) datatype paths in the datatype
conversion table are being tested to see if they can be used for
the current datatypes being converted, they can cause additional
conversion paths to be registered in the conversion path table.
Since this causes the global table to change size and entries to
move around, it is possible that the local variables tracking a
potential path could become incorrect as the global table was
changed out from underneath them.
Both bugs fixed are described in bug #703
Solution:
Two separate fixes:
#1 - Changed H5T_cmp to differentiate between VL datatypes in different
files and not to return datatypes in two different files as equal.
#2 - Note size of global table before evaluating datatype paths. Then,
after the appropriate path has been chosen, check if the size of
the global table has changed and recompute the position of the path
chosen in the table if necessary.
Platforms tested:
FreeBSD 4.5 (sleipnir)
-rw-r--r-- | src/H5T.c | 39 |
1 files changed, 37 insertions, 2 deletions
@@ -7098,6 +7098,11 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2) dt2->u.vlen.loc==H5T_VLEN_MEMORY) { HGOTO_DONE(1); } + /* Don't allow VL types in different files to compare as equal */ + if (dt1->u.vlen.f < dt2->u.vlen.f) + HGOTO_DONE(-1); + if (dt1->u.vlen.f > dt2->u.vlen.f) + HGOTO_DONE(1); break; case H5T_OPAQUE: @@ -7308,6 +7313,7 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name, int lt, rt; /*left and right edges */ int md; /*middle */ int cmp; /*comparison result */ + int old_npaths; /* Previous number of paths in table */ H5T_path_t *table=NULL; /*path existing in the table */ H5T_path_t *path=NULL; /*new path */ H5T_path_t *ret_value=NULL; /*return value */ @@ -7380,6 +7386,12 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name, } } } + + /* Keep a record of the number of paths in the table, in case one of the + * initialization calls below (hard or soft) causes more entries to be + * added to the table - QAK, 1/26/02 + */ + old_npaths=H5T_g.npaths; /* * If we didn't find the path or if the caller is specifying a new hard @@ -7477,6 +7489,29 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name, "no appropriate function for conversion path"); } + /* Check if paths were inserted into the table through a recursive call + * and re-compute the correct location for this path if so. - QAK, 1/26/02 + */ + if(old_npaths!=H5T_g.npaths) { + lt = md = 1; + rt = H5T_g.npaths; + cmp = -1; + + while (cmp && lt<rt) { + md = (lt+rt) / 2; + assert(H5T_g.path[md]); + cmp = H5T_cmp(src, H5T_g.path[md]->src); + if (0==cmp) cmp = H5T_cmp(dst, H5T_g.path[md]->dst); + if (cmp<0) { + rt = md; + } else if (cmp>0) { + lt = md+1; + } else { + table = H5T_g.path[md]; + } + } + } /* end if */ + /* Replace an existing table entry or add a new entry */ if (table && path!=table) { assert(table==H5T_g.path[md]); @@ -7495,7 +7530,7 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name, } if (table->src) H5T_close(table->src); if (table->dst) H5T_close(table->dst); - H5FL_FREE(H5T_path_t,table); + H5FL_FREE(H5T_path_t,table); table = path; H5T_g.path[md] = path; } else if (path!=table) { @@ -7524,7 +7559,7 @@ H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name, if (!ret_value && path && path!=table) { if (path->src) H5T_close(path->src); if (path->dst) H5T_close(path->dst); - H5FL_FREE(H5T_path_t,path); + H5FL_FREE(H5T_path_t,path); } if (src_id>=0) H5I_dec_ref(src_id); if (dst_id>=0) H5I_dec_ref(dst_id); |