diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2016-01-01 06:28:04 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2016-01-01 06:28:04 (GMT) |
commit | f60170dac7c491cc75120a6ebdfe73c13c0bab1d (patch) | |
tree | 6adfe7a8ccaa4c7cf6a0ae8aa2b4e7deb0518521 /src | |
parent | 8d8d56d7d1601a88b90524c7bcb78c2515ce770f (diff) | |
download | hdf5-f60170dac7c491cc75120a6ebdfe73c13c0bab1d.zip hdf5-f60170dac7c491cc75120a6ebdfe73c13c0bab1d.tar.gz hdf5-f60170dac7c491cc75120a6ebdfe73c13c0bab1d.tar.bz2 |
[svn-r28761] Description:
Clean up many mismatches between malloc/free and H5MM_malloc/H5MM_xfree
in the library and tests (and use of H5free_memory and H5Dvlen_reclaim). Also
make H5Ocopy use a private version of H5Lexists, which doesn't internally
throw (and suppress) errors when an object (or the path to it) isn't found in
the destination.
Tested on:
MacOSX/64 10.11.2 (amazon) w/serial & parallel
(h5committest forthcoming)
Diffstat (limited to 'src')
-rw-r--r-- | src/H5.c | 5 | ||||
-rw-r--r-- | src/H5L.c | 186 | ||||
-rw-r--r-- | src/H5Lprivate.h | 2 | ||||
-rw-r--r-- | src/H5Ocopy.c | 24 | ||||
-rw-r--r-- | src/H5TS.c | 17 | ||||
-rw-r--r-- | src/H5Tvlen.c | 8 | ||||
-rw-r--r-- | src/H5Ztrans.c | 4 |
7 files changed, 192 insertions, 54 deletions
@@ -942,7 +942,6 @@ H5allocate_memory(size_t size, hbool_t clear) ret_value = H5MM_malloc(size); FUNC_LEAVE_API(ret_value) - } /* end H5allocate_memory() */ @@ -981,7 +980,6 @@ H5resize_memory(void *mem, size_t size) ret_value = H5MM_realloc(mem, size); FUNC_LEAVE_API(ret_value) - } /* end H5resize_memory() */ @@ -1004,10 +1002,9 @@ H5free_memory(void *mem) H5TRACE1("e", "*x", mem); /* At this time, it is impossible for this to fail. */ - HDfree(mem); + H5MM_xfree(mem); FUNC_LEAVE_API(SUCCEED) - } /* end H5free_memory() */ @@ -93,6 +93,17 @@ typedef struct { hid_t dxpl_id; /* Dataset transfer property list */ } H5L_trav_mv2_t; +/* User data for path traversal routine for checking if a link exists */ +typedef struct { + /* Down */ + char *sep; /* Pointer to next separator in the string */ + hid_t lapl_id; /* Link access property list */ + hid_t dxpl_id; /* Dataset transfer property list */ + + /* Up */ + hbool_t exists; /* Whether the link exists or not */ +} H5L_trav_le_t; + /* User data for path traversal routine for getting link value */ typedef struct { size_t size; /* Size of user buffer */ @@ -170,10 +181,13 @@ static herr_t H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, static herr_t H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/); -static herr_t H5L_exists_cb(H5G_loc_t *grp_loc/*in*/, const char *name, +static herr_t H5L__exists_final_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/); +static herr_t H5L__exists_inter_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/); -static htri_t H5L_exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, +static htri_t H5L__exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id); static herr_t H5L_get_info_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, @@ -827,7 +841,7 @@ H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") /* Check for the existence of the link */ - if((ret_value = H5L_exists(&loc, name, lapl_id, H5AC_ind_dxpl_id)) < 0) + if((ret_value = H5L__exists(&loc, name, lapl_id, H5AC_ind_dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") done: @@ -2716,9 +2730,10 @@ done: /*------------------------------------------------------------------------- - * Function: H5L_exists_cb + * Function: H5L__exists_final_cb * - * Purpose: Callback for checking whether a link exists + * Purpose: Callback for checking whether a link exists, as the final + * component of a path * * Return: Non-negative on success/Negative on failure * @@ -2728,30 +2743,162 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5L_exists_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, +H5L__exists_final_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t *lnk, H5G_loc_t H5_ATTR_UNUSED *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) { - hbool_t *udata = (hbool_t *)_udata; /* User data passed in */ + H5L_trav_le_t *udata = (H5L_trav_le_t *)_udata; /* User data passed in */ - FUNC_ENTER_NOAPI_NOINIT_NOERR + FUNC_ENTER_STATIC_NOERR /* Check if the name in this group resolved to a valid link */ - *udata = (hbool_t)(lnk != NULL); + udata->exists = (hbool_t)(lnk != NULL); /* Indicate that this callback didn't take ownership of the group * * location for the object */ *own_loc = H5G_OWN_NONE; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5L_exists_cb() */ +} /* end H5L__exists_final_cb() */ /*------------------------------------------------------------------------- - * Function: H5L_exists + * Function: H5L__exists_inter_cb + * + * Purpose: Callback for checking whether a link exists, as an intermediate + * component of a path + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, December 31 2015 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L__exists_inter_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/) +{ + H5L_trav_le_t *udata = (H5L_trav_le_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_STATIC + + /* Check if the name in this group resolved to a valid link */ + if(lnk != NULL) { + /* Check for more components to the path */ + if(udata->sep) { + H5G_traverse_t cb_func; /* Callback function for tranversal */ + char *next; /* Pointer to next component name */ + + /* Look for another separator */ + next = udata->sep; + if(NULL == (udata->sep = HDstrchr(udata->sep, '/'))) + cb_func = H5L__exists_final_cb; + else { + /* Chew through adjacent separators, if present */ + do { + *udata->sep = '\0'; + udata->sep++; + } while('/' == *udata->sep); + cb_func = H5L__exists_inter_cb; + } /* end else */ + if(H5G_traverse(obj_loc, next, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, cb_func, udata, udata->lapl_id, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't determine if link exists") + } /* end if */ + else + udata->exists = TRUE; + } /* end if */ + else + udata->exists = FALSE; + + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L__exists_inter_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_exists_tolerant * * Purpose: Returns whether a link exists in a group * + * Note: Same as H5L_exists, except that missing links are reported + * as 'FALSE' instead of causing failures + * + * Return: Non-negative (TRUE/FALSE) on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, December 31 2015 + * + *------------------------------------------------------------------------- + */ +htri_t +H5L_exists_tolerant(const H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id) +{ + H5L_trav_le_t udata; /* User data for traversal */ + H5G_traverse_t cb_func; /* Callback function for tranversal */ + char *name_copy = NULL; /* Duplicate of name */ + char *name_trav; /* Name to traverse */ + htri_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity checks */ + HDassert(loc); + HDassert(name); + + /* Copy the name and skip leading '/'s */ + name_trav = name_copy = H5MM_strdup(name); + while('/' == *name_trav) + name_trav++; + + /* A path of "/" will always exist in a file */ + if('\0' == *name_trav) + HGOTO_DONE(TRUE) + + /* Set up user data & correct callback */ + udata.lapl_id = lapl_id; + udata.dxpl_id = dxpl_id; + udata.exists = FALSE; + if(NULL == (udata.sep = HDstrchr(name_trav, '/'))) + cb_func = H5L__exists_final_cb; + else { + /* Chew through adjacent separators, if present */ + do { + *udata.sep = '\0'; + udata.sep++; + } while('/' == *udata.sep); + cb_func = H5L__exists_inter_cb; + } /* end else */ + + /* Traverse the group hierarchy to locate the link to check */ + if(H5G_traverse(loc, name_trav, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, cb_func, &udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't determine if link exists") + + /* Set return value */ + ret_value = (htri_t)udata.exists; + +done: + /* Release duplicated string */ + H5MM_xfree(name_copy); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5L_exists_tolerant() */ + + +/*------------------------------------------------------------------------- + * Function: H5L__exists + * + * Purpose: Returns whether a link exists in a group + * + * Note: Same as H5L_exists_tolerant, except that missing links are reported + * as failures + * * Return: Non-negative (TRUE/FALSE) on success/Negative on failure * * Programmer: Quincey Koziol @@ -2760,23 +2907,28 @@ H5L_exists_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *------------------------------------------------------------------------- */ static htri_t -H5L_exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id) +H5L__exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id) { - hbool_t exists = FALSE; /* Whether the link exists in the group */ + H5L_trav_le_t udata; /* User data for traversal */ htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT + FUNC_ENTER_STATIC + + /* A path of "/" will always exist in a file */ + if(0 == HDstrcmp(name, "/")) + HGOTO_DONE(TRUE) /* Traverse the group hierarchy to locate the object to get info about */ - if(H5G_traverse(loc, name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_exists_cb, &exists, lapl_id, dxpl_id) < 0) + udata.exists = FALSE; + if(H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__exists_final_cb, &udata, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "path doesn't exist") /* Set return value */ - ret_value = (htri_t)exists; + ret_value = (htri_t)udata.exists; done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5L_exists() */ +} /* H5L__exists() */ /*------------------------------------------------------------------------- diff --git a/src/H5Lprivate.h b/src/H5Lprivate.h index f3079bc..1c8690b 100644 --- a/src/H5Lprivate.h +++ b/src/H5Lprivate.h @@ -81,6 +81,8 @@ H5_DLL hid_t H5L_get_default_lcpl(void); H5_DLL herr_t H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, const char *dst_name, hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id, hid_t dxpl_id); +H5_DLL htri_t H5L_exists_tolerant(const H5G_loc_t *loc, const char *name, hid_t lapl_id, + hid_t dxpl_id); H5_DLL herr_t H5L_get_info(const H5G_loc_t *loc, const char *name, H5L_info_t *linkbuf/*out*/, hid_t lapl_id, hid_t dxpl_id); H5_DLL herr_t H5L_delete(H5G_loc_t *loc, const char *name, hid_t lapl_id, diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index 02c72e7..6f42a88 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -213,10 +213,10 @@ H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, /* for opening the destination object */ H5G_name_t src_path; /* Opened source object hier. path */ H5O_loc_t src_oloc; /* Opened source object object location */ + htri_t dst_exists; /* Does destination name exist already? */ hbool_t loc_found = FALSE; /* Location at 'name' found */ hbool_t obj_open = FALSE; /* Entry at 'name' found */ - - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "i*si*sii", src_loc_id, src_name, dst_loc_id, dst_name, @@ -233,22 +233,10 @@ H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified") /* check if destination name already exists */ - { - H5G_name_t tmp_path; - H5O_loc_t tmp_oloc; - H5G_loc_t tmp_loc; - - /* Set up group location */ - tmp_loc.oloc = &tmp_oloc; - tmp_loc.path = &tmp_path; - H5G_loc_reset(&tmp_loc); - - /* Check if object already exists in destination */ - if(H5G_loc_find(&dst_loc, dst_name, &tmp_loc, H5P_DEFAULT, H5AC_ind_dxpl_id) >= 0) { - H5G_name_free(&tmp_path); - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "destination object already exists") - } /* end if */ - } + if((dst_exists = H5L_exists_tolerant(&dst_loc, dst_name, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to check if destination name exists") + if(TRUE == dst_exists) + HGOTO_ERROR(H5E_OHDR, H5E_EXISTS, FAIL, "destination object already exists") /* Set up opened group location to fill in */ src_loc.oloc = &src_oloc; @@ -255,19 +255,18 @@ H5TS_cancel_count_inc(void) if (!cancel_counter) { /* - * First time thread calls library - create new counter and associate + * First time thread calls library - create new counter and associate * with key */ - cancel_counter = (H5TS_cancel_t *)H5MM_calloc(sizeof(H5TS_cancel_t)); + cancel_counter = (H5TS_cancel_t *)HDcalloc(1, sizeof(H5TS_cancel_t)); - if (!cancel_counter) { - H5E_push_stack(NULL, "H5TS_cancel_count_inc", - __FILE__, __LINE__, H5E_ERR_CLS_g, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed"); - return FAIL; - } + if (!cancel_counter) { + H5E_push_stack(NULL, "H5TS_cancel_count_inc", __FILE__, __LINE__, + H5E_ERR_CLS_g, H5E_RESOURCE, H5E_NOSPACE, "memory allocation failed"); + return FAIL; + } - ret_value = pthread_setspecific(H5TS_cancel_key_g, - (void *)cancel_counter); + ret_value = pthread_setspecific(H5TS_cancel_key_g, (void *)cancel_counter); } if (cancel_counter->cancel_count == 0) diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index 2abdf6f..0ed8209 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -465,7 +465,7 @@ H5T_vlen_seq_mem_write(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, co HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") } /* end if */ else { /* Default to system malloc */ - if(NULL==(vl.p=H5MM_malloc(len))) + if(NULL == (vl.p = HDmalloc(len))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") } /* end else */ @@ -691,7 +691,7 @@ H5T_vlen_str_mem_write(H5F_t H5_ATTR_UNUSED *f, hid_t H5_ATTR_UNUSED dxpl_id, co HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") } /* end if */ else { /* Default to system malloc */ - if(NULL==(t = (char *)H5MM_malloc((seq_len+1)*base_size))) + if(NULL == (t = (char *)HDmalloc((seq_len + 1) * base_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for VL data") } /* end else */ @@ -1073,14 +1073,14 @@ H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, voi if(free_func != NULL) (*free_func)(vl->p, free_info); else - H5MM_xfree(vl->p); + HDfree(vl->p); } /* end if */ } else if(dt->shared->u.vlen.type == H5T_VLEN_STRING) { /* Free the VL string */ if(free_func != NULL) (*free_func)(*(char **)elem, free_info); else - H5MM_xfree(*(char **)elem); + HDfree(*(char **)elem); } else { HDassert(0 && "Invalid VL type"); } /* end else */ diff --git a/src/H5Ztrans.c b/src/H5Ztrans.c index 0a9a4da..2627a29 100644 --- a/src/H5Ztrans.c +++ b/src/H5Ztrans.c @@ -1032,7 +1032,7 @@ H5Z_xform_eval(H5Z_data_xform_t *data_xform_prop, void* array, size_t array_size /* Free the temporary arrays we used */ if(data_xform_prop->dat_val_pointers->num_ptrs > 1) for(i=0; i<data_xform_prop->dat_val_pointers->num_ptrs; i++) - HDfree(data_xform_prop->dat_val_pointers->ptr_dat_val[i]); + H5MM_xfree(data_xform_prop->dat_val_pointers->ptr_dat_val[i]); } /* end else */ done: @@ -1042,7 +1042,7 @@ done: if(data_xform_prop->dat_val_pointers->num_ptrs > 1) for(i = 0; i < data_xform_prop->dat_val_pointers->num_ptrs; i++) if(data_xform_prop->dat_val_pointers->ptr_dat_val[i]) - HDfree(data_xform_prop->dat_val_pointers->ptr_dat_val[i]); + H5MM_xfree(data_xform_prop->dat_val_pointers->ptr_dat_val[i]); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) |