diff options
Diffstat (limited to 'src/H5Oshared.c')
-rw-r--r-- | src/H5Oshared.c | 45 |
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: |