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