summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2002-01-27 05:20:16 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2002-01-27 05:20:16 (GMT)
commit0a612f0a6133363cecf86afe7c872706a200876e (patch)
tree3365abc3e26775be6871c9196c8e4fd4ee63e1c4
parent613d63ba73500e79b247f0bf3a9c053437265428 (diff)
downloadhdf5-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.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/src/H5T.c b/src/H5T.c
index 88c26be..d373629 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -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);