summaryrefslogtreecommitdiffstats
path: root/src/H5Oshared.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Oshared.c')
-rw-r--r--src/H5Oshared.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index 062443a..e22a105 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -107,7 +107,7 @@
*-------------------------------------------------------------------------
*/
static void *
-H5O_shared_read(H5F_t *f, hid_t dxpl_id, unsigned *ioflags,
+H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned *ioflags,
const H5O_shared_t *shared, const H5O_msg_class_t *type)
{
H5HF_t *fheap = NULL;
@@ -159,7 +159,7 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, unsigned *ioflags,
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "can't read message from fractal heap.")
/* Decode the message */
- if(NULL == (ret_value = (type->decode)(f, dxpl_id, 0, ioflags, mesg_ptr)))
+ if(NULL == (ret_value = (type->decode)(f, dxpl_id, open_oh, 0, ioflags, mesg_ptr)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode shared message.")
} /* end if */
else {
@@ -167,12 +167,22 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, unsigned *ioflags,
HDassert(shared->type == H5O_SHARE_TYPE_COMMITTED);
- /* Get the shared message from an object header */
+ /* Build the object location for the shared message's object header */
oloc.file = f;
oloc.addr = shared->u.loc.oh_addr;
oloc.holding_file = FALSE;
- if(NULL == (ret_value = H5O_msg_read(&oloc, type->id, NULL, dxpl_id)))
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read message")
+
+ if(open_oh && oloc.addr == H5O_OH_GET_ADDR(open_oh)) {
+ /* The shared message is in the already opened object header. This
+ * is possible, for example, if an attribute's datatype is shared in
+ * the same object header the attribute is in. Read the message
+ * directly. */
+ if(NULL == (ret_value = H5O_msg_read_oh(f, dxpl_id, open_oh, type->id, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read message")
+ } else
+ /* The shared message is in another object header */
+ if(NULL == (ret_value = H5O_msg_read(&oloc, type->id, NULL, dxpl_id)))
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read message")
} /* end else */
/* Mark the message as shared */
@@ -228,7 +238,7 @@ H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
H5O_loc_t oloc; /* Location for object header where message is stored */
/*
- * The shared message is stored in some other object header.
+ * The shared message is stored in some object header.
* The other object header must be in the same file as the
* new object header. Adjust the reference count on that
* object header.
@@ -236,13 +246,26 @@ H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
if(shared->file->shared != f->shared)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "interfile hard links are not allowed")
- /* Get the shared message from an object header */
+ /* Build the object location for the shared message's object header */
oloc.file = f;
oloc.addr = shared->u.loc.oh_addr;
oloc.holding_file = FALSE;
- if(H5O_link(&oloc, adjust, dxpl_id) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count")
+ if(open_oh && oloc.addr == H5O_OH_GET_ADDR(open_oh)) {
+ /* The shared message is in the already opened object header. This
+ * is possible, for example, if an attribute's datatype is shared in
+ * the same object header the attribute is in. Adjust the link
+ * count directly. */
+ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* This is used only to satisfy H5O_link_oh */
+
+ if(H5O_link_oh(f, adjust, dxpl_id, open_oh, &oh_flags) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count")
+
+ HDassert(!(oh_flags & H5AC__DELETED_FLAG));
+ } else
+ /* The shared message is in another object header */
+ if(H5O_link(&oloc, adjust, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared object link count")
} /* end if */
else {
HDassert(shared->type == H5O_SHARE_TYPE_SOHM || shared->type == H5O_SHARE_TYPE_HERE);
@@ -277,7 +300,7 @@ done:
*-------------------------------------------------------------------------
*/
void *
-H5O_shared_decode(H5F_t *f, hid_t dxpl_id, unsigned *ioflags,
+H5O_shared_decode(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned *ioflags,
const uint8_t *buf, const H5O_msg_class_t *type)
{
H5O_shared_t sh_mesg; /* Shared message info */
@@ -344,7 +367,7 @@ H5O_shared_decode(H5F_t *f, hid_t dxpl_id, unsigned *ioflags,
sh_mesg.msg_type_id = type->id;
/* Retrieve actual message, through decoded shared message info */
- if(NULL == (ret_value = H5O_shared_read(f, dxpl_id, ioflags, &sh_mesg, type)))
+ if(NULL == (ret_value = H5O_shared_read(f, dxpl_id, open_oh, ioflags, &sh_mesg, type)))
HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to retrieve native message")
done: