1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the files COPYING and Copyright.html.  COPYING can be found at the root   *
9  * of the source code distribution tree; Copyright.html can be found at the  *
10  * root level of an installed copy of the electronic HDF5 document set and   *
11  * is linked from the top-level documents page.  It can also be found at     *
12  * http://hdfgroup.org/HDF5/doc/Copyright.html.  If you do not have          *
13  * access to either file, you may request a copy from help@hdfgroup.org.     *
14  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /*
17  * Programmer:	Quincey Koziol <koziol@hdfgroup.org>
18  *		Friday, January 19, 2007
19  *
20  * Purpose:	This file contains inline definitions for "generic" routines
21  *		supporting a "shared message interface" (ala Java) for object
22  *		header messages that can be shared.  This interface is
23  *              dependent on a bunch of macros being defined which define
24  *              the name of the interface and "real" methods which need to
25  *              be implemented for each message class that supports the
26  *              shared message interface.
27  */
28 
29 #ifndef H5Oshared_H
30 #define H5Oshared_H
31 
32 
33 /*-------------------------------------------------------------------------
34  * Function:    H5O_SHARED_DECODE
35  *
36  * Purpose:     Decode an object header message that may be shared.
37  *
38  * Note:	The actual name of this routine can be different in each source
39  *		file that this header file is included in, and must be defined
40  *		prior to including this header file.
41  *
42  * Return:      Success:        Pointer to the new message in native form
43  *              Failure:        NULL
44  *
45  * Programmer:  Quincey Koziol
46  *              Friday, January 19, 2007
47  *
48  *-------------------------------------------------------------------------
49  */
50 static H5_inline void *
H5O_SHARED_DECODE(H5F_t * f,hid_t dxpl_id,H5O_t * open_oh,unsigned mesg_flags,unsigned * ioflags,const uint8_t * p)51 H5O_SHARED_DECODE(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned mesg_flags,
52     unsigned *ioflags, const uint8_t *p)
53 {
54     void *ret_value;            /* Return value */
55 
56     FUNC_ENTER_NOAPI_NOINIT
57 
58 #ifndef H5O_SHARED_TYPE
59 #error "Need to define H5O_SHARED_TYPE macro!"
60 #endif /* H5O_SHARED_TYPE */
61 #ifndef H5O_SHARED_DECODE
62 #error "Need to define H5O_SHARED_DECODE macro!"
63 #endif /* H5O_SHARED_DECODE */
64 #ifndef H5O_SHARED_DECODE_REAL
65 #error "Need to define H5O_SHARED_DECODE_REAL macro!"
66 #endif /* H5O_SHARED_DECODE_REAL */
67 
68     /* Check for shared message */
69     if(mesg_flags & H5O_MSG_FLAG_SHARED) {
70         /* Retrieve native message info indirectly through shared message */
71         if(NULL == (ret_value = H5O_shared_decode(f, dxpl_id, open_oh, ioflags, p, H5O_SHARED_TYPE)))
72 	    HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message")
73 
74         /* We currently do not support automatically fixing shared messages */
75 #ifdef H5_STRICT_FORMAT_CHECKS
76         if(*ioflags & H5O_DECODEIO_DIRTY)
77             HGOTO_ERROR(H5E_OHDR, H5E_UNSUPPORTED, NULL, "unable to mark shared message dirty")
78 #else /* H5_STRICT_FORMAT_CHECKS */
79         *ioflags &= ~H5O_DECODEIO_DIRTY;
80 #endif /* H5_STRICT_FORMAT_CHECKS */
81     } /* end if */
82     else {
83         /* Decode native message directly */
84         if(NULL == (ret_value = H5O_SHARED_DECODE_REAL(f, dxpl_id, open_oh, mesg_flags, ioflags, p)))
85 	    HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode native message")
86     } /* end else */
87 
88 done:
89     FUNC_LEAVE_NOAPI(ret_value)
90 } /* end H5O_SHARED_DECODE() */
91 
92 
93 /*-------------------------------------------------------------------------
94  * Function:    H5O_SHARED_ENCODE
95  *
96  * Purpose:     Encode an object header message that may be shared.
97  *
98  * Note:	The actual name of this routine can be different in each source
99  *		file that this header file is included in, and must be defined
100  *		prior to including this header file.
101  *
102  * Return:      Success:        Non-negative
103  *              Failure:        Negative
104  *
105  * Programmer:  Quincey Koziol
106  *              Friday, January 19, 2007
107  *
108  *-------------------------------------------------------------------------
109  */
110 static H5_inline herr_t
H5O_SHARED_ENCODE(H5F_t * f,hbool_t disable_shared,uint8_t * p,const void * _mesg)111 H5O_SHARED_ENCODE(H5F_t *f, hbool_t disable_shared, uint8_t *p, const void *_mesg)
112 {
113     const H5O_shared_t *sh_mesg = (const H5O_shared_t *)_mesg;     /* Pointer to shared message portion of actual message */
114     herr_t ret_value = SUCCEED;         /* Return value */
115 
116     FUNC_ENTER_NOAPI_NOINIT
117 
118 #ifndef H5O_SHARED_TYPE
119 #error "Need to define H5O_SHARED_TYPE macro!"
120 #endif /* H5O_SHARED_TYPE */
121 #ifndef H5O_SHARED_ENCODE
122 #error "Need to define H5O_SHARED_ENCODE macro!"
123 #endif /* H5O_SHARED_ENCODE */
124 #ifndef H5O_SHARED_ENCODE_REAL
125 #error "Need to define H5O_SHARED_ENCODE_REAL macro!"
126 #endif /* H5O_SHARED_ENCODE_REAL */
127 
128     /* Sanity check */
129     HDassert(sh_mesg->type == H5O_SHARE_TYPE_UNSHARED || sh_mesg->msg_type_id == H5O_SHARED_TYPE->id);
130 
131     /* Check for message stored elsewhere */
132     if(H5O_IS_STORED_SHARED(sh_mesg->type) && !disable_shared) {
133         /* Encode shared message into buffer */
134         if(H5O_shared_encode(f, p, sh_mesg) < 0)
135 	    HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode shared message")
136     } /* end if */
137     else {
138         /* Encode native message directly */
139         if(H5O_SHARED_ENCODE_REAL(f, p, _mesg) < 0)
140 	    HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode native message")
141     } /* end else */
142 
143 done:
144     FUNC_LEAVE_NOAPI(ret_value)
145 } /* end H5O_SHARED_ENCODE() */
146 
147 
148 /*-------------------------------------------------------------------------
149  * Function:    H5O_SHARED_SIZE
150  *
151  * Purpose:	Returns the length of an encoded message.
152  *
153  * Note:	The actual name of this routine can be different in each source
154  *		file that this header file is included in, and must be defined
155  *		prior to including this header file.
156  *
157  * Return:	Success:	Length
158  *		Failure:	0
159  *
160  * Programmer:  Quincey Koziol
161  *              Friday, January 19, 2007
162  *
163  *-------------------------------------------------------------------------
164  */
165 static H5_inline size_t
H5O_SHARED_SIZE(const H5F_t * f,hbool_t disable_shared,const void * _mesg)166 H5O_SHARED_SIZE(const H5F_t *f, hbool_t disable_shared, const void *_mesg)
167 {
168     const H5O_shared_t *sh_mesg = (const H5O_shared_t *)_mesg;     /* Pointer to shared message portion of actual message */
169     size_t ret_value;           /* Return value */
170 
171     FUNC_ENTER_NOAPI_NOINIT
172 
173 #ifndef H5O_SHARED_TYPE
174 #error "Need to define H5O_SHARED_TYPE macro!"
175 #endif /* H5O_SHARED_TYPE */
176 #ifndef H5O_SHARED_SIZE
177 #error "Need to define H5O_SHARED_SIZE macro!"
178 #endif /* H5O_SHARED_SIZE */
179 #ifndef H5O_SHARED_SIZE_REAL
180 #error "Need to define H5O_SHARED_SIZE_REAL macro!"
181 #endif /* H5O_SHARED_SIZE_REAL */
182 
183     /* Check for message stored elsewhere */
184     if(H5O_IS_STORED_SHARED(sh_mesg->type) && !disable_shared) {
185         /* Retrieve encoded size of shared message */
186         if(0 == (ret_value = H5O_shared_size(f, sh_mesg)))
187 	    HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, 0, "unable to retrieve encoded size of shared message")
188     } /* end if */
189     else {
190         /* Retrieve size of native message directly */
191         if(0 == (ret_value = H5O_SHARED_SIZE_REAL(f, _mesg)))
192 	    HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, 0, "unable to retrieve encoded size of native message")
193     } /* end else */
194 
195 done:
196     FUNC_LEAVE_NOAPI(ret_value)
197 } /* end H5O_SHARED_SIZE() */
198 
199 
200 /*-------------------------------------------------------------------------
201  * Function:    H5O_SHARED_DELETE
202  *
203  * Purpose:     Decrement reference count on any objects referenced by
204  *              message
205  *
206  * Note:	The actual name of this routine can be different in each source
207  *		file that this header file is included in, and must be defined
208  *		prior to including this header file.
209  *
210  * Return:	Success:	Non-negative
211  *		Failure:	Negative
212  *
213  * Programmer:  Quincey Koziol
214  *              Friday, January 19, 2007
215  *
216  *-------------------------------------------------------------------------
217  */
218 static H5_inline herr_t
H5O_SHARED_DELETE(H5F_t * f,hid_t dxpl_id,H5O_t * open_oh,void * _mesg)219 H5O_SHARED_DELETE(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg)
220 {
221     H5O_shared_t *sh_mesg = (H5O_shared_t *)_mesg;     /* Pointer to shared message portion of actual message */
222     herr_t ret_value = SUCCEED;         /* Return value */
223 
224     FUNC_ENTER_NOAPI_NOINIT
225 
226 #ifndef H5O_SHARED_TYPE
227 #error "Need to define H5O_SHARED_TYPE macro!"
228 #endif /* H5O_SHARED_TYPE */
229 #ifndef H5O_SHARED_DELETE
230 #error "Need to define H5O_SHARED_DELETE macro!"
231 #endif /* H5O_SHARED_DELETE */
232 
233     /* Check for message tracked elsewhere */
234     if(H5O_IS_TRACKED_SHARED(sh_mesg->type)) {
235         /* Decrement the reference count on the shared message/object */
236         if(H5O_shared_delete(f, dxpl_id, open_oh, H5O_SHARED_TYPE, sh_mesg) < 0)
237 	    HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement ref count for shared message")
238     } /* end if */
239 #ifdef H5O_SHARED_DELETE_REAL
240     else {
241         /* Decrement the reference count on the native message directly */
242         if(H5O_SHARED_DELETE_REAL(f, dxpl_id, open_oh, _mesg) < 0)
243 	    HGOTO_ERROR(H5E_OHDR, H5E_CANTDEC, FAIL, "unable to decrement ref count for native message")
244     } /* end else */
245 #endif /* H5O_SHARED_DELETE_REAL */
246 
247 done:
248     FUNC_LEAVE_NOAPI(ret_value)
249 } /* end H5O_SHARED_DELETE() */
250 
251 
252 /*-------------------------------------------------------------------------
253  * Function:    H5O_SHARED_LINK
254  *
255  * Purpose:     Increment reference count on any objects referenced by
256  *              message
257  *
258  * Note:	The actual name of this routine can be different in each source
259  *		file that this header file is included in, and must be defined
260  *		prior to including this header file.
261  *
262  * Return:	Success:	Non-negative
263  *		Failure:	Negative
264  *
265  * Programmer:  Quincey Koziol
266  *              Friday, January 19, 2007
267  *
268  *-------------------------------------------------------------------------
269  */
270 static H5_inline herr_t
H5O_SHARED_LINK(H5F_t * f,hid_t dxpl_id,H5O_t * open_oh,void * _mesg)271 H5O_SHARED_LINK(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, void *_mesg)
272 {
273     H5O_shared_t *sh_mesg = (H5O_shared_t *)_mesg;     /* Pointer to shared message portion of actual message */
274     herr_t ret_value = SUCCEED;         /* Return value */
275 
276     FUNC_ENTER_NOAPI_NOINIT
277 
278 #ifndef H5O_SHARED_TYPE
279 #error "Need to define H5O_SHARED_TYPE macro!"
280 #endif /* H5O_SHARED_TYPE */
281 #ifndef H5O_SHARED_LINK
282 #error "Need to define H5O_SHARED_LINK macro!"
283 #endif /* H5O_SHARED_LINK */
284 
285     /* Check for message tracked elsewhere */
286     if(H5O_IS_TRACKED_SHARED(sh_mesg->type)) {
287         /* Increment the reference count on the shared message/object */
288         if(H5O_shared_link(f, dxpl_id, open_oh, H5O_SHARED_TYPE, sh_mesg) < 0)
289 	    HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "unable to increment ref count for shared message")
290     } /* end if */
291 #ifdef H5O_SHARED_LINK_REAL
292     else {
293         /* Increment the reference count on the native message directly */
294         if(H5O_SHARED_LINK_REAL(f, dxpl_id, open_oh, _mesg) < 0)
295 	    HGOTO_ERROR(H5E_OHDR, H5E_CANTINC, FAIL, "unable to increment ref count for native message")
296     } /* end else */
297 #endif /* H5O_SHARED_LINK_REAL */
298 
299 done:
300     FUNC_LEAVE_NOAPI(ret_value)
301 } /* end H5O_SHARED_LINK() */
302 
303 
304 /*-------------------------------------------------------------------------
305  * Function:    H5O_SHARED_COPY_FILE
306  *
307  * Purpose:     Copies a message from _SRC to _DEST in file
308  *
309  * Note:	The actual name of this routine can be different in each source
310  *		file that this header file is included in, and must be defined
311  *		prior to including this header file.
312  *
313  * Return:	Success:	Non-negative
314  *		Failure:	Negative
315  *
316  * Programmer:  Quincey Koziol
317  *              Friday, January 19, 2007
318  *
319  *-------------------------------------------------------------------------
320  */
321 static H5_inline void *
H5O_SHARED_COPY_FILE(H5F_t * file_src,void * _native_src,H5F_t * file_dst,hbool_t * recompute_size,unsigned * mesg_flags,H5O_copy_t * cpy_info,void * udata,hid_t dxpl_id)322 H5O_SHARED_COPY_FILE(H5F_t *file_src, void *_native_src, H5F_t *file_dst,
323     hbool_t *recompute_size, unsigned *mesg_flags, H5O_copy_t *cpy_info,
324     void *udata, hid_t dxpl_id)
325 {
326     void *dst_mesg = NULL;      /* Destination message */
327     void *ret_value;            /* Return value */
328 
329     FUNC_ENTER_NOAPI_NOINIT
330 
331 #ifndef H5O_SHARED_TYPE
332 #error "Need to define H5O_SHARED_TYPE macro!"
333 #endif /* H5O_SHARED_TYPE */
334 #ifndef H5O_SHARED_COPY_FILE
335 #error "Need to define H5O_SHARED_COPY_FILE macro!"
336 #endif /* H5O_SHARED_COPY_FILE */
337 
338 #ifdef H5O_SHARED_COPY_FILE_REAL
339     /* Call native message's copy file callback to copy the message */
340     if(NULL == (dst_mesg = H5O_SHARED_COPY_FILE_REAL(file_src, H5O_SHARED_TYPE, _native_src, file_dst, recompute_size, cpy_info, udata, dxpl_id)))
341         HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy native message to another file")
342 #else /* H5O_SHARED_COPY_FILE_REAL */
343     /* No copy file callback defined, just copy the message itself */
344     if(NULL == (dst_mesg = (H5O_SHARED_TYPE->copy)(_native_src, NULL)))
345         HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy native message")
346 #endif /* H5O_SHARED_COPY_FILE_REAL */
347 
348     /* Reset shared message info for new message */
349     HDmemset(dst_mesg, 0, sizeof(H5O_shared_t));
350 
351     /* Handle sharing destination message */
352     if(H5O_shared_copy_file(file_src, file_dst, H5O_SHARED_TYPE, _native_src,
353             dst_mesg, recompute_size, mesg_flags, cpy_info, udata, dxpl_id) < 0)
354         HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, NULL, "unable to determine if message should be shared")
355 
356     /* Set return value */
357     ret_value = dst_mesg;
358 
359 done:
360     if(!ret_value)
361         if(dst_mesg)
362             H5O_msg_free(H5O_SHARED_TYPE->id, dst_mesg);
363 
364     FUNC_LEAVE_NOAPI(ret_value)
365 } /* end H5O_SHARED_COPY_FILE() */
366 
367 
368 /*-------------------------------------------------------------------------
369  * Function:    H5O_SHARED_POST_COPY_FILE
370  *
371  * Purpose:     Copies a message from _SRC to _DEST in file
372  *
373  * Note:        The actual name of this routine can be different in each source
374  *              file that this header file is included in, and must be defined
375  *              prior to including this header file.
376  *
377  * Return:      Success:        Non-negative
378  *              Failure:        Negative
379  *
380  * Programmer:  Peter Cao
381  *              May 25, 2007
382  *
383  *-------------------------------------------------------------------------
384  */
385 static H5_inline herr_t
H5O_SHARED_POST_COPY_FILE(const H5O_loc_t * oloc_src,const void * mesg_src,H5O_loc_t * oloc_dst,void * mesg_dst,unsigned * mesg_flags,hid_t dxpl_id,H5O_copy_t * cpy_info)386 H5O_SHARED_POST_COPY_FILE(const H5O_loc_t *oloc_src, const void *mesg_src,
387     H5O_loc_t *oloc_dst, void *mesg_dst, unsigned *mesg_flags, hid_t dxpl_id,
388     H5O_copy_t *cpy_info)
389 {
390     const H5O_shared_t  *shared_src = (const H5O_shared_t *)mesg_src; /* Alias to shared info in native source */
391     H5O_shared_t        *shared_dst = (H5O_shared_t *)mesg_dst; /* Alias to shared info in native destination */
392     herr_t              ret_value = SUCCEED;         /* Return value */
393 
394     FUNC_ENTER_NOAPI_NOINIT
395 
396     HDassert(oloc_src->file);
397     HDassert(oloc_dst->file);
398     HDassert(mesg_src);
399     HDassert(mesg_dst);
400     HDassert(cpy_info);
401 
402 #ifndef H5O_SHARED_TYPE
403 #error "Need to define H5O_SHARED_TYPE macro!"
404 #endif /* H5O_SHARED_TYPE */
405 #ifndef H5O_SHARED_POST_COPY_FILE
406 #error "Need to define H5O_SHARED_POST_COPY_FILE macro!"
407 #endif /* H5O_SHARED_POST_COPY_FILE */
408 
409 #ifdef H5O_SHARED_POST_COPY_FILE_REAL
410     /* Call native message's post copy file callback to copy the message */
411     if(H5O_SHARED_POST_COPY_FILE_REAL(oloc_src, mesg_src, oloc_dst, mesg_dst, dxpl_id, cpy_info) <0 )
412         HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy native message to another file")
413 #endif /* H5O_SHARED_POST_COPY_FILE_REAL */
414 
415     /* Update shared message after the post copy - will short circuit in
416      * production if the DEFER pass determined it will not be shared; debug mode
417      * verifies that it is indeed the case */
418     if(H5O_shared_post_copy_file(oloc_dst->file, H5O_SHARED_TYPE,
419             shared_src, shared_dst, mesg_flags, dxpl_id, cpy_info) < 0)
420         HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to fix shared message in post copy")
421 
422 #ifdef H5O_SHARED_POST_COPY_FILE_UPD
423     /* Call native message's post copy file update callback to update the
424      * message */
425     if(H5O_SHARED_POST_COPY_FILE_UPD(oloc_src, mesg_src, oloc_dst, mesg_dst, dxpl_id, cpy_info) < 0)
426         HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to update native message")
427 #endif /* H5O_SHARED_POST_COPY_FILE_UPD */
428 
429     /* Make sure that if the the source or destination is committed, both are
430      * committed */
431     HDassert((shared_src->type == H5O_SHARE_TYPE_COMMITTED)
432             == (shared_dst->type == H5O_SHARE_TYPE_COMMITTED));
433 
434 done:
435     FUNC_LEAVE_NOAPI(ret_value)
436 } /* end H5O_SHARED_POST_COPY_FILE() */
437 
438 
439 /*-------------------------------------------------------------------------
440  * Function:    H5O_SHARED_DEBUG
441  *
442  * Purpose:     Prints debugging info for a potentially shared message.
443  *
444  * Note:	The actual name of this routine can be different in each source
445  *		file that this header file is included in, and must be defined
446  *		prior to including this header file.
447  *
448  * Return:	Success:	Non-negative
449  *		Failure:	Negative
450  *
451  * Programmer:  Quincey Koziol
452  *              Saturday, February  3, 2007
453  *
454  *-------------------------------------------------------------------------
455  */
456 static H5_inline herr_t
H5O_SHARED_DEBUG(H5F_t * f,hid_t dxpl_id,const void * _mesg,FILE * stream,int indent,int fwidth)457 H5O_SHARED_DEBUG(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *stream,
458     int indent, int fwidth)
459 {
460     const H5O_shared_t *sh_mesg = (const H5O_shared_t *)_mesg;     /* Pointer to shared message portion of actual message */
461     herr_t ret_value = SUCCEED;           /* Return value */
462 
463     FUNC_ENTER_NOAPI_NOINIT
464 
465 #ifndef H5O_SHARED_TYPE
466 #error "Need to define H5O_SHARED_TYPE macro!"
467 #endif /* H5O_SHARED_TYPE */
468 #ifndef H5O_SHARED_DEBUG
469 #error "Need to define H5O_SHARED_DEBUG macro!"
470 #endif /* H5O_SHARED_DEBUG */
471 #ifndef H5O_SHARED_DEBUG_REAL
472 #error "Need to define H5O_SHARED_DEBUG_REAL macro!"
473 #endif /* H5O_SHARED_DEBUG_REAL */
474 
475     /* Check for message stored elsewhere */
476     if(H5O_IS_STORED_SHARED(sh_mesg->type)) {
477         /* Print shared message information */
478         if(H5O_shared_debug(sh_mesg, stream, indent, fwidth) < 0)
479             HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to display shared message info")
480     } /* end if */
481 
482     /* Call native message's debug callback */
483     if(H5O_SHARED_DEBUG_REAL(f, dxpl_id, _mesg, stream, indent, fwidth) < 0)
484         HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to display native message info")
485 
486 done:
487     FUNC_LEAVE_NOAPI(ret_value)
488 } /* end H5O_SHARED_DEBUG() */
489 
490 #endif /* H5Oshared_H */
491 
492