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