Coverage Report

Created: 2026-04-15 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/hdf5/src/H5CX.c
Line
Count
Source
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
 * Copyright by The HDF Group.                                               *
3
 * All rights reserved.                                                      *
4
 *                                                                           *
5
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6
 * terms governing use, modification, and redistribution, is contained in    *
7
 * the LICENSE file, which can be found at the root of the source code       *
8
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
9
 * If you do not have access to either file, you may request a copy from     *
10
 * help@hdfgroup.org.                                                        *
11
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13
/*
14
 * Purpose:
15
 *      Keep a set of "psuedo-global" information for an API call.  This
16
 *      general corresponds to the DXPL for the call, along with cached
17
 *      information from them.
18
 */
19
20
/****************/
21
/* Module Setup */
22
/****************/
23
24
#include "H5CXmodule.h" /* This source code file is part of the H5CX module */
25
26
/***********/
27
/* Headers */
28
/***********/
29
#include "H5private.h"   /* Generic Functions                    */
30
#include "H5CXprivate.h" /* API Contexts                         */
31
#include "H5Dprivate.h"  /* Datasets                             */
32
#include "H5Eprivate.h"  /* Error handling                       */
33
#include "H5FLprivate.h" /* Free Lists                           */
34
#include "H5Iprivate.h"  /* IDs                                  */
35
#include "H5Lprivate.h"  /* Links                                */
36
#include "H5MMprivate.h" /* Memory management                    */
37
#include "H5Pprivate.h"  /* Property lists                       */
38
39
/****************/
40
/* Local Macros */
41
/****************/
42
43
#ifdef H5_HAVE_THREADSAFE_API
44
/*
45
 * The per-thread API context.
46
 *
47
 * In order for this macro to work, H5CX_get_my_context() must be preceded
48
 * by "H5CX_node_t **ctx =".
49
 */
50
#define H5CX_get_my_context() H5TS_get_api_ctx_ptr()
51
#else /* H5_HAVE_THREADSAFE_API */
52
/*
53
 * The current API context.
54
 */
55
4.89k
#define H5CX_get_my_context() (&H5CX_head_g)
56
#endif /* H5_HAVE_THREADSAFE_API */
57
58
/* Common macro for the retrieving the pointer to a property list */
59
#define H5CX_RETRIEVE_PLIST(PL, FAILVAL)                                                                     \
60
    /* Check if the property list is already available */                                                    \
61
0
    if (NULL == (*head)->ctx.PL)                                                                             \
62
0
        /* Get the property list pointer */                                                                  \
63
0
        if (H5_UNLIKELY(NULL ==                                                                              \
64
0
                        ((*head)->ctx.PL = (H5P_genplist_t *)H5I_object((*head)->ctx.H5_GLUE(PL, _id)))))    \
65
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, (FAILVAL), "can't get property list");
66
67
/* Common macro for the duplicated code to retrieve properties from a property list */
68
#define H5CX_RETRIEVE_PROP_COMMON(PL, DEF_PL, PROP_NAME, PROP_FIELD)                                         \
69
1
    {                                                                                                        \
70
1
                                                                                                             \
71
1
        /* Check for default property list */                                                                \
72
1
        if ((*head)->ctx.H5_GLUE(PL, _id) == (DEF_PL))                                                       \
73
1
            H5MM_memcpy(&(*head)->ctx.PROP_FIELD, &H5_GLUE3(H5CX_def_, PL, _cache).PROP_FIELD,               \
74
1
                        sizeof(H5_GLUE3(H5CX_def_, PL, _cache).PROP_FIELD));                                 \
75
1
        else {                                                                                               \
76
0
            /* Retrieve the property list */                                                                 \
77
0
            H5CX_RETRIEVE_PLIST(PL, FAIL)                                                                    \
78
0
                                                                                                             \
79
0
            /* Get the property */                                                                           \
80
0
            if (H5_UNLIKELY(H5P_get((*head)->ctx.PL, (PROP_NAME), &(*head)->ctx.PROP_FIELD) < 0))            \
81
0
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't retrieve value from API context");        \
82
0
        } /* end else */                                                                                     \
83
1
                                                                                                             \
84
1
        /* Mark the field as valid */                                                                        \
85
1
        (*head)->ctx.H5_GLUE(PROP_FIELD, _valid) = true;                                                     \
86
1
    }
87
88
/* Macro for the duplicated code to retrieve a value from a plist if the context value is invalid */
89
#define H5CX_RETRIEVE_PROP_VALID(PL, DEF_PL, PROP_NAME, PROP_FIELD)                                          \
90
    /* Check if the value has been retrieved already */                                                      \
91
1
    if (!(*head)->ctx.H5_GLUE(PROP_FIELD, _valid))                                                           \
92
1
    H5CX_RETRIEVE_PROP_COMMON(PL, DEF_PL, PROP_NAME, PROP_FIELD)
93
94
/* Macro for the duplicated code to retrieve a value from a plist if the context value is invalid, or the
95
 * library has previously modified the context value for return */
96
#define H5CX_RETRIEVE_PROP_VALID_SET(PL, DEF_PL, PROP_NAME, PROP_FIELD)                                      \
97
    /* Check if the value has been retrieved already */                                                      \
98
0
    if (!((*head)->ctx.H5_GLUE(PROP_FIELD, _valid) || (*head)->ctx.H5_GLUE(PROP_FIELD, _set)))               \
99
0
    H5CX_RETRIEVE_PROP_COMMON(PL, DEF_PL, PROP_NAME, PROP_FIELD)
100
101
#if defined(H5_HAVE_PARALLEL) && defined(H5_HAVE_INSTRUMENTED_LIBRARY)
102
/* Macro for the duplicated code to set a context field that may not exist as a property */
103
#define H5CX_TEST_SET_PROP(PROP_NAME, PROP_FIELD)                                                            \
104
    {                                                                                                        \
105
        htri_t check_prop = 0; /* Whether the property exists in the API context's DXPL */                   \
106
                                                                                                             \
107
        /* Check if property exists in DXPL */                                                               \
108
        if (!(*head)->ctx.H5_GLUE(PROP_FIELD, _set)) {                                                       \
109
            /* Retrieve the dataset transfer property list */                                                \
110
            H5CX_RETRIEVE_PLIST(dxpl, FAIL)                                                                  \
111
                                                                                                             \
112
            if (H5_UNLIKELY((check_prop = H5P_exist_plist((*head)->ctx.dxpl, PROP_NAME)) < 0))               \
113
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "error checking for property");                  \
114
        } /* end if */                                                                                       \
115
                                                                                                             \
116
        /* If property was already set or exists (for first set), update it */                               \
117
        if ((*head)->ctx.H5_GLUE(PROP_FIELD, _set) || check_prop > 0) {                                      \
118
            /* Cache the value for later, marking it to set in DXPL when context popped */                   \
119
            (*head)->ctx.PROP_FIELD                = PROP_FIELD;                                             \
120
            (*head)->ctx.H5_GLUE(PROP_FIELD, _set) = true;                                                   \
121
        } /* end if */                                                                                       \
122
    }
123
#endif /* defined(H5_HAVE_PARALLEL) && defined(H5_HAVE_INSTRUMENTED_LIBRARY) */
124
125
/* Macro for the duplicated code to test and set properties for a property list from the context */
126
#define H5CX_SET_PROP(PROP_NAME, PROP_FIELD)                                                                 \
127
226
    if ((*head)->ctx.H5_GLUE(PROP_FIELD, _set)) {                                                            \
128
0
        /* Retrieve the dataset transfer property list */                                                    \
129
0
        H5CX_RETRIEVE_PLIST(dxpl, FAIL)                                                                      \
130
0
                                                                                                             \
131
0
        /* Set the property */                                                                               \
132
0
        if (H5_UNLIKELY(H5P_set((*head)->ctx.dxpl, PROP_NAME, &(*head)->ctx.PROP_FIELD) < 0))                \
133
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTSET, FAIL, "error setting data xfer property");                 \
134
0
    } /* end if */
135
136
/******************/
137
/* Local Typedefs */
138
/******************/
139
140
/* Typedef for cached default dataset transfer property list information */
141
/* This is initialized to the values in the default DXPL during package
142
 * initialization and then remains constant for the rest of the library's
143
 * operation.  When a field in H5CX_t is retrieved from an API context that
144
 * uses a default DXPL, this value is copied instead of spending time looking
145
 * up the property in the DXPL.
146
 */
147
typedef struct H5CX_dxpl_cache_t {
148
    size_t    max_temp_buf;         /* Maximum temporary buffer size (H5D_XFER_MAX_TEMP_BUF_NAME) */
149
    void     *tconv_buf;            /* Temporary conversion buffer (H5D_XFER_TCONV_BUF_NAME) */
150
    void     *bkgr_buf;             /* Background conversion buffer (H5D_XFER_BKGR_BUF_NAME) */
151
    H5T_bkg_t bkgr_buf_type;        /* Background buffer type (H5D_XFER_BKGR_BUF_NAME) */
152
    double    btree_split_ratio[3]; /* B-tree split ratios (H5D_XFER_BTREE_SPLIT_RATIO_NAME) */
153
    size_t    vec_size;             /* Size of hyperslab vector (H5D_XFER_HYPER_VECTOR_SIZE_NAME) */
154
#ifdef H5_HAVE_PARALLEL
155
    H5FD_mpio_xfer_t io_xfer_mode; /* Parallel transfer mode for this request (H5D_XFER_IO_XFER_MODE_NAME) */
156
    H5FD_mpio_collective_opt_t mpio_coll_opt; /* Parallel transfer with independent IO or collective IO with
157
                                                 this mode (H5D_XFER_MPIO_COLLECTIVE_OPT_NAME) */
158
    uint32_t mpio_local_no_coll_cause;        /* Local reason for breaking collective I/O
159
                                                 (H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME) */
160
    uint32_t mpio_global_no_coll_cause;       /* Global reason for breaking collective I/O
161
                                                 (H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME) */
162
    H5FD_mpio_chunk_opt_t
163
             mpio_chunk_opt_mode;       /* Collective chunk option (H5D_XFER_MPIO_CHUNK_OPT_HARD_NAME) */
164
    unsigned mpio_chunk_opt_num;        /* Collective chunk threshold (H5D_XFER_MPIO_CHUNK_OPT_NUM_NAME) */
165
    unsigned mpio_chunk_opt_ratio;      /* Collective chunk ratio (H5D_XFER_MPIO_CHUNK_OPT_RATIO_NAME) */
166
#endif                                  /* H5_HAVE_PARALLEL */
167
    H5Z_EDC_t               err_detect; /* Error detection info (H5D_XFER_EDC_NAME) */
168
    H5Z_cb_t                filter_cb;  /* Filter callback function (H5D_XFER_FILTER_CB_NAME) */
169
    H5Z_data_xform_t       *data_transform;        /* Data transform info (H5D_XFER_XFORM_NAME) */
170
    H5T_vlen_alloc_info_t   vl_alloc_info;         /* VL datatype alloc info (H5D_XFER_VLEN_*_NAME) */
171
    H5T_conv_cb_t           dt_conv_cb;            /* Datatype conversion struct (H5D_XFER_CONV_CB_NAME) */
172
    H5D_selection_io_mode_t selection_io_mode;     /* Selection I/O mode (H5D_XFER_SELECTION_IO_MODE_NAME) */
173
    uint32_t                no_selection_io_cause; /* Reasons for not performing selection I/O
174
                                                            (H5D_XFER_NO_SELECTION_IO_CAUSE_NAME) */
175
    uint32_t actual_selection_io_mode;             /* Actual selection I/O mode
176
                                                         (H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME) */
177
    bool modify_write_buf;                         /* Whether the library can modify write buffers */
178
} H5CX_dxpl_cache_t;
179
180
/* Typedef for cached default link creation property list information */
181
/* (Same as the cached DXPL struct, above, except for the default LCPL) */
182
typedef struct H5CX_lcpl_cache_t {
183
    H5T_cset_t encoding;           /* Link name character encoding */
184
    unsigned   intermediate_group; /* Whether to create intermediate groups  */
185
} H5CX_lcpl_cache_t;
186
187
/* Typedef for cached default link access property list information */
188
/* (Same as the cached DXPL struct, above, except for the default LAPL) */
189
typedef struct H5CX_lapl_cache_t {
190
    size_t nlinks; /* Number of soft / UD links to traverse (H5L_ACS_NLINKS_NAME) */
191
} H5CX_lapl_cache_t;
192
193
/* Typedef for cached default dataset creation property list information */
194
/* (Same as the cached DXPL struct, above, except for the default DCPL) */
195
typedef struct H5CX_dcpl_cache_t {
196
    bool    do_min_dset_ohdr; /* Whether to minimize dataset object header */
197
    uint8_t ohdr_flags;       /* Object header flags */
198
} H5CX_dcpl_cache_t;
199
200
/* Typedef for cached default dataset access property list information */
201
/* (Same as the cached DXPL struct, above, except for the default DXPL) */
202
typedef struct H5CX_dapl_cache_t {
203
    const char *extfile_prefix; /* Prefix for external file */
204
    const char *vds_prefix;     /* Prefix for VDS           */
205
} H5CX_dapl_cache_t;
206
207
/* Typedef for cached default file access property list information */
208
/* (Same as the cached DXPL struct, above, except for the default DCPL) */
209
typedef struct H5CX_fapl_cache_t {
210
    H5F_libver_t low_bound;  /* low_bound property for H5Pset_libver_bounds() */
211
    H5F_libver_t high_bound; /* high_bound property for H5Pset_libver_bounds */
212
} H5CX_fapl_cache_t;
213
214
/********************/
215
/* Local Prototypes */
216
/********************/
217
218
/*********************/
219
/* Package Variables */
220
/*********************/
221
222
/* Package initialization variable */
223
bool H5_PKG_INIT_VAR = false;
224
225
/*******************/
226
/* Local Variables */
227
/*******************/
228
229
#ifndef H5_HAVE_THREADSAFE_API
230
static H5CX_node_t *H5CX_head_g = NULL; /* Pointer to head of context stack */
231
#endif                                  /* H5_HAVE_THREADSAFE_API */
232
233
/* Define a "default" dataset transfer property list cache structure to use for default DXPLs */
234
static H5CX_dxpl_cache_t H5CX_def_dxpl_cache;
235
236
/* Define a "default" link creation property list cache structure to use for default LCPLs */
237
static H5CX_lcpl_cache_t H5CX_def_lcpl_cache;
238
239
/* Define a "default" link access property list cache structure to use for default LAPLs */
240
static H5CX_lapl_cache_t H5CX_def_lapl_cache;
241
242
/* Define a "default" dataset creation property list cache structure to use for default DCPLs */
243
static H5CX_dcpl_cache_t H5CX_def_dcpl_cache;
244
245
/* Define a "default" dataset access property list cache structure to use for default DAPLs */
246
static H5CX_dapl_cache_t H5CX_def_dapl_cache;
247
248
/* Define a "default" file access property list cache structure to use for default FAPLs */
249
static H5CX_fapl_cache_t H5CX_def_fapl_cache;
250
251
/* Declare a static free list to manage H5CX_state_t structs */
252
H5FL_DEFINE_STATIC(H5CX_state_t);
253
254
/*--------------------------------------------------------------------------
255
NAME
256
    H5CX__init_package -- Initialize interface-specific information
257
USAGE
258
    herr_t H5CX__init_package()
259
RETURNS
260
    Non-negative on success/Negative on failure
261
DESCRIPTION
262
    Initializes any interface-specific data or routines.
263
--------------------------------------------------------------------------*/
264
herr_t
265
H5CX__init_package(void)
266
2
{
267
2
    H5P_genplist_t *dx_plist;            /* Data transfer property list */
268
2
    H5P_genplist_t *lc_plist;            /* Link creation property list */
269
2
    H5P_genplist_t *la_plist;            /* Link access property list */
270
2
    H5P_genplist_t *dc_plist;            /* Dataset creation property list */
271
2
    H5P_genplist_t *da_plist;            /* Dataset access property list */
272
2
    H5P_genplist_t *fa_plist;            /* File access property list */
273
2
    herr_t          ret_value = SUCCEED; /* Return value */
274
275
2
    FUNC_ENTER_PACKAGE
276
277
    /* Reset the "default DXPL cache" information */
278
2
    memset(&H5CX_def_dxpl_cache, 0, sizeof(H5CX_dxpl_cache_t));
279
280
    /* Get the default DXPL cache information */
281
282
    /* Get the default dataset transfer property list */
283
2
    if (NULL == (dx_plist = (H5P_genplist_t *)H5I_object(H5P_DATASET_XFER_DEFAULT)))
284
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a dataset transfer property list");
285
286
    /* Get B-tree split ratios */
287
2
    if (H5P_get(dx_plist, H5D_XFER_BTREE_SPLIT_RATIO_NAME, &H5CX_def_dxpl_cache.btree_split_ratio) < 0)
288
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve B-tree split ratios");
289
290
    /* Get maximum temporary buffer size value */
291
2
    if (H5P_get(dx_plist, H5D_XFER_MAX_TEMP_BUF_NAME, &H5CX_def_dxpl_cache.max_temp_buf) < 0)
292
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve maximum temporary buffer size");
293
294
    /* Get temporary buffer pointer */
295
2
    if (H5P_get(dx_plist, H5D_XFER_TCONV_BUF_NAME, &H5CX_def_dxpl_cache.tconv_buf) < 0)
296
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve temporary buffer pointer");
297
298
    /* Get background buffer pointer */
299
2
    if (H5P_get(dx_plist, H5D_XFER_BKGR_BUF_NAME, &H5CX_def_dxpl_cache.bkgr_buf) < 0)
300
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve background buffer pointer");
301
302
    /* Get background buffer type */
303
2
    if (H5P_get(dx_plist, H5D_XFER_BKGR_BUF_TYPE_NAME, &H5CX_def_dxpl_cache.bkgr_buf_type) < 0)
304
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve background buffer type");
305
306
    /* Get I/O vector size */
307
2
    if (H5P_get(dx_plist, H5D_XFER_HYPER_VECTOR_SIZE_NAME, &H5CX_def_dxpl_cache.vec_size) < 0)
308
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve I/O vector size");
309
310
#ifdef H5_HAVE_PARALLEL
311
    /* Collect Parallel I/O information for possible later use */
312
    if (H5P_get(dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &H5CX_def_dxpl_cache.io_xfer_mode) < 0)
313
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve parallel transfer method");
314
    if (H5P_get(dx_plist, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME, &H5CX_def_dxpl_cache.mpio_coll_opt) < 0)
315
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve collective transfer option");
316
    if (H5P_get(dx_plist, H5D_XFER_MPIO_CHUNK_OPT_HARD_NAME, &H5CX_def_dxpl_cache.mpio_chunk_opt_mode) < 0)
317
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve chunk optimization option");
318
    if (H5P_get(dx_plist, H5D_XFER_MPIO_CHUNK_OPT_NUM_NAME, &H5CX_def_dxpl_cache.mpio_chunk_opt_num) < 0)
319
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve chunk optimization threshold");
320
    if (H5P_get(dx_plist, H5D_XFER_MPIO_CHUNK_OPT_RATIO_NAME, &H5CX_def_dxpl_cache.mpio_chunk_opt_ratio) < 0)
321
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve chunk optimization ratio");
322
323
    /* Get the local & global reasons for breaking collective I/O values */
324
    if (H5P_get(dx_plist, H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME,
325
                &H5CX_def_dxpl_cache.mpio_local_no_coll_cause) < 0)
326
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve local cause for breaking collective I/O");
327
    if (H5P_get(dx_plist, H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME,
328
                &H5CX_def_dxpl_cache.mpio_global_no_coll_cause) < 0)
329
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL,
330
                    "Can't retrieve global cause for breaking collective I/O");
331
#endif /* H5_HAVE_PARALLEL */
332
333
    /* Get error detection properties */
334
2
    if (H5P_get(dx_plist, H5D_XFER_EDC_NAME, &H5CX_def_dxpl_cache.err_detect) < 0)
335
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve error detection info");
336
337
    /* Get filter callback function */
338
2
    if (H5P_get(dx_plist, H5D_XFER_FILTER_CB_NAME, &H5CX_def_dxpl_cache.filter_cb) < 0)
339
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve filter callback function");
340
341
    /* Look at the data transform property */
342
    /* (Note: 'peek', not 'get' - if this turns out to be a problem, we may need
343
     *          to copy it and free this in the H5CX terminate routine. -QAK)
344
     */
345
2
    if (H5P_peek(dx_plist, H5D_XFER_XFORM_NAME, &H5CX_def_dxpl_cache.data_transform) < 0)
346
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve data transform info");
347
348
    /* Get VL datatype alloc info */
349
2
    if (H5P_get(dx_plist, H5D_XFER_VLEN_ALLOC_NAME, &H5CX_def_dxpl_cache.vl_alloc_info.alloc_func) < 0)
350
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve VL datatype alloc info");
351
2
    if (H5P_get(dx_plist, H5D_XFER_VLEN_ALLOC_INFO_NAME, &H5CX_def_dxpl_cache.vl_alloc_info.alloc_info) < 0)
352
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve VL datatype alloc info");
353
2
    if (H5P_get(dx_plist, H5D_XFER_VLEN_FREE_NAME, &H5CX_def_dxpl_cache.vl_alloc_info.free_func) < 0)
354
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve VL datatype alloc info");
355
2
    if (H5P_get(dx_plist, H5D_XFER_VLEN_FREE_INFO_NAME, &H5CX_def_dxpl_cache.vl_alloc_info.free_info) < 0)
356
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve VL datatype alloc info");
357
358
    /* Get datatype conversion struct */
359
2
    if (H5P_get(dx_plist, H5D_XFER_CONV_CB_NAME, &H5CX_def_dxpl_cache.dt_conv_cb) < 0)
360
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve datatype conversion exception callback");
361
362
    /* Get the selection I/O mode */
363
2
    if (H5P_get(dx_plist, H5D_XFER_SELECTION_IO_MODE_NAME, &H5CX_def_dxpl_cache.selection_io_mode) < 0)
364
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve selection I/O mode");
365
366
    /* Get the local & global reasons for breaking selection I/O values */
367
2
    if (H5P_get(dx_plist, H5D_XFER_NO_SELECTION_IO_CAUSE_NAME, &H5CX_def_dxpl_cache.no_selection_io_cause) <
368
2
        0)
369
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve cause for no selection I/O");
370
371
    /* Get the actual selection I/O mode */
372
2
    if (H5P_get(dx_plist, H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME,
373
2
                &H5CX_def_dxpl_cache.actual_selection_io_mode) < 0)
374
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve actual selection I/O mode");
375
376
    /* Get the modify write buffer property */
377
2
    if (H5P_get(dx_plist, H5D_XFER_MODIFY_WRITE_BUF_NAME, &H5CX_def_dxpl_cache.modify_write_buf) < 0)
378
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve modify write buffer property");
379
380
    /* Reset the "default LCPL cache" information */
381
2
    memset(&H5CX_def_lcpl_cache, 0, sizeof(H5CX_lcpl_cache_t));
382
383
    /* Get the default LCPL cache information */
384
385
    /* Get the default link creation property list */
386
2
    if (NULL == (lc_plist = (H5P_genplist_t *)H5I_object(H5P_LINK_CREATE_DEFAULT)))
387
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a link creation property list");
388
389
    /* Get link name character encoding */
390
2
    if (H5P_get(lc_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &H5CX_def_lcpl_cache.encoding) < 0)
391
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve link name encoding");
392
393
    /* Get flag whether to create intermediate groups */
394
2
    if (H5P_get(lc_plist, H5L_CRT_INTERMEDIATE_GROUP_NAME, &H5CX_def_lcpl_cache.intermediate_group) < 0)
395
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve intermediate group creation flag");
396
397
    /* Reset the "default LAPL cache" information */
398
2
    memset(&H5CX_def_lapl_cache, 0, sizeof(H5CX_lapl_cache_t));
399
400
    /* Get the default LAPL cache information */
401
402
    /* Get the default link access property list */
403
2
    if (NULL == (la_plist = (H5P_genplist_t *)H5I_object(H5P_LINK_ACCESS_DEFAULT)))
404
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a link access property list");
405
406
    /* Get number of soft / UD links to traverse */
407
2
    if (H5P_get(la_plist, H5L_ACS_NLINKS_NAME, &H5CX_def_lapl_cache.nlinks) < 0)
408
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve number of soft / UD links to traverse");
409
410
    /* Reset the "default DCPL cache" information */
411
2
    memset(&H5CX_def_dcpl_cache, 0, sizeof(H5CX_dcpl_cache_t));
412
413
    /* Get the default DCPL cache information */
414
415
    /* Get the default dataset creation property list */
416
2
    if (NULL == (dc_plist = (H5P_genplist_t *)H5I_object(H5P_DATASET_CREATE_DEFAULT)))
417
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a dataset create property list");
418
419
    /* Get flag to indicate whether to minimize dataset object header */
420
2
    if (H5P_get(dc_plist, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, &H5CX_def_dcpl_cache.do_min_dset_ohdr) < 0)
421
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve dataset minimize flag");
422
423
    /* Get object header flags */
424
2
    if (H5P_get(dc_plist, H5O_CRT_OHDR_FLAGS_NAME, &H5CX_def_dcpl_cache.ohdr_flags) < 0)
425
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve object header flags");
426
427
    /* Reset the "default DAPL cache" information */
428
2
    memset(&H5CX_def_dapl_cache, 0, sizeof(H5CX_dapl_cache_t));
429
430
    /* Get the default DAPL cache information */
431
432
    /* Get the default dataset access property list */
433
2
    if (NULL == (da_plist = (H5P_genplist_t *)H5I_object(H5P_DATASET_ACCESS_DEFAULT)))
434
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a dataset create property list");
435
436
    /* Get the prefix for the external file */
437
2
    if (H5P_peek(da_plist, H5D_ACS_EFILE_PREFIX_NAME, &H5CX_def_dapl_cache.extfile_prefix) < 0)
438
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve prefix for external file");
439
440
    /* Get the prefix for the VDS file */
441
2
    if (H5P_peek(da_plist, H5D_ACS_VDS_PREFIX_NAME, &H5CX_def_dapl_cache.vds_prefix) < 0)
442
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve prefix for VDS");
443
444
    /* Reset the "default FAPL cache" information */
445
2
    memset(&H5CX_def_fapl_cache, 0, sizeof(H5CX_fapl_cache_t));
446
447
    /* Get the default FAPL cache information */
448
449
    /* Get the default file access property list */
450
2
    if (NULL == (fa_plist = (H5P_genplist_t *)H5I_object(H5P_FILE_ACCESS_DEFAULT)))
451
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not a dataset create property list");
452
453
    /* Get low_bound */
454
2
    if (H5P_get(fa_plist, H5F_ACS_LIBVER_LOW_BOUND_NAME, &H5CX_def_fapl_cache.low_bound) < 0)
455
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve dataset minimize flag");
456
457
2
    if (H5P_get(fa_plist, H5F_ACS_LIBVER_HIGH_BOUND_NAME, &H5CX_def_fapl_cache.high_bound) < 0)
458
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve dataset minimize flag");
459
460
2
done:
461
2
    FUNC_LEAVE_NOAPI(ret_value)
462
2
} /* end H5CX__init_package() */
463
464
/*-------------------------------------------------------------------------
465
 * Function: H5CX_term_package
466
 *
467
 * Purpose:  Terminate this interface.
468
 *
469
 * Return:   Success:    Positive if anything was done that might
470
 *                affect other interfaces; zero otherwise.
471
 *            Failure:    Negative.
472
 *
473
 *-------------------------------------------------------------------------
474
 */
475
int
476
H5CX_term_package(void)
477
1
{
478
1
    FUNC_ENTER_NOAPI_NOINIT_NOERR
479
480
1
    if (H5_PKG_INIT_VAR) {
481
1
        H5CX_node_t **head = NULL; /* Pointer to head of API context list */
482
483
        /* Get the pointer to the head of the API context, for this thread */
484
1
        head = H5CX_get_my_context();
485
1
        assert(head);
486
487
        /* Reset head of context list */
488
1
        *head = NULL;
489
490
1
        H5_PKG_INIT_VAR = false;
491
1
    } /* end if */
492
493
1
    FUNC_LEAVE_NOAPI(0)
494
1
} /* end H5CX_term_package() */
495
496
/*-------------------------------------------------------------------------
497
 * Function:    H5CX_pushed
498
 *
499
 * Purpose:     Returns whether or not an API context has been pushed.
500
 *
501
 * Return:      true/false
502
 *
503
 *-------------------------------------------------------------------------
504
 */
505
bool
506
H5CX_pushed(void)
507
538
{
508
538
    H5CX_node_t **head      = NULL;  /* Pointer to head of API context list */
509
538
    bool          is_pushed = false; /* Flag to indicate context is pushed */
510
511
538
    FUNC_ENTER_NOAPI_NOINIT_NOERR
512
513
538
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
514
538
    assert(head);
515
516
    /* Set return value */
517
538
    is_pushed = (*head != NULL);
518
519
538
    FUNC_LEAVE_NOAPI(is_pushed)
520
538
}
521
522
/*-------------------------------------------------------------------------
523
 * Function:    H5CX_push
524
 *
525
 * Purpose:     Pushes a context for an API call.
526
 *
527
 * Return:      Non-negative on success / Negative on failure
528
 *
529
 *-------------------------------------------------------------------------
530
 */
531
herr_t
532
H5CX_push(H5CX_node_t *cnode)
533
115
{
534
115
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
535
115
    herr_t        ret_value = SUCCEED; /* Return value */
536
537
115
    FUNC_ENTER_NOAPI(FAIL)
538
539
    /* Sanity check */
540
115
    assert(cnode);
541
115
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
542
115
    assert(head);
543
544
    /* Set non-zero context info */
545
115
    cnode->ctx.dxpl_id = H5P_DATASET_XFER_DEFAULT;
546
115
    cnode->ctx.dcpl_id = H5P_DATASET_CREATE_DEFAULT;
547
115
    cnode->ctx.dapl_id = H5P_DATASET_ACCESS_DEFAULT;
548
115
    cnode->ctx.lcpl_id = H5P_LINK_CREATE_DEFAULT;
549
115
    cnode->ctx.lapl_id = H5P_LINK_ACCESS_DEFAULT;
550
115
    cnode->ctx.fapl_id = H5P_FILE_ACCESS_DEFAULT;
551
115
    cnode->ctx.tag     = H5AC__INVALID_TAG;
552
115
    cnode->ctx.ring    = H5AC_RING_USER;
553
554
#ifdef H5_HAVE_PARALLEL
555
    cnode->ctx.btype = MPI_BYTE;
556
    cnode->ctx.ftype = MPI_BYTE;
557
#endif
558
559
    /* Push context node onto stack */
560
115
    cnode->next = *head;
561
115
    *head       = cnode;
562
563
115
done:
564
115
    FUNC_LEAVE_NOAPI(ret_value)
565
115
} /* end H5CX_push() */
566
567
/*-------------------------------------------------------------------------
568
 * Function:    H5CX_retrieve_state
569
 *
570
 * Purpose:     Retrieve the state of an API context, for later resumption.
571
 *
572
 * Note:  This routine _only_ tracks the state of API context information
573
 *    set before the VOL callback is invoked, not values that are
574
 *    set internal to the library.  It's main purpose is to provide
575
 *    API context state to VOL connectors.
576
 *
577
 * Return:      Non-negative on success / Negative on failure
578
 *
579
 *-------------------------------------------------------------------------
580
 */
581
herr_t
582
H5CX_retrieve_state(H5CX_state_t **api_state)
583
0
{
584
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
585
0
    herr_t        ret_value = SUCCEED; /* Return value */
586
587
0
    FUNC_ENTER_NOAPI(FAIL)
588
589
    /* Sanity check */
590
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
591
0
    assert(head && *head);
592
0
    assert(api_state);
593
594
    /* Allocate & clear API context state */
595
0
    if (NULL == (*api_state = H5FL_CALLOC(H5CX_state_t)))
596
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTALLOC, FAIL, "unable to allocate new API context state");
597
598
    /* Check for non-default DCPL */
599
0
    if (H5P_DATASET_CREATE_DEFAULT != (*head)->ctx.dcpl_id) {
600
        /* Retrieve the DCPL property list */
601
0
        H5CX_RETRIEVE_PLIST(dcpl, FAIL)
602
603
        /* Copy the DCPL ID */
604
0
        if (((*api_state)->dcpl_id = H5P_copy_plist((H5P_genplist_t *)(*head)->ctx.dcpl, false)) < 0)
605
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTCOPY, FAIL, "can't copy property list");
606
0
    } /* end if */
607
0
    else
608
0
        (*api_state)->dcpl_id = H5P_DATASET_CREATE_DEFAULT;
609
610
    /* Check for non-default DXPL */
611
0
    if (H5P_DATASET_XFER_DEFAULT != (*head)->ctx.dxpl_id) {
612
        /* Retrieve the DXPL property list */
613
0
        H5CX_RETRIEVE_PLIST(dxpl, FAIL)
614
615
        /* Copy the DXPL ID */
616
0
        if (((*api_state)->dxpl_id = H5P_copy_plist((H5P_genplist_t *)(*head)->ctx.dxpl, false)) < 0)
617
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTCOPY, FAIL, "can't copy property list");
618
0
    } /* end if */
619
0
    else
620
0
        (*api_state)->dxpl_id = H5P_DATASET_XFER_DEFAULT;
621
622
    /* Check for non-default LAPL */
623
0
    if (H5P_LINK_ACCESS_DEFAULT != (*head)->ctx.lapl_id) {
624
        /* Retrieve the LAPL property list */
625
0
        H5CX_RETRIEVE_PLIST(lapl, FAIL)
626
627
        /* Copy the LAPL ID */
628
0
        if (((*api_state)->lapl_id = H5P_copy_plist((H5P_genplist_t *)(*head)->ctx.lapl, false)) < 0)
629
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTCOPY, FAIL, "can't copy property list");
630
0
    } /* end if */
631
0
    else
632
0
        (*api_state)->lapl_id = H5P_LINK_ACCESS_DEFAULT;
633
634
    /* Check for non-default LCPL */
635
0
    if (H5P_LINK_CREATE_DEFAULT != (*head)->ctx.lcpl_id) {
636
        /* Retrieve the LCPL property list */
637
0
        H5CX_RETRIEVE_PLIST(lcpl, FAIL)
638
639
        /* Copy the LCPL ID */
640
0
        if (((*api_state)->lcpl_id = H5P_copy_plist((H5P_genplist_t *)(*head)->ctx.lcpl, false)) < 0)
641
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTCOPY, FAIL, "can't copy property list");
642
0
    } /* end if */
643
0
    else
644
0
        (*api_state)->lcpl_id = H5P_LINK_CREATE_DEFAULT;
645
646
    /* Keep a reference to the current VOL wrapping context */
647
0
    (*api_state)->vol_wrap_ctx = (*head)->ctx.vol_wrap_ctx;
648
0
    if (NULL != (*api_state)->vol_wrap_ctx) {
649
0
        assert((*head)->ctx.vol_wrap_ctx_valid);
650
0
        if (H5VL_inc_vol_wrapper((*api_state)->vol_wrap_ctx) < 0)
651
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTINC, FAIL, "can't increment refcount on VOL wrapping context");
652
0
    } /* end if */
653
654
    /* Keep a copy of the VOL connector property, if there is one */
655
0
    if ((*head)->ctx.vol_connector_prop_valid && (*head)->ctx.vol_connector_prop.connector) {
656
        /* Get the connector property */
657
0
        H5MM_memcpy(&(*api_state)->vol_connector_prop, &(*head)->ctx.vol_connector_prop,
658
0
                    sizeof(H5VL_connector_prop_t));
659
660
        /* Check for actual VOL connector property */
661
0
        if ((*api_state)->vol_connector_prop.connector) {
662
            /* Copy connector info, if it exists */
663
0
            if ((*api_state)->vol_connector_prop.connector_info) {
664
0
                void *new_connector_info = NULL; /* Copy of connector info */
665
666
                /* Allocate and copy connector info */
667
0
                if (H5VL_copy_connector_info((*api_state)->vol_connector_prop.connector, &new_connector_info,
668
0
                                             (*api_state)->vol_connector_prop.connector_info) < 0)
669
0
                    HGOTO_ERROR(H5E_CONTEXT, H5E_CANTCOPY, FAIL, "connector info copy failed");
670
0
                (*api_state)->vol_connector_prop.connector_info = new_connector_info;
671
0
            } /* end if */
672
673
            /* Increment the refcount on the connector */
674
0
            if (H5VL_conn_inc_rc((*api_state)->vol_connector_prop.connector) < 0)
675
0
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTINC, FAIL, "incrementing VOL connector refcount failed");
676
0
        } /* end if */
677
0
    }     /* end if */
678
679
#ifdef H5_HAVE_PARALLEL
680
    /* Save parallel I/O settings */
681
    (*api_state)->coll_metadata_read = (*head)->ctx.coll_metadata_read;
682
#endif /* H5_HAVE_PARALLEL */
683
684
0
done:
685
    /* Cleanup on error */
686
0
    if (ret_value < 0) {
687
0
        if (*api_state) {
688
            /* Release the (possibly partially allocated) API state struct */
689
0
            if (H5CX_free_state(*api_state) < 0)
690
0
                HDONE_ERROR(H5E_CONTEXT, H5E_CANTRELEASE, FAIL, "unable to release API state");
691
0
            *api_state = NULL;
692
0
        } /* end if */
693
0
    }     /* end if */
694
695
0
    FUNC_LEAVE_NOAPI(ret_value)
696
0
} /* end H5CX_retrieve_state() */
697
698
/*-------------------------------------------------------------------------
699
 * Function:    H5CX_restore_state
700
 *
701
 * Purpose:     Restore an API context, from a previously retrieved state.
702
 *
703
 * Note:  This routine _only_ resets the state of API context information
704
 *    set before the VOL callback is invoked, not values that are
705
 *    set internal to the library.  It's main purpose is to restore
706
 *    API context state from VOL connectors.
707
 *
708
 * Return:      Non-negative on success / Negative on failure
709
 *
710
 *-------------------------------------------------------------------------
711
 */
712
herr_t
713
H5CX_restore_state(const H5CX_state_t *api_state)
714
0
{
715
0
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
716
717
0
    FUNC_ENTER_NOAPI_NOINIT_NOERR
718
719
    /* Sanity check */
720
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
721
0
    assert(head && *head);
722
0
    assert(api_state);
723
724
    /* Restore the DCPL info */
725
0
    (*head)->ctx.dcpl_id = api_state->dcpl_id;
726
0
    (*head)->ctx.dcpl    = NULL;
727
728
    /* Restore the DXPL info */
729
0
    (*head)->ctx.dxpl_id = api_state->dxpl_id;
730
0
    (*head)->ctx.dxpl    = NULL;
731
732
    /* Restore the LAPL info */
733
0
    (*head)->ctx.lapl_id = api_state->lapl_id;
734
0
    (*head)->ctx.lapl    = NULL;
735
736
    /* Restore the LCPL info */
737
0
    (*head)->ctx.lcpl_id = api_state->lcpl_id;
738
0
    (*head)->ctx.lcpl    = NULL;
739
740
    /* Restore the VOL wrapper context */
741
0
    (*head)->ctx.vol_wrap_ctx = api_state->vol_wrap_ctx;
742
0
    if (NULL != (*head)->ctx.vol_wrap_ctx)
743
0
        (*head)->ctx.vol_wrap_ctx_valid = true;
744
745
    /* Restore the VOL connector info */
746
0
    if (api_state->vol_connector_prop.connector) {
747
0
        H5MM_memcpy(&(*head)->ctx.vol_connector_prop, &api_state->vol_connector_prop,
748
0
                    sizeof(H5VL_connector_prop_t));
749
0
        (*head)->ctx.vol_connector_prop_valid = true;
750
0
    } /* end if */
751
752
#ifdef H5_HAVE_PARALLEL
753
    /* Restore parallel I/O settings */
754
    (*head)->ctx.coll_metadata_read = api_state->coll_metadata_read;
755
#endif /* H5_HAVE_PARALLEL */
756
757
0
    FUNC_LEAVE_NOAPI(SUCCEED)
758
0
} /* end H5CX_restore_state() */
759
760
/*-------------------------------------------------------------------------
761
 * Function:    H5CX_free_state
762
 *
763
 * Purpose:     Free a previously retrieved API context state
764
 *
765
 * Return:      Non-negative on success / Negative on failure
766
 *
767
 *-------------------------------------------------------------------------
768
 */
769
herr_t
770
H5CX_free_state(H5CX_state_t *api_state)
771
0
{
772
0
    herr_t ret_value = SUCCEED; /* Return value */
773
774
0
    FUNC_ENTER_NOAPI(FAIL)
775
776
    /* Sanity check */
777
0
    assert(api_state);
778
779
    /* Release the DCPL */
780
0
    if (0 != api_state->dcpl_id && H5P_DATASET_CREATE_DEFAULT != api_state->dcpl_id)
781
0
        if (H5I_dec_ref(api_state->dcpl_id) < 0)
782
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on DCPL");
783
784
    /* Release the DXPL */
785
0
    if (0 != api_state->dxpl_id && H5P_DATASET_XFER_DEFAULT != api_state->dxpl_id)
786
0
        if (H5I_dec_ref(api_state->dxpl_id) < 0)
787
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on DXPL");
788
789
    /* Release the LAPL */
790
0
    if (0 != api_state->lapl_id && H5P_LINK_ACCESS_DEFAULT != api_state->lapl_id)
791
0
        if (H5I_dec_ref(api_state->lapl_id) < 0)
792
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on LAPL");
793
794
    /* Release the LCPL */
795
0
    if (0 != api_state->lcpl_id && H5P_LINK_CREATE_DEFAULT != api_state->lcpl_id)
796
0
        if (H5I_dec_ref(api_state->lcpl_id) < 0)
797
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on LCPL");
798
799
    /* Release the VOL wrapper context */
800
0
    if (api_state->vol_wrap_ctx)
801
0
        if (H5VL_dec_vol_wrapper(api_state->vol_wrap_ctx) < 0)
802
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't decrement refcount on VOL wrapping context");
803
804
    /* Release the VOL connector property, if it was set */
805
0
    if (api_state->vol_connector_prop.connector) {
806
        /* Clean up any VOL connector info */
807
0
        if (api_state->vol_connector_prop.connector_info)
808
0
            if (H5VL_free_connector_info(api_state->vol_connector_prop.connector,
809
0
                                         api_state->vol_connector_prop.connector_info) < 0)
810
0
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTRELEASE, FAIL,
811
0
                            "unable to release VOL connector info object");
812
813
        /* Decrement connector refcount */
814
0
        if (H5VL_conn_dec_rc(api_state->vol_connector_prop.connector) < 0)
815
0
            HDONE_ERROR(H5E_CONTEXT, H5E_CANTDEC, FAIL, "can't close VOL connector");
816
0
    } /* end if */
817
818
    /* Free the state */
819
0
    api_state = H5FL_FREE(H5CX_state_t, api_state);
820
821
0
done:
822
0
    FUNC_LEAVE_NOAPI(ret_value)
823
0
} /* end H5CX_free_state() */
824
825
/*-------------------------------------------------------------------------
826
 * Function:    H5CX_is_def_dxpl
827
 *
828
 * Purpose:     Checks if the API context is using the library's default DXPL
829
 *
830
 * Return:      true / false (can't fail)
831
 *
832
 *-------------------------------------------------------------------------
833
 */
834
bool
835
H5CX_is_def_dxpl(void)
836
0
{
837
0
    H5CX_node_t **head        = NULL;  /* Pointer to head of API context list */
838
0
    bool          is_def_dxpl = false; /* Flag to indicate DXPL is default */
839
840
0
    FUNC_ENTER_NOAPI_NOINIT_NOERR
841
842
    /* Sanity check */
843
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
844
0
    assert(head && *head);
845
846
    /* Set return value */
847
0
    is_def_dxpl = ((*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT);
848
849
0
    FUNC_LEAVE_NOAPI(is_def_dxpl)
850
0
} /* end H5CX_is_def_dxpl() */
851
852
/*-------------------------------------------------------------------------
853
 * Function:    H5CX_set_dxpl
854
 *
855
 * Purpose:     Sets the DXPL for the current API call context.
856
 *
857
 * Return:      <none>
858
 *
859
 *-------------------------------------------------------------------------
860
 */
861
void
862
H5CX_set_dxpl(hid_t dxpl_id)
863
0
{
864
0
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
865
866
0
    FUNC_ENTER_NOAPI_NOINIT_NOERR
867
868
    /* Sanity check */
869
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
870
0
    assert(head && *head);
871
872
    /* Set the API context's DXPL to a new value */
873
0
    (*head)->ctx.dxpl_id = dxpl_id;
874
875
0
    FUNC_LEAVE_NOAPI_VOID
876
0
} /* end H5CX_set_dxpl() */
877
878
/*-------------------------------------------------------------------------
879
 * Function:    H5CX_set_dcpl
880
 *
881
 * Purpose:     Sets the DCPL for the current API call context.
882
 *
883
 * Return:      <none>
884
 *
885
 *-------------------------------------------------------------------------
886
 */
887
void
888
H5CX_set_dcpl(hid_t dcpl_id)
889
0
{
890
0
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
891
892
0
    FUNC_ENTER_NOAPI_NOINIT_NOERR
893
894
    /* Sanity check */
895
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
896
0
    assert(head && *head);
897
898
    /* Set the API context's DCPL to a new value */
899
0
    (*head)->ctx.dcpl_id = dcpl_id;
900
901
0
    FUNC_LEAVE_NOAPI_VOID
902
0
} /* end H5CX_set_dcpl() */
903
904
/*-------------------------------------------------------------------------
905
 * Function:    H5CX_set_libver_bounds
906
 *
907
 * Purpose:     Sets the low/high bounds according to "f" for the current API call context.
908
 *              When "f" is NULL, the low/high bounds are set to latest format.
909
 *
910
 * Return:      Non-negative on success / Negative on failure
911
 *
912
 *-------------------------------------------------------------------------
913
 */
914
herr_t
915
H5CX_set_libver_bounds(H5F_t *f)
916
0
{
917
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
918
0
    herr_t        ret_value = SUCCEED; /* Return value */
919
920
0
    FUNC_ENTER_NOAPI(FAIL)
921
922
    /* Sanity check */
923
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
924
0
    assert(head && *head);
925
926
    /* Set the API context value */
927
0
    (*head)->ctx.low_bound  = (f == NULL) ? H5F_LIBVER_LATEST : H5F_LOW_BOUND(f);
928
0
    (*head)->ctx.high_bound = (f == NULL) ? H5F_LIBVER_LATEST : H5F_HIGH_BOUND(f);
929
930
    /* Mark the values as valid */
931
0
    (*head)->ctx.low_bound_valid  = true;
932
0
    (*head)->ctx.high_bound_valid = true;
933
934
0
done:
935
0
    FUNC_LEAVE_NOAPI(ret_value)
936
0
} /* end H5CX_set_libver_bounds() */
937
938
/*-------------------------------------------------------------------------
939
 * Function:    H5CX_set_lcpl
940
 *
941
 * Purpose:     Sets the LCPL for the current API call context.
942
 *
943
 * Return:      <none>
944
 *
945
 *-------------------------------------------------------------------------
946
 */
947
void
948
H5CX_set_lcpl(hid_t lcpl_id)
949
0
{
950
0
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
951
952
0
    FUNC_ENTER_NOAPI_NOINIT_NOERR
953
954
    /* Sanity check */
955
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
956
0
    assert(head && *head);
957
958
    /* Set the API context's LCPL to a new value */
959
0
    (*head)->ctx.lcpl_id = lcpl_id;
960
961
0
    FUNC_LEAVE_NOAPI_VOID
962
0
} /* end H5CX_set_lcpl() */
963
964
/*-------------------------------------------------------------------------
965
 * Function:    H5CX_set_lapl
966
 *
967
 * Purpose:     Sets the LAPL for the current API call context.
968
 *
969
 * Return:      <none>
970
 *
971
 *-------------------------------------------------------------------------
972
 */
973
void
974
H5CX_set_lapl(hid_t lapl_id)
975
0
{
976
0
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
977
978
0
    FUNC_ENTER_NOAPI_NOINIT_NOERR
979
980
    /* Sanity check */
981
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
982
0
    assert(head && *head);
983
984
    /* Set the API context's LAPL to a new value */
985
0
    (*head)->ctx.lapl_id = lapl_id;
986
987
0
    FUNC_LEAVE_NOAPI_VOID
988
0
} /* end H5CX_set_lapl() */
989
990
/*-------------------------------------------------------------------------
991
 * Function:    H5CX_set_apl
992
 *
993
 * Purpose:     Validaties an access property list, and sanity checking &
994
 *              setting up collective operations.
995
 *
996
 * Return:      Non-negative on success / Negative on failure
997
 *
998
 *-------------------------------------------------------------------------
999
 */
1000
herr_t
1001
H5CX_set_apl(hid_t *acspl_id, const H5P_libclass_t *libclass,
1002
             hid_t
1003
#ifndef H5_HAVE_PARALLEL
1004
                 H5_ATTR_UNUSED
1005
#endif /* H5_HAVE_PARALLEL */
1006
                     loc_id,
1007
             bool
1008
#ifndef H5_HAVE_PARALLEL
1009
                 H5_ATTR_UNUSED
1010
#endif /* H5_HAVE_PARALLEL */
1011
                     is_collective)
1012
75
{
1013
75
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1014
75
    herr_t        ret_value = SUCCEED; /* Return value */
1015
1016
75
    FUNC_ENTER_NOAPI(FAIL)
1017
1018
    /* Sanity checks */
1019
75
    assert(acspl_id);
1020
75
    assert(libclass);
1021
75
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1022
75
    assert(head && *head);
1023
1024
    /* Set access plist to the default property list of the appropriate class if it's the generic default */
1025
75
    if (H5P_DEFAULT == *acspl_id)
1026
75
        *acspl_id = *libclass->def_plist_id;
1027
0
    else {
1028
0
        htri_t is_lapl; /* Whether the access property list is (or is derived from) a link access property
1029
                           list */
1030
0
        htri_t is_dapl; /* Whether the access property list is (or is derived from) a dataset access property
1031
                           list */
1032
0
        htri_t is_fapl; /* Whether the access property list is (or is derived from) a file access property
1033
                           list */
1034
1035
#ifdef H5CX_DEBUG
1036
        /* Sanity check the access property list class */
1037
        if (true != H5P_isa_class(*acspl_id, *libclass->class_id))
1038
            HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL, "not the required access property list");
1039
#endif /* H5CX_DEBUG*/
1040
1041
        /* Check for link access property and set API context if so */
1042
0
        if ((is_lapl = H5P_class_isa(*libclass->pclass, *H5P_CLS_LACC->pclass)) < 0)
1043
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't check for link access class");
1044
0
        else if (is_lapl)
1045
0
            (*head)->ctx.lapl_id = *acspl_id;
1046
1047
        /* Check for dataset access property and set API context if so */
1048
0
        if ((is_dapl = H5P_class_isa(*libclass->pclass, *H5P_CLS_DACC->pclass)) < 0)
1049
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't check for dataset access class");
1050
0
        else if (is_dapl)
1051
0
            (*head)->ctx.dapl_id = *acspl_id;
1052
1053
        /* Check for file access property and set API context if so */
1054
0
        if ((is_fapl = H5P_class_isa(*libclass->pclass, *H5P_CLS_FACC->pclass)) < 0)
1055
0
            HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't check for file access class");
1056
0
        else if (is_fapl)
1057
0
            (*head)->ctx.fapl_id = *acspl_id;
1058
1059
#ifdef H5_HAVE_PARALLEL
1060
        /* If this routine is not guaranteed to be collective (i.e. it doesn't
1061
         * modify the structural metadata in a file), check if the application
1062
         * specified a collective metadata read for just this operation.
1063
         */
1064
        if (!is_collective) {
1065
            H5P_genplist_t         *plist;        /* Property list pointer */
1066
            H5P_coll_md_read_flag_t md_coll_read; /* Collective metadata read flag */
1067
1068
            /* Get the plist structure for the access property list */
1069
            if (NULL == (plist = (H5P_genplist_t *)H5I_object(*acspl_id)))
1070
                HGOTO_ERROR(H5E_CONTEXT, H5E_BADID, FAIL, "can't find object for ID");
1071
1072
            /* Get the collective metadata read flag */
1073
            if (H5P_peek(plist, H5_COLL_MD_READ_FLAG_NAME, &md_coll_read) < 0)
1074
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "can't get core collective metadata read flag");
1075
1076
            /* If collective metadata read requested, set collective metadata read flag */
1077
            if (H5P_USER_TRUE == md_coll_read)
1078
                is_collective = true;
1079
        } /* end if */
1080
#endif    /* H5_HAVE_PARALLEL */
1081
0
    }     /* end else */
1082
1083
#ifdef H5_HAVE_PARALLEL
1084
    /* Check for collective operation */
1085
    if (is_collective) {
1086
        /* Set collective metadata read flag */
1087
        (*head)->ctx.coll_metadata_read = true;
1088
1089
        /* If parallel is enabled and the file driver used is the MPI-IO
1090
         * VFD, issue an MPI barrier for easier debugging if the API function
1091
         * calling this is supposed to be called collectively.
1092
         */
1093
        if (H5_coll_api_sanity_check_g) {
1094
            MPI_Comm mpi_comm; /* File communicator */
1095
1096
            /* Retrieve the MPI communicator from the loc_id or the fapl_id */
1097
            if (H5F_mpi_retrieve_comm(loc_id, *acspl_id, &mpi_comm) < 0)
1098
                HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MPI communicator");
1099
1100
            /* issue the barrier */
1101
            if (mpi_comm != MPI_COMM_NULL)
1102
                MPI_Barrier(mpi_comm);
1103
        } /* end if */
1104
    }     /* end if */
1105
#endif    /* H5_HAVE_PARALLEL */
1106
1107
75
done:
1108
75
    FUNC_LEAVE_NOAPI(ret_value)
1109
75
} /* end H5CX_set_apl() */
1110
1111
/*-------------------------------------------------------------------------
1112
 * Function:    H5CX_set_loc
1113
 *
1114
 * Purpose:     Sanity checks and sets up collective operations.
1115
 *
1116
 * Note:        Should be called for all API routines that modify file
1117
 *              metadata but don't pass in an access property list.
1118
 *
1119
 * Return:      Non-negative on success / Negative on failure
1120
 *
1121
 *-------------------------------------------------------------------------
1122
 */
1123
herr_t
1124
H5CX_set_loc(hid_t
1125
#ifndef H5_HAVE_PARALLEL
1126
                 H5_ATTR_UNUSED
1127
#endif /* H5_HAVE_PARALLEL */
1128
                     loc_id)
1129
0
{
1130
#ifdef H5_HAVE_PARALLEL
1131
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1132
    herr_t        ret_value = SUCCEED; /* Return value */
1133
1134
    FUNC_ENTER_NOAPI(FAIL)
1135
1136
    /* Sanity check */
1137
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1138
    assert(head && *head);
1139
1140
    /* Set collective metadata read flag */
1141
    (*head)->ctx.coll_metadata_read = true;
1142
1143
    /* If parallel is enabled and the file driver used is the MPI-IO
1144
     * VFD, issue an MPI barrier for easier debugging if the API function
1145
     * calling this is supposed to be called collectively.
1146
     */
1147
    if (H5_coll_api_sanity_check_g) {
1148
        MPI_Comm mpi_comm; /* File communicator */
1149
1150
        /* Retrieve the MPI communicator from the loc_id or the fapl_id */
1151
        if (H5F_mpi_retrieve_comm(loc_id, H5P_DEFAULT, &mpi_comm) < 0)
1152
            HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get MPI communicator");
1153
1154
        /* issue the barrier */
1155
        if (mpi_comm != MPI_COMM_NULL)
1156
            MPI_Barrier(mpi_comm);
1157
    } /* end if */
1158
1159
done:
1160
    FUNC_LEAVE_NOAPI(ret_value)
1161
#else  /* H5_HAVE_PARALLEL */
1162
0
    FUNC_ENTER_NOAPI_NOINIT_NOERR
1163
1164
0
    FUNC_LEAVE_NOAPI(SUCCEED)
1165
0
#endif /* H5_HAVE_PARALLEL */
1166
0
} /* end H5CX_set_loc() */
1167
1168
/*-------------------------------------------------------------------------
1169
 * Function:    H5CX_set_vol_wrap_ctx
1170
 *
1171
 * Purpose:     Sets the VOL object wrapping context for an operation.
1172
 *
1173
 * Return:      Non-negative on success / Negative on failure
1174
 *
1175
 *-------------------------------------------------------------------------
1176
 */
1177
herr_t
1178
H5CX_set_vol_wrap_ctx(void *vol_wrap_ctx)
1179
286
{
1180
286
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1181
286
    herr_t        ret_value = SUCCEED; /* Return value */
1182
1183
286
    FUNC_ENTER_NOAPI(FAIL)
1184
1185
    /* Sanity check */
1186
286
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1187
286
    assert(head && *head);
1188
1189
    /* Set the API context value */
1190
286
    (*head)->ctx.vol_wrap_ctx = vol_wrap_ctx;
1191
1192
    /* Mark the value as valid */
1193
286
    (*head)->ctx.vol_wrap_ctx_valid = true;
1194
1195
286
done:
1196
286
    FUNC_LEAVE_NOAPI(ret_value)
1197
286
} /* end H5CX_set_vol_wrap_ctx() */
1198
1199
/*-------------------------------------------------------------------------
1200
 * Function:    H5CX_set_vol_connector_prop
1201
 *
1202
 * Purpose:     Sets the VOL connector ID & info for an operation.
1203
 *
1204
 * Return:      Non-negative on success / Negative on failure
1205
 *
1206
 *-------------------------------------------------------------------------
1207
 */
1208
herr_t
1209
H5CX_set_vol_connector_prop(const H5VL_connector_prop_t *vol_connector_prop)
1210
74
{
1211
74
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1212
74
    herr_t        ret_value = SUCCEED; /* Return value */
1213
1214
74
    FUNC_ENTER_NOAPI(FAIL)
1215
1216
    /* Sanity check */
1217
74
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1218
74
    assert(head && *head);
1219
1220
    /* Set the API context value */
1221
74
    H5MM_memcpy(&(*head)->ctx.vol_connector_prop, vol_connector_prop, sizeof(H5VL_connector_prop_t));
1222
1223
    /* Mark the value as valid */
1224
74
    (*head)->ctx.vol_connector_prop_valid = true;
1225
1226
74
done:
1227
74
    FUNC_LEAVE_NOAPI(ret_value)
1228
74
} /* end H5CX_set_vol_connector_prop() */
1229
1230
/*-------------------------------------------------------------------------
1231
 * Function:    H5CX_get_dxpl
1232
 *
1233
 * Purpose:     Retrieves the DXPL ID for the current API call context.
1234
 *
1235
 * Return:      Non-negative on success / Negative on failure
1236
 *
1237
 *-------------------------------------------------------------------------
1238
 */
1239
hid_t
1240
H5CX_get_dxpl(void)
1241
810
{
1242
810
    H5CX_node_t **head    = NULL;            /* Pointer to head of API context list */
1243
810
    hid_t         dxpl_id = H5I_INVALID_HID; /* DXPL ID for API operation */
1244
1245
810
    FUNC_ENTER_NOAPI_NOINIT_NOERR
1246
1247
    /* Sanity check */
1248
810
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1249
810
    assert(head && *head);
1250
1251
    /* Set return value */
1252
810
    dxpl_id = (*head)->ctx.dxpl_id;
1253
1254
810
    FUNC_LEAVE_NOAPI(dxpl_id)
1255
810
} /* end H5CX_get_dxpl() */
1256
1257
/*-------------------------------------------------------------------------
1258
 * Function:    H5CX_get_lapl
1259
 *
1260
 * Purpose:     Retrieves the LAPL ID for the current API call context.
1261
 *
1262
 * Return:      Non-negative on success / Negative on failure
1263
 *
1264
 *-------------------------------------------------------------------------
1265
 */
1266
hid_t
1267
H5CX_get_lapl(void)
1268
0
{
1269
0
    H5CX_node_t **head    = NULL;            /* Pointer to head of API context list */
1270
0
    hid_t         lapl_id = H5I_INVALID_HID; /* LAPL ID for API operation */
1271
1272
0
    FUNC_ENTER_NOAPI_NOINIT_NOERR
1273
1274
    /* Sanity check */
1275
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1276
0
    assert(head && *head);
1277
1278
    /* Set return value */
1279
0
    lapl_id = (*head)->ctx.lapl_id;
1280
1281
0
    FUNC_LEAVE_NOAPI(lapl_id)
1282
0
} /* end H5CX_get_lapl() */
1283
1284
/*-------------------------------------------------------------------------
1285
 * Function:    H5CX_get_vol_wrap_ctx
1286
 *
1287
 * Purpose:     Retrieves the VOL object wrapping context for an operation.
1288
 *
1289
 * Return:      Non-negative on success / Negative on failure
1290
 *
1291
 *-------------------------------------------------------------------------
1292
 */
1293
herr_t
1294
H5CX_get_vol_wrap_ctx(void **vol_wrap_ctx)
1295
362
{
1296
362
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1297
362
    herr_t        ret_value = SUCCEED; /* Return value */
1298
1299
362
    FUNC_ENTER_NOAPI(FAIL)
1300
1301
    /* Sanity check */
1302
362
    assert(vol_wrap_ctx);
1303
362
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1304
1305
    /* No error is expected at this point.  But in case an application calls H5VLwrap_register
1306
     * which doesn't reset the API context and there is no context, returns a relevant error here
1307
     */
1308
362
    if (!head)
1309
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_UNINITIALIZED, FAIL, "the API context isn't available");
1310
1311
362
    if (!(*head))
1312
0
        HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "unable to get the current API context");
1313
1314
    /* Check for value that was set */
1315
362
    if ((*head)->ctx.vol_wrap_ctx_valid)
1316
        /* Get the value */
1317
284
        *vol_wrap_ctx = (*head)->ctx.vol_wrap_ctx;
1318
78
    else
1319
78
        *vol_wrap_ctx = NULL;
1320
1321
362
done:
1322
362
    FUNC_LEAVE_NOAPI(ret_value)
1323
362
} /* end H5CX_get_vol_wrap_ctx() */
1324
1325
/*-------------------------------------------------------------------------
1326
 * Function:    H5CX_get_vol_connector_prop
1327
 *
1328
 * Purpose:     Retrieves the VOL connector ID & info for an operation.
1329
 *
1330
 * Return:      Non-negative on success / Negative on failure
1331
 *
1332
 *-------------------------------------------------------------------------
1333
 */
1334
herr_t
1335
H5CX_get_vol_connector_prop(H5VL_connector_prop_t *vol_connector_prop)
1336
74
{
1337
74
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1338
74
    herr_t        ret_value = SUCCEED; /* Return value */
1339
1340
74
    FUNC_ENTER_NOAPI(FAIL)
1341
1342
    /* Sanity check */
1343
74
    assert(vol_connector_prop);
1344
74
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1345
74
    assert(head && *head);
1346
1347
    /* Check for value that was set */
1348
74
    if ((*head)->ctx.vol_connector_prop_valid)
1349
        /* Get the value */
1350
74
        H5MM_memcpy(vol_connector_prop, &(*head)->ctx.vol_connector_prop, sizeof(H5VL_connector_prop_t));
1351
0
    else
1352
0
        memset(vol_connector_prop, 0, sizeof(H5VL_connector_prop_t));
1353
1354
74
done:
1355
74
    FUNC_LEAVE_NOAPI(ret_value)
1356
74
} /* end H5CX_get_vol_connector_prop() */
1357
1358
/*-------------------------------------------------------------------------
1359
 * Function:    H5CX_get_tag
1360
 *
1361
 * Purpose:     Retrieves the object tag for the current API call context.
1362
 *
1363
 * Return:      Non-negative on success / Negative on failure
1364
 *
1365
 *-------------------------------------------------------------------------
1366
 */
1367
haddr_t
1368
H5CX_get_tag(void)
1369
648
{
1370
648
    H5CX_node_t **head = NULL;        /* Pointer to head of API context list */
1371
648
    haddr_t       tag  = HADDR_UNDEF; /* Current object's tag (ohdr chunk #0 address) */
1372
1373
648
    FUNC_ENTER_NOAPI_NOINIT_NOERR
1374
1375
    /* Sanity check */
1376
648
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1377
648
    assert(head && *head);
1378
1379
    /* Set return value */
1380
648
    tag = (*head)->ctx.tag;
1381
1382
648
    FUNC_LEAVE_NOAPI(tag)
1383
648
} /* end H5CX_get_tag() */
1384
1385
/*-------------------------------------------------------------------------
1386
 * Function:    H5CX_get_ring
1387
 *
1388
 * Purpose:     Retrieves the metadata cache ring for the current API call context.
1389
 *
1390
 * Return:      Non-negative on success / Negative on failure
1391
 *
1392
 *-------------------------------------------------------------------------
1393
 */
1394
H5AC_ring_t
1395
H5CX_get_ring(void)
1396
460
{
1397
460
    H5CX_node_t **head = NULL;          /* Pointer to head of API context list */
1398
460
    H5AC_ring_t   ring = H5AC_RING_INV; /* Current metadata cache ring for entries */
1399
1400
460
    FUNC_ENTER_NOAPI_NOINIT_NOERR
1401
1402
    /* Sanity check */
1403
460
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1404
460
    assert(head && *head);
1405
1406
    /* Set return value */
1407
460
    ring = (*head)->ctx.ring;
1408
1409
460
    FUNC_LEAVE_NOAPI(ring)
1410
460
} /* end H5CX_get_ring() */
1411
1412
#ifdef H5_HAVE_PARALLEL
1413
/*-------------------------------------------------------------------------
1414
 * Function:    H5CX_get_coll_metadata_read
1415
 *
1416
 * Purpose:     Retrieves the "do collective metadata reads" flag for the current API call context.
1417
 *
1418
 * Return:      true / false on success / <can't fail>
1419
 *
1420
 *-------------------------------------------------------------------------
1421
 */
1422
bool
1423
H5CX_get_coll_metadata_read(void)
1424
{
1425
    H5CX_node_t **head         = NULL; /* Pointer to head of API context list */
1426
    bool          coll_md_read = false;
1427
1428
    FUNC_ENTER_NOAPI_NOINIT_NOERR
1429
1430
    /* Sanity check */
1431
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1432
    assert(head && *head);
1433
1434
    /* Set return value */
1435
    coll_md_read = (*head)->ctx.coll_metadata_read;
1436
1437
    FUNC_LEAVE_NOAPI(coll_md_read)
1438
} /* end H5CX_get_coll_metadata_read() */
1439
1440
/*-------------------------------------------------------------------------
1441
 * Function:    H5CX_get_mpi_coll_datatypes
1442
 *
1443
 * Purpose:     Retrieves the MPI datatypes for collective I/O for the current API call context.
1444
 *
1445
 * Note:  This is only a shallow copy, the datatypes are not duplicated.
1446
 *
1447
 * Return:      Non-negative on success / Negative on failure
1448
 *
1449
 *-------------------------------------------------------------------------
1450
 */
1451
herr_t
1452
H5CX_get_mpi_coll_datatypes(MPI_Datatype *btype, MPI_Datatype *ftype)
1453
{
1454
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1455
    herr_t        ret_value = SUCCEED; /* Return value */
1456
1457
    FUNC_ENTER_NOAPI(FAIL)
1458
1459
    /* Sanity check */
1460
    assert(btype);
1461
    assert(ftype);
1462
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1463
    assert(head && *head);
1464
1465
    /* Set the API context values */
1466
    *btype = (*head)->ctx.btype;
1467
    *ftype = (*head)->ctx.ftype;
1468
1469
done:
1470
    FUNC_LEAVE_NOAPI(ret_value)
1471
} /* end H5CX_get_mpi_coll_datatypes() */
1472
1473
/*-------------------------------------------------------------------------
1474
 * Function:    H5CX_get_mpi_file_flushing
1475
 *
1476
 * Purpose:     Retrieves the "flushing an MPI-opened file" flag for the current API call context.
1477
 *
1478
 * Return:      true / false on success / <can't fail>
1479
 *
1480
 *-------------------------------------------------------------------------
1481
 */
1482
bool
1483
H5CX_get_mpi_file_flushing(void)
1484
{
1485
    H5CX_node_t **head     = NULL; /* Pointer to head of API context list */
1486
    bool          flushing = false;
1487
1488
    FUNC_ENTER_NOAPI_NOINIT_NOERR
1489
1490
    /* Sanity check */
1491
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1492
    assert(head && *head);
1493
1494
    /* Set return value */
1495
    flushing = (*head)->ctx.mpi_file_flushing;
1496
1497
    FUNC_LEAVE_NOAPI(flushing)
1498
} /* end H5CX_get_mpi_file_flushing() */
1499
1500
/*-------------------------------------------------------------------------
1501
 * Function:    H5CX_get_mpio_rank0_bcast
1502
 *
1503
 * Purpose:     Retrieves if the dataset meets read-with-rank0-and-bcast requirements for the current API call
1504
 *context.
1505
 *
1506
 * Return:      Non-negative on success / Negative on failure
1507
 *
1508
 *-------------------------------------------------------------------------
1509
 */
1510
bool
1511
H5CX_get_mpio_rank0_bcast(void)
1512
{
1513
    H5CX_node_t **head           = NULL; /* Pointer to head of API context list */
1514
    bool          do_rank0_bcast = false;
1515
1516
    FUNC_ENTER_NOAPI_NOINIT_NOERR
1517
1518
    /* Sanity check */
1519
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1520
    assert(head && *head);
1521
1522
    /* Set return value */
1523
    do_rank0_bcast = (*head)->ctx.rank0_bcast;
1524
1525
    FUNC_LEAVE_NOAPI(do_rank0_bcast)
1526
} /* end H5CX_get_mpio_rank0_bcast() */
1527
#endif /* H5_HAVE_PARALLEL */
1528
1529
/*-------------------------------------------------------------------------
1530
 * Function:    H5CX_get_btree_split_ratios
1531
 *
1532
 * Purpose:     Retrieves the B-tree split ratios for the current API call context.
1533
 *
1534
 * Return:      Non-negative on success / Negative on failure
1535
 *
1536
 *-------------------------------------------------------------------------
1537
 */
1538
herr_t
1539
H5CX_get_btree_split_ratios(double split_ratio[3])
1540
0
{
1541
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1542
0
    herr_t        ret_value = SUCCEED; /* Return value */
1543
1544
0
    FUNC_ENTER_NOAPI(FAIL)
1545
1546
    /* Sanity check */
1547
0
    assert(split_ratio);
1548
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1549
0
    assert(head && *head);
1550
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1551
1552
0
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_BTREE_SPLIT_RATIO_NAME,
1553
0
                             btree_split_ratio)
1554
1555
    /* Get the B-tree split ratio values */
1556
0
    H5MM_memcpy(split_ratio, &(*head)->ctx.btree_split_ratio, sizeof((*head)->ctx.btree_split_ratio));
1557
1558
0
done:
1559
0
    FUNC_LEAVE_NOAPI(ret_value)
1560
0
} /* end H5CX_get_btree_split_ratios() */
1561
1562
/*-------------------------------------------------------------------------
1563
 * Function:    H5CX_get_max_temp_buf
1564
 *
1565
 * Purpose:     Retrieves the maximum temporary buffer size for the current API call context.
1566
 *
1567
 * Return:      Non-negative on success / Negative on failure
1568
 *
1569
 *-------------------------------------------------------------------------
1570
 */
1571
herr_t
1572
H5CX_get_max_temp_buf(size_t *max_temp_buf)
1573
0
{
1574
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1575
0
    herr_t        ret_value = SUCCEED; /* Return value */
1576
1577
0
    FUNC_ENTER_NOAPI(FAIL)
1578
1579
    /* Sanity check */
1580
0
    assert(max_temp_buf);
1581
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1582
0
    assert(head && *head);
1583
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1584
1585
0
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_MAX_TEMP_BUF_NAME, max_temp_buf)
1586
1587
    /* Get the value */
1588
0
    *max_temp_buf = (*head)->ctx.max_temp_buf;
1589
1590
0
done:
1591
0
    FUNC_LEAVE_NOAPI(ret_value)
1592
0
} /* end H5CX_get_max_temp_buf() */
1593
1594
/*-------------------------------------------------------------------------
1595
 * Function:    H5CX_get_tconv_buf
1596
 *
1597
 * Purpose:     Retrieves the temporary buffer pointer for the current API call context.
1598
 *
1599
 * Return:      Non-negative on success / Negative on failure
1600
 *
1601
 *-------------------------------------------------------------------------
1602
 */
1603
herr_t
1604
H5CX_get_tconv_buf(void **tconv_buf)
1605
0
{
1606
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1607
0
    herr_t        ret_value = SUCCEED; /* Return value */
1608
1609
0
    FUNC_ENTER_NOAPI(FAIL)
1610
1611
    /* Sanity check */
1612
0
    assert(tconv_buf);
1613
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1614
0
    assert(head && *head);
1615
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1616
1617
0
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_TCONV_BUF_NAME, tconv_buf)
1618
1619
    /* Get the value */
1620
0
    *tconv_buf = (*head)->ctx.tconv_buf;
1621
1622
0
done:
1623
0
    FUNC_LEAVE_NOAPI(ret_value)
1624
0
} /* end H5CX_get_tconv_buf() */
1625
1626
/*-------------------------------------------------------------------------
1627
 * Function:    H5CX_get_bkgr_buf
1628
 *
1629
 * Purpose:     Retrieves the background buffer pointer for the current API call context.
1630
 *
1631
 * Return:      Non-negative on success / Negative on failure
1632
 *
1633
 *-------------------------------------------------------------------------
1634
 */
1635
herr_t
1636
H5CX_get_bkgr_buf(void **bkgr_buf)
1637
0
{
1638
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1639
0
    herr_t        ret_value = SUCCEED; /* Return value */
1640
1641
0
    FUNC_ENTER_NOAPI(FAIL)
1642
1643
    /* Sanity check */
1644
0
    assert(bkgr_buf);
1645
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1646
0
    assert(head && *head);
1647
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1648
1649
0
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_BKGR_BUF_NAME, bkgr_buf)
1650
1651
    /* Get the value */
1652
0
    *bkgr_buf = (*head)->ctx.bkgr_buf;
1653
1654
0
done:
1655
0
    FUNC_LEAVE_NOAPI(ret_value)
1656
0
} /* end H5CX_get_bkgr_buf() */
1657
1658
/*-------------------------------------------------------------------------
1659
 * Function:    H5CX_get_bkgr_buf_type
1660
 *
1661
 * Purpose:     Retrieves the background buffer type for the current API call context.
1662
 *
1663
 * Return:      Non-negative on success / Negative on failure
1664
 *
1665
 *-------------------------------------------------------------------------
1666
 */
1667
herr_t
1668
H5CX_get_bkgr_buf_type(H5T_bkg_t *bkgr_buf_type)
1669
0
{
1670
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1671
0
    herr_t        ret_value = SUCCEED; /* Return value */
1672
1673
0
    FUNC_ENTER_NOAPI(FAIL)
1674
1675
    /* Sanity check */
1676
0
    assert(bkgr_buf_type);
1677
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1678
0
    assert(head && *head);
1679
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1680
1681
0
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_BKGR_BUF_TYPE_NAME, bkgr_buf_type)
1682
1683
    /* Get the value */
1684
0
    *bkgr_buf_type = (*head)->ctx.bkgr_buf_type;
1685
1686
0
done:
1687
0
    FUNC_LEAVE_NOAPI(ret_value)
1688
0
} /* end H5CX_get_bkgr_buf_type() */
1689
1690
/*-------------------------------------------------------------------------
1691
 * Function:    H5CX_get_vec_size
1692
 *
1693
 * Purpose:     Retrieves the hyperslab vector size for the current API call context.
1694
 *
1695
 * Return:      Non-negative on success / Negative on failure
1696
 *
1697
 *-------------------------------------------------------------------------
1698
 */
1699
herr_t
1700
H5CX_get_vec_size(size_t *vec_size)
1701
0
{
1702
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1703
0
    herr_t        ret_value = SUCCEED; /* Return value */
1704
1705
0
    FUNC_ENTER_NOAPI(FAIL)
1706
1707
    /* Sanity check */
1708
0
    assert(vec_size);
1709
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1710
0
    assert(head && *head);
1711
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1712
1713
0
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_HYPER_VECTOR_SIZE_NAME, vec_size)
1714
1715
    /* Get the value */
1716
0
    *vec_size = (*head)->ctx.vec_size;
1717
1718
0
done:
1719
0
    FUNC_LEAVE_NOAPI(ret_value)
1720
0
} /* end H5CX_get_vec_size() */
1721
1722
#ifdef H5_HAVE_PARALLEL
1723
1724
/*-------------------------------------------------------------------------
1725
 * Function:    H5CX_get_io_xfer_mode
1726
 *
1727
 * Purpose:     Retrieves the parallel transfer mode for the current API call context.
1728
 *
1729
 * Return:      Non-negative on success / Negative on failure
1730
 *
1731
 *-------------------------------------------------------------------------
1732
 */
1733
herr_t
1734
H5CX_get_io_xfer_mode(H5FD_mpio_xfer_t *io_xfer_mode)
1735
{
1736
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1737
    herr_t        ret_value = SUCCEED; /* Return value */
1738
1739
    FUNC_ENTER_NOAPI(FAIL)
1740
1741
    /* Sanity check */
1742
    assert(io_xfer_mode);
1743
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1744
    assert(head && *head);
1745
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1746
1747
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_IO_XFER_MODE_NAME, io_xfer_mode)
1748
1749
    /* Get the value */
1750
    *io_xfer_mode = (*head)->ctx.io_xfer_mode;
1751
1752
done:
1753
    FUNC_LEAVE_NOAPI(ret_value)
1754
} /* end H5CX_get_io_xfer_mode() */
1755
1756
/*-------------------------------------------------------------------------
1757
 * Function:    H5CX_get_mpio_coll_opt
1758
 *
1759
 * Purpose:     Retrieves the collective / independent parallel I/O option for the current API call context.
1760
 *
1761
 * Return:      Non-negative on success / Negative on failure
1762
 *
1763
 *-------------------------------------------------------------------------
1764
 */
1765
herr_t
1766
H5CX_get_mpio_coll_opt(H5FD_mpio_collective_opt_t *mpio_coll_opt)
1767
{
1768
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1769
    herr_t        ret_value = SUCCEED; /* Return value */
1770
1771
    FUNC_ENTER_NOAPI(FAIL)
1772
1773
    /* Sanity check */
1774
    assert(mpio_coll_opt);
1775
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1776
    assert(head && *head);
1777
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1778
1779
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_MPIO_COLLECTIVE_OPT_NAME, mpio_coll_opt)
1780
1781
    /* Get the value */
1782
    *mpio_coll_opt = (*head)->ctx.mpio_coll_opt;
1783
1784
done:
1785
    FUNC_LEAVE_NOAPI(ret_value)
1786
} /* end H5CX_get_mpio_coll_opt() */
1787
1788
/*-------------------------------------------------------------------------
1789
 * Function:    H5CX_get_mpio_local_no_coll_cause
1790
 *
1791
 * Purpose:     Retrieves the local cause for breaking collective I/O for the current API call context.
1792
 *
1793
 * Return:      Non-negative on success / Negative on failure
1794
 *
1795
 *-------------------------------------------------------------------------
1796
 */
1797
herr_t
1798
H5CX_get_mpio_local_no_coll_cause(uint32_t *mpio_local_no_coll_cause)
1799
{
1800
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1801
    herr_t        ret_value = SUCCEED; /* Return value */
1802
1803
    FUNC_ENTER_NOAPI(FAIL)
1804
1805
    /* Sanity check */
1806
    assert(mpio_local_no_coll_cause);
1807
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1808
    assert(head && *head);
1809
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1810
1811
    H5CX_RETRIEVE_PROP_VALID_SET(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME,
1812
                                 mpio_local_no_coll_cause)
1813
1814
    /* Get the value */
1815
    *mpio_local_no_coll_cause = (*head)->ctx.mpio_local_no_coll_cause;
1816
1817
done:
1818
    FUNC_LEAVE_NOAPI(ret_value)
1819
} /* end H5CX_get_mpio_local_no_coll_cause() */
1820
1821
/*-------------------------------------------------------------------------
1822
 * Function:    H5CX_get_mpio_global_no_coll_cause
1823
 *
1824
 * Purpose:     Retrieves the global cause for breaking collective I/O for the current API call context.
1825
 *
1826
 * Return:      Non-negative on success / Negative on failure
1827
 *
1828
 *-------------------------------------------------------------------------
1829
 */
1830
herr_t
1831
H5CX_get_mpio_global_no_coll_cause(uint32_t *mpio_global_no_coll_cause)
1832
{
1833
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1834
    herr_t        ret_value = SUCCEED; /* Return value */
1835
1836
    FUNC_ENTER_NOAPI(FAIL)
1837
1838
    /* Sanity check */
1839
    assert(mpio_global_no_coll_cause);
1840
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1841
    assert(head && *head);
1842
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1843
1844
    H5CX_RETRIEVE_PROP_VALID_SET(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME,
1845
                                 mpio_global_no_coll_cause)
1846
1847
    /* Get the value */
1848
    *mpio_global_no_coll_cause = (*head)->ctx.mpio_global_no_coll_cause;
1849
1850
done:
1851
    FUNC_LEAVE_NOAPI(ret_value)
1852
} /* end H5CX_get_mpio_global_no_coll_cause() */
1853
1854
/*-------------------------------------------------------------------------
1855
 * Function:    H5CX_get_mpio_chunk_opt_mode
1856
 *
1857
 * Purpose:     Retrieves the collective chunk optimization mode for the current API call context.
1858
 *
1859
 * Return:      Non-negative on success / Negative on failure
1860
 *
1861
 *-------------------------------------------------------------------------
1862
 */
1863
herr_t
1864
H5CX_get_mpio_chunk_opt_mode(H5FD_mpio_chunk_opt_t *mpio_chunk_opt_mode)
1865
{
1866
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1867
    herr_t        ret_value = SUCCEED; /* Return value */
1868
1869
    FUNC_ENTER_NOAPI(FAIL)
1870
1871
    /* Sanity check */
1872
    assert(mpio_chunk_opt_mode);
1873
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1874
    assert(head && *head);
1875
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1876
1877
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_MPIO_CHUNK_OPT_HARD_NAME,
1878
                             mpio_chunk_opt_mode)
1879
1880
    /* Get the value */
1881
    *mpio_chunk_opt_mode = (*head)->ctx.mpio_chunk_opt_mode;
1882
1883
done:
1884
    FUNC_LEAVE_NOAPI(ret_value)
1885
} /* end H5CX_get_mpio_chunk_opt_mode() */
1886
1887
/*-------------------------------------------------------------------------
1888
 * Function:    H5CX_get_mpio_chunk_opt_num
1889
 *
1890
 * Purpose:     Retrieves the collective chunk optimization threshold for the current API call context.
1891
 *
1892
 * Return:      Non-negative on success / Negative on failure
1893
 *
1894
 *-------------------------------------------------------------------------
1895
 */
1896
herr_t
1897
H5CX_get_mpio_chunk_opt_num(unsigned *mpio_chunk_opt_num)
1898
{
1899
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1900
    herr_t        ret_value = SUCCEED; /* Return value */
1901
1902
    FUNC_ENTER_NOAPI(FAIL)
1903
1904
    /* Sanity check */
1905
    assert(mpio_chunk_opt_num);
1906
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1907
    assert(head && *head);
1908
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1909
1910
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_MPIO_CHUNK_OPT_NUM_NAME,
1911
                             mpio_chunk_opt_num)
1912
1913
    /* Get the value */
1914
    *mpio_chunk_opt_num = (*head)->ctx.mpio_chunk_opt_num;
1915
1916
done:
1917
    FUNC_LEAVE_NOAPI(ret_value)
1918
} /* end H5CX_get_mpio_chunk_opt_num() */
1919
1920
/*-------------------------------------------------------------------------
1921
 * Function:    H5CX_get_mpio_chunk_opt_ratio
1922
 *
1923
 * Purpose:     Retrieves the collective chunk optimization ratio for the current API call context.
1924
 *
1925
 * Return:      Non-negative on success / Negative on failure
1926
 *
1927
 *-------------------------------------------------------------------------
1928
 */
1929
herr_t
1930
H5CX_get_mpio_chunk_opt_ratio(unsigned *mpio_chunk_opt_ratio)
1931
{
1932
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1933
    herr_t        ret_value = SUCCEED; /* Return value */
1934
1935
    FUNC_ENTER_NOAPI(FAIL)
1936
1937
    /* Sanity check */
1938
    assert(mpio_chunk_opt_ratio);
1939
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1940
    assert(head && *head);
1941
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1942
1943
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_MPIO_CHUNK_OPT_RATIO_NAME,
1944
                             mpio_chunk_opt_ratio)
1945
1946
    /* Get the value */
1947
    *mpio_chunk_opt_ratio = (*head)->ctx.mpio_chunk_opt_ratio;
1948
1949
done:
1950
    FUNC_LEAVE_NOAPI(ret_value)
1951
} /* end H5CX_get_mpio_chunk_opt_ratio() */
1952
#endif /* H5_HAVE_PARALLEL */
1953
1954
/*-------------------------------------------------------------------------
1955
 * Function:    H5CX_get_err_detect
1956
 *
1957
 * Purpose:     Retrieves the error detection info for the current API call context.
1958
 *
1959
 * Return:      Non-negative on success / Negative on failure
1960
 *
1961
 *-------------------------------------------------------------------------
1962
 */
1963
herr_t
1964
H5CX_get_err_detect(H5Z_EDC_t *err_detect)
1965
0
{
1966
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1967
0
    herr_t        ret_value = SUCCEED; /* Return value */
1968
1969
0
    FUNC_ENTER_NOAPI(FAIL)
1970
1971
    /* Sanity check */
1972
0
    assert(err_detect);
1973
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
1974
0
    assert(head && *head);
1975
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
1976
1977
0
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_EDC_NAME, err_detect)
1978
1979
    /* Get the value */
1980
0
    *err_detect = (*head)->ctx.err_detect;
1981
1982
0
done:
1983
0
    FUNC_LEAVE_NOAPI(ret_value)
1984
0
} /* end H5CX_get_err_detect() */
1985
1986
/*-------------------------------------------------------------------------
1987
 * Function:    H5CX_get_filter_cb
1988
 *
1989
 * Purpose:     Retrieves the I/O filter callback function for the current API call context.
1990
 *
1991
 * Return:      Non-negative on success / Negative on failure
1992
 *
1993
 *-------------------------------------------------------------------------
1994
 */
1995
herr_t
1996
H5CX_get_filter_cb(H5Z_cb_t *filter_cb)
1997
0
{
1998
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
1999
0
    herr_t        ret_value = SUCCEED; /* Return value */
2000
2001
0
    FUNC_ENTER_NOAPI(FAIL)
2002
2003
    /* Sanity check */
2004
0
    assert(filter_cb);
2005
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2006
0
    assert(head && *head);
2007
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
2008
2009
0
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_FILTER_CB_NAME, filter_cb)
2010
2011
    /* Get the value */
2012
0
    *filter_cb = (*head)->ctx.filter_cb;
2013
2014
0
done:
2015
0
    FUNC_LEAVE_NOAPI(ret_value)
2016
0
} /* end H5CX_get_filter_cb() */
2017
2018
/*-------------------------------------------------------------------------
2019
 * Function:    H5CX_get_data_transform
2020
 *
2021
 * Purpose:     Retrieves the data transformation expression for the current API call context.
2022
 *
2023
 * Return:      Non-negative on success / Negative on failure
2024
 *
2025
 *-------------------------------------------------------------------------
2026
 */
2027
herr_t
2028
H5CX_get_data_transform(H5Z_data_xform_t **data_transform)
2029
0
{
2030
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2031
0
    herr_t        ret_value = SUCCEED; /* Return value */
2032
2033
0
    FUNC_ENTER_NOAPI(FAIL)
2034
2035
    /* Sanity check */
2036
0
    assert(data_transform);
2037
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2038
0
    assert(head && *head);
2039
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
2040
2041
    /* This getter does not use H5CX_RETRIEVE_PROP_VALID in order to use H5P_peek instead of H5P_get.
2042
       This prevents invocation of the data transform property's library-defined copy callback */
2043
2044
    /* Check if the value has been retrieved already */
2045
0
    if (!(*head)->ctx.data_transform_valid) {
2046
        /* Check for default DXPL */
2047
0
        if ((*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)
2048
0
            (*head)->ctx.data_transform = H5CX_def_dxpl_cache.data_transform;
2049
0
        else {
2050
            /* Check if the property list is already available */
2051
0
            if (NULL == (*head)->ctx.dxpl)
2052
                /* Get the dataset transfer property list pointer */
2053
0
                if (NULL == ((*head)->ctx.dxpl = (H5P_genplist_t *)H5I_object((*head)->ctx.dxpl_id)))
2054
0
                    HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL,
2055
0
                                "can't get default dataset transfer property list");
2056
2057
            /* Get data transform info value */
2058
            /* (Note: 'peek', not 'get' - if this turns out to be a problem, we may need
2059
             *          to copy it and free this in the H5CX pop routine. -QAK)
2060
             */
2061
0
            if (H5P_peek((*head)->ctx.dxpl, H5D_XFER_XFORM_NAME, &(*head)->ctx.data_transform) < 0)
2062
0
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve data transform info");
2063
0
        } /* end else */
2064
2065
        /* Mark the value as valid */
2066
0
        (*head)->ctx.data_transform_valid = true;
2067
0
    } /* end if */
2068
2069
    /* Get the value */
2070
0
    *data_transform = (*head)->ctx.data_transform;
2071
2072
0
done:
2073
0
    FUNC_LEAVE_NOAPI(ret_value)
2074
0
} /* end H5CX_get_data_transform() */
2075
2076
/*-------------------------------------------------------------------------
2077
 * Function:    H5CX_get_vlen_alloc_info
2078
 *
2079
 * Purpose:     Retrieves the VL datatype alloc info for the current API call context.
2080
 *
2081
 * Return:      Non-negative on success / Negative on failure
2082
 *
2083
 *-------------------------------------------------------------------------
2084
 */
2085
herr_t
2086
H5CX_get_vlen_alloc_info(H5T_vlen_alloc_info_t *vl_alloc_info)
2087
0
{
2088
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2089
0
    herr_t        ret_value = SUCCEED; /* Return value */
2090
2091
0
    FUNC_ENTER_NOAPI(FAIL)
2092
2093
    /* Sanity check */
2094
0
    assert(vl_alloc_info);
2095
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2096
0
    assert(head && *head);
2097
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
2098
2099
    /* Check if the value has been retrieved already */
2100
0
    if (!(*head)->ctx.vl_alloc_info_valid) {
2101
        /* Check for default DXPL */
2102
0
        if ((*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT)
2103
0
            (*head)->ctx.vl_alloc_info = H5CX_def_dxpl_cache.vl_alloc_info;
2104
0
        else {
2105
            /* Check if the property list is already available */
2106
0
            if (NULL == (*head)->ctx.dxpl)
2107
                /* Get the dataset transfer property list pointer */
2108
0
                if (NULL == ((*head)->ctx.dxpl = (H5P_genplist_t *)H5I_object((*head)->ctx.dxpl_id)))
2109
0
                    HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL,
2110
0
                                "can't get default dataset transfer property list");
2111
2112
            /* Get VL datatype alloc info values */
2113
0
            if (H5P_get((*head)->ctx.dxpl, H5D_XFER_VLEN_ALLOC_NAME, &(*head)->ctx.vl_alloc_info.alloc_func) <
2114
0
                0)
2115
0
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve VL datatype alloc info");
2116
0
            if (H5P_get((*head)->ctx.dxpl, H5D_XFER_VLEN_ALLOC_INFO_NAME,
2117
0
                        &(*head)->ctx.vl_alloc_info.alloc_info) < 0)
2118
0
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve VL datatype alloc info");
2119
0
            if (H5P_get((*head)->ctx.dxpl, H5D_XFER_VLEN_FREE_NAME, &(*head)->ctx.vl_alloc_info.free_func) <
2120
0
                0)
2121
0
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve VL datatype alloc info");
2122
0
            if (H5P_get((*head)->ctx.dxpl, H5D_XFER_VLEN_FREE_INFO_NAME,
2123
0
                        &(*head)->ctx.vl_alloc_info.free_info) < 0)
2124
0
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve VL datatype alloc info");
2125
0
        } /* end else */
2126
2127
        /* Mark the value as valid */
2128
0
        (*head)->ctx.vl_alloc_info_valid = true;
2129
0
    } /* end if */
2130
2131
    /* Get the value */
2132
0
    *vl_alloc_info = (*head)->ctx.vl_alloc_info;
2133
2134
0
done:
2135
0
    FUNC_LEAVE_NOAPI(ret_value)
2136
0
} /* end H5CX_get_vlen_alloc_info() */
2137
2138
/*-------------------------------------------------------------------------
2139
 * Function:    H5CX_get_dt_conv_cb
2140
 *
2141
 * Purpose:     Retrieves the datatype conversion exception callback for the current API call context.
2142
 *
2143
 * Return:      Non-negative on success / Negative on failure
2144
 *
2145
 *-------------------------------------------------------------------------
2146
 */
2147
herr_t
2148
H5CX_get_dt_conv_cb(H5T_conv_cb_t *dt_conv_cb)
2149
0
{
2150
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2151
0
    herr_t        ret_value = SUCCEED; /* Return value */
2152
2153
0
    FUNC_ENTER_NOAPI(FAIL)
2154
2155
    /* Sanity check */
2156
0
    assert(dt_conv_cb);
2157
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2158
0
    assert(head && *head);
2159
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
2160
2161
0
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_CONV_CB_NAME, dt_conv_cb)
2162
2163
    /* Get the value */
2164
0
    *dt_conv_cb = (*head)->ctx.dt_conv_cb;
2165
2166
0
done:
2167
0
    FUNC_LEAVE_NOAPI(ret_value)
2168
0
} /* end H5CX_get_dt_conv_cb() */
2169
2170
/*-------------------------------------------------------------------------
2171
 * Function:    H5CX_get_selection_io_mode
2172
 *
2173
 * Purpose:     Retrieves the selection I/O mode for the current API call context.
2174
 *
2175
 * Return:      Non-negative on success / Negative on failure
2176
 *
2177
 *-------------------------------------------------------------------------
2178
 */
2179
herr_t
2180
H5CX_get_selection_io_mode(H5D_selection_io_mode_t *selection_io_mode)
2181
0
{
2182
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2183
0
    herr_t        ret_value = SUCCEED; /* Return value */
2184
2185
0
    FUNC_ENTER_NOAPI(FAIL)
2186
2187
    /* Sanity check */
2188
0
    assert(selection_io_mode);
2189
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2190
0
    assert(head && *head);
2191
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
2192
2193
0
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_SELECTION_IO_MODE_NAME,
2194
0
                             selection_io_mode)
2195
2196
    /* Get the value */
2197
0
    *selection_io_mode = (*head)->ctx.selection_io_mode;
2198
2199
0
done:
2200
0
    FUNC_LEAVE_NOAPI(ret_value)
2201
0
} /* end H5CX_get_selection_io_mode() */
2202
2203
/*-------------------------------------------------------------------------
2204
 * Function:    H5CX_get_no_selection_io_cause
2205
 *
2206
 * Purpose:     Retrieves the cause for not performing selection I/O
2207
 *              for the current API call context.
2208
 *
2209
 * Return:      Non-negative on success / Negative on failure
2210
 *
2211
 *-------------------------------------------------------------------------
2212
 */
2213
herr_t
2214
H5CX_get_no_selection_io_cause(uint32_t *no_selection_io_cause)
2215
0
{
2216
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2217
0
    herr_t        ret_value = SUCCEED; /* Return value */
2218
2219
0
    FUNC_ENTER_NOAPI(FAIL)
2220
2221
    /* Sanity check */
2222
0
    assert(no_selection_io_cause);
2223
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2224
0
    assert(head && *head);
2225
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
2226
2227
0
    H5CX_RETRIEVE_PROP_VALID_SET(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_NO_SELECTION_IO_CAUSE_NAME,
2228
0
                                 no_selection_io_cause)
2229
2230
    /* Get the value */
2231
0
    *no_selection_io_cause = (*head)->ctx.no_selection_io_cause;
2232
2233
0
done:
2234
0
    FUNC_LEAVE_NOAPI(ret_value)
2235
0
} /* end H5CX_get_no_selection_io_cause() */
2236
2237
/*-------------------------------------------------------------------------
2238
 * Function:    H5CX_get_actual_selection_io_mode
2239
 *
2240
 * Purpose:     Retrieves the actual I/O mode (scalar, vector, and/or selection) for the current API call
2241
 *context.
2242
 *
2243
 * Return:      Non-negative on success / Negative on failure
2244
 *
2245
 *-------------------------------------------------------------------------
2246
 */
2247
herr_t
2248
H5CX_get_actual_selection_io_mode(uint32_t *actual_selection_io_mode)
2249
0
{
2250
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2251
0
    herr_t        ret_value = SUCCEED; /* Return value */
2252
2253
0
    FUNC_ENTER_NOAPI(FAIL)
2254
2255
    /* Sanity check */
2256
0
    assert(actual_selection_io_mode);
2257
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2258
0
    assert(head && *head);
2259
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
2260
2261
    /* This property is a special case - we want to wipe out any previous setting.  Copy the default setting
2262
     * if it has not been set yet. */
2263
0
    if ((*head)->ctx.dxpl_id != H5P_DATASET_XFER_DEFAULT && !(*head)->ctx.actual_selection_io_mode_set &&
2264
0
        !(*head)->ctx.actual_selection_io_mode_valid) {
2265
0
        (*head)->ctx.actual_selection_io_mode     = H5CX_def_dxpl_cache.actual_selection_io_mode;
2266
0
        (*head)->ctx.actual_selection_io_mode_set = true;
2267
0
    }
2268
0
    H5CX_RETRIEVE_PROP_VALID_SET(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME,
2269
0
                                 actual_selection_io_mode)
2270
2271
    /* Get the value */
2272
0
    *actual_selection_io_mode = (*head)->ctx.actual_selection_io_mode;
2273
2274
0
done:
2275
0
    FUNC_LEAVE_NOAPI(ret_value)
2276
0
} /* end H5CX_get_actual_selection_io_mode() */
2277
2278
/*-------------------------------------------------------------------------
2279
 * Function:    H5CX_get_modify_write_buf
2280
 *
2281
 * Purpose:     Retrieves the modify write buffer property for the current API call context.
2282
 *
2283
 * Return:      Non-negative on success / Negative on failure
2284
 *
2285
 *-------------------------------------------------------------------------
2286
 */
2287
herr_t
2288
H5CX_get_modify_write_buf(bool *modify_write_buf)
2289
0
{
2290
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2291
0
    herr_t        ret_value = SUCCEED; /* Return value */
2292
2293
0
    FUNC_ENTER_NOAPI(FAIL)
2294
2295
    /* Sanity check */
2296
0
    assert(modify_write_buf);
2297
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2298
0
    assert(head && *head);
2299
0
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
2300
2301
0
    H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_MODIFY_WRITE_BUF_NAME, modify_write_buf)
2302
2303
    /* Get the value */
2304
0
    *modify_write_buf = (*head)->ctx.modify_write_buf;
2305
2306
0
done:
2307
0
    FUNC_LEAVE_NOAPI(ret_value)
2308
0
} /* end H5CX_get_selection_io_mode() */
2309
2310
/*-------------------------------------------------------------------------
2311
 * Function:    H5CX_get_encoding
2312
 *
2313
 * Purpose:     Retrieves the character encoding for the current API call context.
2314
 *
2315
 * Return:      Non-negative on success / Negative on failure
2316
 *
2317
 *-------------------------------------------------------------------------
2318
 */
2319
herr_t
2320
H5CX_get_encoding(H5T_cset_t *encoding)
2321
0
{
2322
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2323
0
    herr_t        ret_value = SUCCEED; /* Return value */
2324
2325
0
    FUNC_ENTER_NOAPI(FAIL)
2326
2327
    /* Sanity check */
2328
0
    assert(encoding);
2329
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2330
0
    assert(head && *head);
2331
0
    assert(H5P_DEFAULT != (*head)->ctx.lcpl_id);
2332
2333
0
    H5CX_RETRIEVE_PROP_VALID(lcpl, H5P_LINK_CREATE_DEFAULT, H5P_STRCRT_CHAR_ENCODING_NAME, encoding)
2334
2335
    /* Get the value */
2336
0
    *encoding = (*head)->ctx.encoding;
2337
2338
0
done:
2339
0
    FUNC_LEAVE_NOAPI(ret_value)
2340
0
} /* end H5CX_get_encoding() */
2341
2342
/*-------------------------------------------------------------------------
2343
 * Function:    H5CX_get_intermediate_group
2344
 *
2345
 * Purpose:     Retrieves the create intermediate group flag for the current API call context.
2346
 *
2347
 * Return:      Non-negative on success / Negative on failure
2348
 *
2349
 *-------------------------------------------------------------------------
2350
 */
2351
herr_t
2352
H5CX_get_intermediate_group(unsigned *crt_intermed_group)
2353
0
{
2354
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2355
0
    herr_t        ret_value = SUCCEED; /* Return value */
2356
2357
0
    FUNC_ENTER_NOAPI(FAIL)
2358
2359
    /* Sanity check */
2360
0
    assert(crt_intermed_group);
2361
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2362
0
    assert(head && *head);
2363
0
    assert(H5P_DEFAULT != (*head)->ctx.lcpl_id);
2364
2365
0
    H5CX_RETRIEVE_PROP_VALID(lcpl, H5P_LINK_CREATE_DEFAULT, H5L_CRT_INTERMEDIATE_GROUP_NAME,
2366
0
                             intermediate_group)
2367
2368
    /* Get the value */
2369
0
    *crt_intermed_group = (*head)->ctx.intermediate_group;
2370
2371
0
done:
2372
0
    FUNC_LEAVE_NOAPI(ret_value)
2373
0
} /* end H5CX_get_create_intermediate_group() */
2374
2375
/*-------------------------------------------------------------------------
2376
 * Function:    H5CX_get_nlinks
2377
 *
2378
 * Purpose:     Retrieves the # of soft / UD links to traverse for the current API call context.
2379
 *
2380
 * Return:      Non-negative on success / Negative on failure
2381
 *
2382
 *-------------------------------------------------------------------------
2383
 */
2384
herr_t
2385
H5CX_get_nlinks(size_t *nlinks)
2386
1
{
2387
1
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2388
1
    herr_t        ret_value = SUCCEED; /* Return value */
2389
2390
1
    FUNC_ENTER_NOAPI(FAIL)
2391
2392
    /* Sanity check */
2393
1
    assert(nlinks);
2394
1
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2395
1
    assert(head && *head);
2396
1
    assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
2397
2398
1
    H5CX_RETRIEVE_PROP_VALID(lapl, H5P_LINK_ACCESS_DEFAULT, H5L_ACS_NLINKS_NAME, nlinks)
2399
2400
    /* Get the value */
2401
1
    *nlinks = (*head)->ctx.nlinks;
2402
2403
1
done:
2404
1
    FUNC_LEAVE_NOAPI(ret_value)
2405
1
} /* end H5CX_get_nlinks() */
2406
2407
/*-------------------------------------------------------------------------
2408
 * Function:    H5CX_get_libver_bounds
2409
 *
2410
 * Purpose:     Retrieves the low/high bounds for the current API call context.
2411
 *
2412
 * Return:      Non-negative on success / Negative on failure
2413
 *
2414
 *-------------------------------------------------------------------------
2415
 */
2416
herr_t
2417
H5CX_get_libver_bounds(H5F_libver_t *low_bound, H5F_libver_t *high_bound)
2418
0
{
2419
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2420
0
    herr_t        ret_value = SUCCEED; /* Return value */
2421
2422
0
    FUNC_ENTER_NOAPI(FAIL)
2423
2424
    /* Sanity check */
2425
0
    assert(low_bound);
2426
0
    assert(high_bound);
2427
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2428
0
    assert(head && *head);
2429
0
    assert(H5P_DEFAULT != (*head)->ctx.fapl_id);
2430
2431
0
    H5CX_RETRIEVE_PROP_VALID(fapl, H5P_FILE_ACCESS_DEFAULT, H5F_ACS_LIBVER_LOW_BOUND_NAME, low_bound)
2432
0
    H5CX_RETRIEVE_PROP_VALID(fapl, H5P_FILE_ACCESS_DEFAULT, H5F_ACS_LIBVER_HIGH_BOUND_NAME, high_bound)
2433
2434
    /* Get the values */
2435
0
    *low_bound  = (*head)->ctx.low_bound;
2436
0
    *high_bound = (*head)->ctx.high_bound;
2437
2438
0
done:
2439
0
    FUNC_LEAVE_NOAPI(ret_value)
2440
0
} /* end H5CX_get_libver_bounds() */
2441
2442
/*-------------------------------------------------------------------------
2443
 * Function:    H5CX_get_dset_min_ohdr_flag
2444
 *
2445
 * Purpose:     Retrieves the flag that indicates whether the dataset object
2446
 *    header should be minimized
2447
 *
2448
 * Return:      Non-negative on success / Negative on failure
2449
 *
2450
 *-------------------------------------------------------------------------
2451
 */
2452
herr_t
2453
H5CX_get_dset_min_ohdr_flag(bool *dset_min_ohdr_flag)
2454
0
{
2455
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2456
0
    herr_t        ret_value = SUCCEED; /* Return value */
2457
2458
0
    FUNC_ENTER_NOAPI(FAIL)
2459
2460
    /* Sanity check */
2461
0
    assert(dset_min_ohdr_flag);
2462
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2463
0
    assert(head && *head);
2464
0
    assert(H5P_DEFAULT != (*head)->ctx.dcpl_id);
2465
2466
0
    H5CX_RETRIEVE_PROP_VALID(dcpl, H5P_DATASET_CREATE_DEFAULT, H5D_CRT_MIN_DSET_HDR_SIZE_NAME,
2467
0
                             do_min_dset_ohdr)
2468
2469
    /* Get the value */
2470
0
    *dset_min_ohdr_flag = (*head)->ctx.do_min_dset_ohdr;
2471
2472
0
done:
2473
0
    FUNC_LEAVE_NOAPI(ret_value)
2474
0
} /* end H5CX_get_dset_min_ohdr_flag() */
2475
2476
/*-------------------------------------------------------------------------
2477
 * Function:    H5CX_get_ext_file_prefix
2478
 *
2479
 * Purpose:     Retrieves the prefix for external file
2480
 *
2481
 * Return:      Non-negative on success / Negative on failure
2482
 *
2483
 *-------------------------------------------------------------------------
2484
 */
2485
herr_t
2486
H5CX_get_ext_file_prefix(const char **extfile_prefix)
2487
0
{
2488
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2489
0
    herr_t        ret_value = SUCCEED; /* Return value */
2490
2491
0
    FUNC_ENTER_NOAPI(FAIL)
2492
2493
    /* Sanity check */
2494
0
    assert(extfile_prefix);
2495
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2496
0
    assert(head && *head);
2497
0
    assert(H5P_DEFAULT != (*head)->ctx.dapl_id);
2498
2499
    /* Check if the value has been retrieved already */
2500
0
    if (!(*head)->ctx.extfile_prefix_valid) {
2501
        /* Check for default DAPL */
2502
0
        if ((*head)->ctx.dapl_id == H5P_DATASET_ACCESS_DEFAULT)
2503
0
            (*head)->ctx.extfile_prefix = H5CX_def_dapl_cache.extfile_prefix;
2504
0
        else {
2505
            /* Check if the property list is already available */
2506
0
            if (NULL == (*head)->ctx.dapl)
2507
                /* Get the dataset access property list pointer */
2508
0
                if (NULL == ((*head)->ctx.dapl = (H5P_genplist_t *)H5I_object((*head)->ctx.dapl_id)))
2509
0
                    HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL,
2510
0
                                "can't get default dataset access property list");
2511
2512
            /* Get the prefix for the external file */
2513
            /* (Note: 'peek', not 'get' - if this turns out to be a problem, we may need
2514
             *          to copy it and free this in the H5CX pop routine. -QAK)
2515
             */
2516
0
            if (H5P_peek((*head)->ctx.dapl, H5D_ACS_EFILE_PREFIX_NAME, &(*head)->ctx.extfile_prefix) < 0)
2517
0
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve external file prefix");
2518
0
        } /* end else */
2519
2520
        /* Mark the value as valid */
2521
0
        (*head)->ctx.extfile_prefix_valid = true;
2522
0
    } /* end if */
2523
2524
    /* Get the value */
2525
0
    *extfile_prefix = (*head)->ctx.extfile_prefix;
2526
2527
0
done:
2528
0
    FUNC_LEAVE_NOAPI(ret_value)
2529
0
} /* end H5CX_get_ext_file_prefix() */
2530
2531
/*-------------------------------------------------------------------------
2532
 * Function:    H5CX_get_vds_prefix
2533
 *
2534
 * Purpose:     Retrieves the prefix for VDS
2535
 *
2536
 * Return:      Non-negative on success / Negative on failure
2537
 *
2538
 *-------------------------------------------------------------------------
2539
 */
2540
herr_t
2541
H5CX_get_vds_prefix(const char **vds_prefix)
2542
0
{
2543
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2544
0
    herr_t        ret_value = SUCCEED; /* Return value */
2545
2546
0
    FUNC_ENTER_NOAPI(FAIL)
2547
2548
    /* Sanity check */
2549
0
    assert(vds_prefix);
2550
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2551
0
    assert(head && *head);
2552
0
    assert(H5P_DEFAULT != (*head)->ctx.dapl_id);
2553
2554
    /* Check if the value has been retrieved already */
2555
0
    if (!(*head)->ctx.vds_prefix_valid) {
2556
        /* Check for default DAPL */
2557
0
        if ((*head)->ctx.dapl_id == H5P_DATASET_ACCESS_DEFAULT)
2558
0
            (*head)->ctx.vds_prefix = H5CX_def_dapl_cache.vds_prefix;
2559
0
        else {
2560
            /* Check if the property list is already available */
2561
0
            if (NULL == (*head)->ctx.dapl)
2562
                /* Get the dataset access property list pointer */
2563
0
                if (NULL == ((*head)->ctx.dapl = (H5P_genplist_t *)H5I_object((*head)->ctx.dapl_id)))
2564
0
                    HGOTO_ERROR(H5E_CONTEXT, H5E_BADTYPE, FAIL,
2565
0
                                "can't get default dataset access property list");
2566
2567
            /* Get the prefix for the VDS */
2568
            /* (Note: 'peek', not 'get' - if this turns out to be a problem, we may need
2569
             *          to copy it and free this in the H5CX pop routine. -QAK)
2570
             */
2571
0
            if (H5P_peek((*head)->ctx.dapl, H5D_ACS_VDS_PREFIX_NAME, &(*head)->ctx.vds_prefix) < 0)
2572
0
                HGOTO_ERROR(H5E_CONTEXT, H5E_CANTGET, FAIL, "Can't retrieve VDS prefix");
2573
0
        } /* end else */
2574
2575
        /* Mark the value as valid */
2576
0
        (*head)->ctx.vds_prefix_valid = true;
2577
0
    } /* end if */
2578
2579
    /* Get the value */
2580
0
    *vds_prefix = (*head)->ctx.vds_prefix;
2581
2582
0
done:
2583
0
    FUNC_LEAVE_NOAPI(ret_value)
2584
0
} /* end H5CX_get_vds_prefix() */
2585
2586
/*-------------------------------------------------------------------------
2587
 * Function:    H5CX_set_tag
2588
 *
2589
 * Purpose:     Sets the object tag for the current API call context.
2590
 *
2591
 * Return:      <none>
2592
 *
2593
 *-------------------------------------------------------------------------
2594
 */
2595
void
2596
H5CX_set_tag(haddr_t tag)
2597
894
{
2598
894
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
2599
2600
894
    FUNC_ENTER_NOAPI_NOINIT_NOERR
2601
2602
    /* Sanity check */
2603
894
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2604
894
    assert(head && *head);
2605
2606
894
    (*head)->ctx.tag = tag;
2607
2608
894
    FUNC_LEAVE_NOAPI_VOID
2609
894
} /* end H5CX_set_tag() */
2610
2611
/*-------------------------------------------------------------------------
2612
 * Function:    H5CX_set_ring
2613
 *
2614
 * Purpose:     Sets the metadata cache ring for the current API call context.
2615
 *
2616
 * Return:      <none>
2617
 *
2618
 *-------------------------------------------------------------------------
2619
 */
2620
void
2621
H5CX_set_ring(H5AC_ring_t ring)
2622
447
{
2623
447
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
2624
2625
447
    FUNC_ENTER_NOAPI_NOINIT_NOERR
2626
2627
    /* Sanity check */
2628
447
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2629
447
    assert(head && *head);
2630
2631
447
    (*head)->ctx.ring = ring;
2632
2633
447
    FUNC_LEAVE_NOAPI_VOID
2634
447
} /* end H5CX_set_ring() */
2635
2636
#ifdef H5_HAVE_PARALLEL
2637
2638
/*-------------------------------------------------------------------------
2639
 * Function:    H5CX_set_coll_metadata_read
2640
 *
2641
 * Purpose:     Sets the "do collective metadata reads" flag for the current API call context.
2642
 *
2643
 * Return:      <none>
2644
 *
2645
 *-------------------------------------------------------------------------
2646
 */
2647
void
2648
H5CX_set_coll_metadata_read(bool cmdr)
2649
{
2650
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
2651
2652
    FUNC_ENTER_NOAPI_NOINIT_NOERR
2653
2654
    /* Sanity check */
2655
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2656
    assert(head && *head);
2657
2658
    (*head)->ctx.coll_metadata_read = cmdr;
2659
2660
    FUNC_LEAVE_NOAPI_VOID
2661
} /* end H5CX_set_coll_metadata_read() */
2662
2663
/*-------------------------------------------------------------------------
2664
 * Function:    H5CX_set_mpi_coll_datatypes
2665
 *
2666
 * Purpose:     Sets the MPI datatypes for collective I/O for the current API call context.
2667
 *
2668
 * Note:  This is only a shallow copy, the datatypes are not duplicated.
2669
 *
2670
 * Return:      Non-negative on success / Negative on failure
2671
 *
2672
 *-------------------------------------------------------------------------
2673
 */
2674
herr_t
2675
H5CX_set_mpi_coll_datatypes(MPI_Datatype btype, MPI_Datatype ftype)
2676
{
2677
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2678
    herr_t        ret_value = SUCCEED; /* Return value */
2679
2680
    FUNC_ENTER_NOAPI(FAIL)
2681
2682
    /* Sanity check */
2683
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2684
    assert(head && *head);
2685
2686
    /* Set the API context values */
2687
    (*head)->ctx.btype = btype;
2688
    (*head)->ctx.ftype = ftype;
2689
2690
done:
2691
    FUNC_LEAVE_NOAPI(ret_value)
2692
} /* end H5CX_set_mpi_coll_datatypes() */
2693
2694
/*-------------------------------------------------------------------------
2695
 * Function:    H5CX_set_io_xfer_mode
2696
 *
2697
 * Purpose:     Sets the parallel transfer mode for the current API call context.
2698
 *
2699
 * Return:      Non-negative on success / Negative on failure
2700
 *
2701
 *-------------------------------------------------------------------------
2702
 */
2703
herr_t
2704
H5CX_set_io_xfer_mode(H5FD_mpio_xfer_t io_xfer_mode)
2705
{
2706
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2707
    herr_t        ret_value = SUCCEED; /* Return value */
2708
2709
    FUNC_ENTER_NOAPI(FAIL)
2710
2711
    /* Sanity check */
2712
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2713
    assert(head && *head);
2714
2715
    /* Set the API context value */
2716
    (*head)->ctx.io_xfer_mode = io_xfer_mode;
2717
2718
    /* Mark the value as valid */
2719
    (*head)->ctx.io_xfer_mode_valid = true;
2720
2721
done:
2722
    FUNC_LEAVE_NOAPI(ret_value)
2723
} /* end H5CX_set_io_xfer_mode() */
2724
2725
/*-------------------------------------------------------------------------
2726
 * Function:    H5CX_set_mpio_coll_opt
2727
 *
2728
 * Purpose:     Sets the parallel transfer mode for the current API call context.
2729
 *
2730
 * Return:      Non-negative on success / Negative on failure
2731
 *
2732
 *-------------------------------------------------------------------------
2733
 */
2734
herr_t
2735
H5CX_set_mpio_coll_opt(H5FD_mpio_collective_opt_t mpio_coll_opt)
2736
{
2737
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2738
    herr_t        ret_value = SUCCEED; /* Return value */
2739
2740
    FUNC_ENTER_NOAPI(FAIL)
2741
2742
    /* Sanity check */
2743
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2744
    assert(head && *head);
2745
2746
    /* Set the API context value */
2747
    (*head)->ctx.mpio_coll_opt = mpio_coll_opt;
2748
2749
    /* Mark the value as valid */
2750
    (*head)->ctx.mpio_coll_opt_valid = true;
2751
2752
done:
2753
    FUNC_LEAVE_NOAPI(ret_value)
2754
} /* end H5CX_set_mpio_coll_opt() */
2755
2756
/*-------------------------------------------------------------------------
2757
 * Function:    H5CX_set_mpi_file_flushing
2758
 *
2759
 * Purpose:     Sets the "flushing an MPI-opened file" flag for the current API call context.
2760
 *
2761
 * Return:      <none>
2762
 *
2763
 *-------------------------------------------------------------------------
2764
 */
2765
void
2766
H5CX_set_mpi_file_flushing(bool flushing)
2767
{
2768
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
2769
2770
    FUNC_ENTER_NOAPI_NOINIT_NOERR
2771
2772
    /* Sanity check */
2773
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2774
    assert(head && *head);
2775
2776
    (*head)->ctx.mpi_file_flushing = flushing;
2777
2778
    FUNC_LEAVE_NOAPI_VOID
2779
} /* end H5CX_set_mpi_file_flushing() */
2780
2781
/*-------------------------------------------------------------------------
2782
 * Function:    H5CX_set_mpio_rank0_bcast
2783
 *
2784
 * Purpose:     Sets the "dataset meets read-with-rank0-and-bcast requirements" flag for the current API call
2785
 *context.
2786
 *
2787
 * Return:      <none>
2788
 *
2789
 *-------------------------------------------------------------------------
2790
 */
2791
void
2792
H5CX_set_mpio_rank0_bcast(bool rank0_bcast)
2793
{
2794
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
2795
2796
    FUNC_ENTER_NOAPI_NOINIT_NOERR
2797
2798
    /* Sanity checks */
2799
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2800
    assert(head && *head);
2801
2802
    (*head)->ctx.rank0_bcast = rank0_bcast;
2803
2804
    FUNC_LEAVE_NOAPI_VOID
2805
} /* end H5CX_set_mpio_rank0_bcast() */
2806
#endif /* H5_HAVE_PARALLEL */
2807
2808
/*-------------------------------------------------------------------------
2809
 * Function:    H5CX_set_vlen_alloc_info
2810
 *
2811
 * Purpose:     Sets the VL datatype alloc info for the current API call context.
2812
 *
2813
 * Return:      Non-negative on success / Negative on failure
2814
 *
2815
 *-------------------------------------------------------------------------
2816
 */
2817
herr_t
2818
H5CX_set_vlen_alloc_info(H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free_t free_func, void *free_info)
2819
0
{
2820
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2821
0
    herr_t        ret_value = SUCCEED; /* Return value */
2822
2823
0
    FUNC_ENTER_NOAPI(FAIL)
2824
2825
    /* Sanity check */
2826
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2827
0
    assert(head && *head);
2828
2829
    /* Set the API context value */
2830
0
    (*head)->ctx.vl_alloc_info.alloc_func = alloc_func;
2831
0
    (*head)->ctx.vl_alloc_info.alloc_info = alloc_info;
2832
0
    (*head)->ctx.vl_alloc_info.free_func  = free_func;
2833
0
    (*head)->ctx.vl_alloc_info.free_info  = free_info;
2834
2835
    /* Mark the value as valid */
2836
0
    (*head)->ctx.vl_alloc_info_valid = true;
2837
2838
0
done:
2839
0
    FUNC_LEAVE_NOAPI(ret_value)
2840
0
} /* end H5CX_set_vlen_alloc_info() */
2841
2842
/*-------------------------------------------------------------------------
2843
 * Function:    H5CX_set_nlinks
2844
 *
2845
 * Purpose:     Sets the # of soft / UD links to traverse for the current API call context.
2846
 *
2847
 * Return:      Non-negative on success / Negative on failure
2848
 *
2849
 *-------------------------------------------------------------------------
2850
 */
2851
herr_t
2852
H5CX_set_nlinks(size_t nlinks)
2853
0
{
2854
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
2855
0
    herr_t        ret_value = SUCCEED; /* Return value */
2856
2857
0
    FUNC_ENTER_NOAPI(FAIL)
2858
2859
    /* Sanity check */
2860
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2861
0
    assert(head && *head);
2862
2863
    /* Set the API context value */
2864
0
    (*head)->ctx.nlinks = nlinks;
2865
2866
    /* Mark the value as valid */
2867
0
    (*head)->ctx.nlinks_valid = true;
2868
2869
0
done:
2870
0
    FUNC_LEAVE_NOAPI(ret_value)
2871
0
} /* end H5CX_set_nlinks() */
2872
2873
#ifdef H5_HAVE_PARALLEL
2874
2875
/*-------------------------------------------------------------------------
2876
 * Function:    H5CX_set_mpio_actual_chunk_opt
2877
 *
2878
 * Purpose:     Sets the actual chunk optimization used for parallel I/O for the current API call context.
2879
 *
2880
 * Return:      <none>
2881
 *
2882
 *-------------------------------------------------------------------------
2883
 */
2884
void
2885
H5CX_set_mpio_actual_chunk_opt(H5D_mpio_actual_chunk_opt_mode_t mpio_actual_chunk_opt)
2886
{
2887
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
2888
2889
    FUNC_ENTER_NOAPI_NOINIT_NOERR
2890
2891
    /* Sanity checks */
2892
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2893
    assert(head && *head);
2894
    assert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT));
2895
2896
    /* Cache the value for later, marking it to set in DXPL when context popped */
2897
    (*head)->ctx.mpio_actual_chunk_opt     = mpio_actual_chunk_opt;
2898
    (*head)->ctx.mpio_actual_chunk_opt_set = true;
2899
2900
    FUNC_LEAVE_NOAPI_VOID
2901
} /* end H5CX_set_mpio_actual_chunk_opt() */
2902
2903
/*-------------------------------------------------------------------------
2904
 * Function:    H5CX_set_mpio_actual_io_mode
2905
 *
2906
 * Purpose:     Sets the actual I/O mode used for parallel I/O for the current API call context.
2907
 *
2908
 * Return:      <none>
2909
 *
2910
 *-------------------------------------------------------------------------
2911
 */
2912
void
2913
H5CX_set_mpio_actual_io_mode(H5D_mpio_actual_io_mode_t mpio_actual_io_mode)
2914
{
2915
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
2916
2917
    FUNC_ENTER_NOAPI_NOINIT_NOERR
2918
2919
    /* Sanity checks */
2920
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2921
    assert(head && *head);
2922
    assert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT));
2923
2924
    /* Cache the value for later, marking it to set in DXPL when context popped */
2925
    (*head)->ctx.mpio_actual_io_mode     = mpio_actual_io_mode;
2926
    (*head)->ctx.mpio_actual_io_mode_set = true;
2927
2928
    FUNC_LEAVE_NOAPI_VOID
2929
} /* end H5CX_set_mpio_actual_chunk_opt() */
2930
2931
/*-------------------------------------------------------------------------
2932
 * Function:    H5CX_set_mpio_local_no_coll_cause
2933
 *
2934
 * Purpose:     Sets the local reason for breaking collective I/O for the current API call context.
2935
 *
2936
 * Return:      <none>
2937
 *
2938
 *-------------------------------------------------------------------------
2939
 */
2940
void
2941
H5CX_set_mpio_local_no_coll_cause(uint32_t mpio_local_no_coll_cause)
2942
{
2943
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
2944
2945
    FUNC_ENTER_NOAPI_NOINIT_NOERR
2946
2947
    /* Sanity checks */
2948
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2949
    assert(head && *head);
2950
    assert((*head)->ctx.dxpl_id != H5P_DEFAULT);
2951
2952
    /* If we're using the default DXPL, don't modify it */
2953
    if ((*head)->ctx.dxpl_id != H5P_DATASET_XFER_DEFAULT) {
2954
        /* Cache the value for later, marking it to set in DXPL when context popped */
2955
        (*head)->ctx.mpio_local_no_coll_cause     = mpio_local_no_coll_cause;
2956
        (*head)->ctx.mpio_local_no_coll_cause_set = true;
2957
    } /* end if */
2958
2959
    FUNC_LEAVE_NOAPI_VOID
2960
} /* end H5CX_set_mpio_local_no_coll_cause() */
2961
2962
/*-------------------------------------------------------------------------
2963
 * Function:    H5CX_set_mpio_global_no_coll_cause
2964
 *
2965
 * Purpose:     Sets the global reason for breaking collective I/O for the current API call context.
2966
 *
2967
 * Return:      <none>
2968
 *
2969
 *-------------------------------------------------------------------------
2970
 */
2971
void
2972
H5CX_set_mpio_global_no_coll_cause(uint32_t mpio_global_no_coll_cause)
2973
{
2974
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
2975
2976
    FUNC_ENTER_NOAPI_NOINIT_NOERR
2977
2978
    /* Sanity checks */
2979
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
2980
    assert(head && *head);
2981
    assert((*head)->ctx.dxpl_id != H5P_DEFAULT);
2982
2983
    /* If we're using the default DXPL, don't modify it */
2984
    if ((*head)->ctx.dxpl_id != H5P_DATASET_XFER_DEFAULT) {
2985
        /* Cache the value for later, marking it to set in DXPL when context popped */
2986
        (*head)->ctx.mpio_global_no_coll_cause     = mpio_global_no_coll_cause;
2987
        (*head)->ctx.mpio_global_no_coll_cause_set = true;
2988
    } /* end if */
2989
2990
    FUNC_LEAVE_NOAPI_VOID
2991
} /* end H5CX_set_mpio_global_no_coll_cause() */
2992
2993
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
2994
2995
/*-------------------------------------------------------------------------
2996
 * Function:    H5CX_test_set_mpio_coll_chunk_link_hard
2997
 *
2998
 * Purpose:     Sets the instrumented "collective chunk link hard" value for the current API call context.
2999
 *
3000
 * Note:        Only sets value if property set in DXPL
3001
 *
3002
 * Return:      Non-negative on success / Negative on failure
3003
 *
3004
 *-------------------------------------------------------------------------
3005
 */
3006
herr_t
3007
H5CX_test_set_mpio_coll_chunk_link_hard(int mpio_coll_chunk_link_hard)
3008
{
3009
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
3010
    herr_t        ret_value = SUCCEED; /* Return value */
3011
3012
    FUNC_ENTER_NOAPI_NOINIT
3013
3014
    /* Sanity checks */
3015
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
3016
    assert(head && *head);
3017
    assert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT));
3018
3019
    H5CX_TEST_SET_PROP(H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, mpio_coll_chunk_link_hard)
3020
3021
done:
3022
    FUNC_LEAVE_NOAPI(ret_value)
3023
} /* end H5CX_test_set_mpio_coll_chunk_link_hard() */
3024
3025
/*-------------------------------------------------------------------------
3026
 * Function:    H5CX_test_set_mpio_coll_chunk_multi_hard
3027
 *
3028
 * Purpose:     Sets the instrumented "collective chunk multi hard" value for the current API call context.
3029
 *
3030
 * Note:        Only sets value if property set in DXPL
3031
 *
3032
 * Return:      Non-negative on success / Negative on failure
3033
 *
3034
 *-------------------------------------------------------------------------
3035
 */
3036
herr_t
3037
H5CX_test_set_mpio_coll_chunk_multi_hard(int mpio_coll_chunk_multi_hard)
3038
{
3039
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
3040
    herr_t        ret_value = SUCCEED; /* Return value */
3041
3042
    FUNC_ENTER_NOAPI_NOINIT
3043
3044
    /* Sanity checks */
3045
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
3046
    assert(head && *head);
3047
    assert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT));
3048
3049
    H5CX_TEST_SET_PROP(H5D_XFER_COLL_CHUNK_MULTI_HARD_NAME, mpio_coll_chunk_multi_hard)
3050
3051
done:
3052
    FUNC_LEAVE_NOAPI(ret_value)
3053
} /* end H5CX_test_set_mpio_coll_chunk_multi_hard() */
3054
3055
/*-------------------------------------------------------------------------
3056
 * Function:    H5CX_test_set_mpio_coll_chunk_link_num_true
3057
 *
3058
 * Purpose:     Sets the instrumented "collective chunk link num true" value for the current API call context.
3059
 *
3060
 * Note:        Only sets value if property set in DXPL
3061
 *
3062
 * Return:      Non-negative on success / Negative on failure
3063
 *
3064
 *-------------------------------------------------------------------------
3065
 */
3066
herr_t
3067
H5CX_test_set_mpio_coll_chunk_link_num_true(int mpio_coll_chunk_link_num_true)
3068
{
3069
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
3070
    herr_t        ret_value = SUCCEED; /* Return value */
3071
3072
    FUNC_ENTER_NOAPI_NOINIT
3073
3074
    /* Sanity checks */
3075
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
3076
    assert(head && *head);
3077
    assert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT));
3078
3079
    H5CX_TEST_SET_PROP(H5D_XFER_COLL_CHUNK_LINK_NUM_TRUE_NAME, mpio_coll_chunk_link_num_true)
3080
3081
done:
3082
    FUNC_LEAVE_NOAPI(ret_value)
3083
} /* end H5CX_test_set_mpio_coll_chunk_link_num_true() */
3084
3085
/*-------------------------------------------------------------------------
3086
 * Function:    H5CX_test_set_mpio_coll_chunk_link_num_false
3087
 *
3088
 * Purpose:     Sets the instrumented "collective chunk link num false" value for the current API call
3089
 *context.
3090
 *
3091
 * Note:        Only sets value if property set in DXPL
3092
 *
3093
 * Return:      Non-negative on success / Negative on failure
3094
 *
3095
 *-------------------------------------------------------------------------
3096
 */
3097
herr_t
3098
H5CX_test_set_mpio_coll_chunk_link_num_false(int mpio_coll_chunk_link_num_false)
3099
{
3100
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
3101
    herr_t        ret_value = SUCCEED; /* Return value */
3102
3103
    FUNC_ENTER_NOAPI_NOINIT
3104
3105
    /* Sanity checks */
3106
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
3107
    assert(head && *head);
3108
    assert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT));
3109
3110
    H5CX_TEST_SET_PROP(H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME, mpio_coll_chunk_link_num_false)
3111
3112
done:
3113
    FUNC_LEAVE_NOAPI(ret_value)
3114
} /* end H5CX_test_set_mpio_coll_chunk_link_num_false() */
3115
3116
/*-------------------------------------------------------------------------
3117
 * Function:    H5CX_test_set_mpio_coll_chunk_multi_ratio_coll
3118
 *
3119
 * Purpose:     Sets the instrumented "collective chunk multi ratio coll" value for the current API call
3120
 *context.
3121
 *
3122
 * Note:        Only sets value if property set in DXPL
3123
 *
3124
 * Return:      Non-negative on success / Negative on failure
3125
 *
3126
 *-------------------------------------------------------------------------
3127
 */
3128
herr_t
3129
H5CX_test_set_mpio_coll_chunk_multi_ratio_coll(int mpio_coll_chunk_multi_ratio_coll)
3130
{
3131
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
3132
    herr_t        ret_value = SUCCEED; /* Return value */
3133
3134
    FUNC_ENTER_NOAPI_NOINIT
3135
3136
    /* Sanity checks */
3137
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
3138
    assert(head && *head);
3139
    assert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT));
3140
3141
    H5CX_TEST_SET_PROP(H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME, mpio_coll_chunk_multi_ratio_coll)
3142
3143
done:
3144
    FUNC_LEAVE_NOAPI(ret_value)
3145
} /* end H5CX_test_set_mpio_coll_chunk_multi_ratio_coll() */
3146
3147
/*-------------------------------------------------------------------------
3148
 * Function:    H5CX_test_set_mpio_coll_chunk_multi_ratio_ind
3149
 *
3150
 * Purpose:     Sets the instrumented "collective chunk multi ratio ind" value for the current API call
3151
 *context.
3152
 *
3153
 * Note:        Only sets value if property set in DXPL
3154
 *
3155
 * Return:      Non-negative on success / Negative on failure
3156
 *
3157
 *-------------------------------------------------------------------------
3158
 */
3159
herr_t
3160
H5CX_test_set_mpio_coll_chunk_multi_ratio_ind(int mpio_coll_chunk_multi_ratio_ind)
3161
{
3162
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
3163
    herr_t        ret_value = SUCCEED; /* Return value */
3164
3165
    FUNC_ENTER_NOAPI_NOINIT
3166
3167
    /* Sanity checks */
3168
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
3169
    assert(head && *head);
3170
    assert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT));
3171
3172
    H5CX_TEST_SET_PROP(H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME, mpio_coll_chunk_multi_ratio_ind)
3173
3174
done:
3175
    FUNC_LEAVE_NOAPI(ret_value)
3176
} /* end H5CX_test_set_mpio_coll_chunk_multi_ratio_ind() */
3177
3178
/*-------------------------------------------------------------------------
3179
 * Function:    H5CX_test_set_mpio_coll_rank0_bcast
3180
 *
3181
 * Purpose:     Sets the instrumented "read-with-rank0-bcast" flag for the current API call context.
3182
 *
3183
 * Note:        Only sets value if property set in DXPL
3184
 *
3185
 * Return:      Non-negative on success / Negative on failure
3186
 *
3187
 *-------------------------------------------------------------------------
3188
 */
3189
herr_t
3190
H5CX_test_set_mpio_coll_rank0_bcast(bool mpio_coll_rank0_bcast)
3191
{
3192
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
3193
    herr_t        ret_value = SUCCEED; /* Return value */
3194
3195
    FUNC_ENTER_NOAPI_NOINIT
3196
3197
    /* Sanity checks */
3198
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
3199
    assert(head && *head);
3200
    assert(!((*head)->ctx.dxpl_id == H5P_DEFAULT || (*head)->ctx.dxpl_id == H5P_DATASET_XFER_DEFAULT));
3201
3202
    H5CX_TEST_SET_PROP(H5D_XFER_COLL_RANK0_BCAST_NAME, mpio_coll_rank0_bcast)
3203
3204
done:
3205
    FUNC_LEAVE_NOAPI(ret_value)
3206
} /* end H5CX_test_set_mpio_coll_rank0_bcast() */
3207
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
3208
#endif /* H5_HAVE_PARALLEL */
3209
3210
/*-------------------------------------------------------------------------
3211
 * Function:    H5CX_set_no_selection_io_cause
3212
 *
3213
 * Purpose:     Sets the reason for not performing selection I/O for
3214
 *              the current API call context.
3215
 *
3216
 * Return:      <none>
3217
 *
3218
 *-------------------------------------------------------------------------
3219
 */
3220
void
3221
H5CX_set_no_selection_io_cause(uint32_t no_selection_io_cause)
3222
0
{
3223
0
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
3224
3225
0
    FUNC_ENTER_NOAPI_NOINIT_NOERR
3226
3227
    /* Sanity checks */
3228
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
3229
0
    assert(head && *head);
3230
0
    assert((*head)->ctx.dxpl_id != H5P_DEFAULT);
3231
3232
    /* If we're using the default DXPL, don't modify it */
3233
0
    if ((*head)->ctx.dxpl_id != H5P_DATASET_XFER_DEFAULT) {
3234
        /* Cache the value for later, marking it to set in DXPL when context popped */
3235
0
        (*head)->ctx.no_selection_io_cause     = no_selection_io_cause;
3236
0
        (*head)->ctx.no_selection_io_cause_set = true;
3237
0
    } /* end if */
3238
3239
0
    FUNC_LEAVE_NOAPI_VOID
3240
0
} /* end H5CX_set_no_selection_io_cause() */
3241
3242
/*-------------------------------------------------------------------------
3243
 * Function:    H5CX_set_actual_selection_io_mode
3244
 *
3245
 * Purpose:     Sets the actual selection I/O mode for the current API
3246
 *              call context.
3247
 *
3248
 * Return:      <none>
3249
 *
3250
 *-------------------------------------------------------------------------
3251
 */
3252
void
3253
H5CX_set_actual_selection_io_mode(uint32_t actual_selection_io_mode)
3254
0
{
3255
0
    H5CX_node_t **head = NULL; /* Pointer to head of API context list */
3256
3257
0
    FUNC_ENTER_NOAPI_NOINIT_NOERR
3258
3259
    /* Sanity checks */
3260
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
3261
0
    assert(head && *head);
3262
0
    assert((*head)->ctx.dxpl_id != H5P_DEFAULT);
3263
3264
    /* If we're using the default DXPL, don't modify it */
3265
0
    if ((*head)->ctx.dxpl_id != H5P_DATASET_XFER_DEFAULT) {
3266
        /* Cache the value for later, marking it to set in DXPL when context popped */
3267
0
        (*head)->ctx.actual_selection_io_mode     = actual_selection_io_mode;
3268
0
        (*head)->ctx.actual_selection_io_mode_set = true;
3269
0
    }
3270
3271
0
    FUNC_LEAVE_NOAPI_VOID
3272
0
} /* end H5CX_set_actual_selection_io_mode() */
3273
3274
/*-------------------------------------------------------------------------
3275
 * Function:    H5CX_get_ohdr_flags
3276
 *
3277
 * Purpose:     Retrieves the object header flags for the current API call context.
3278
 *
3279
 * Return:      Non-negative on success / Negative on failure
3280
 *
3281
 *-------------------------------------------------------------------------
3282
 */
3283
herr_t
3284
H5CX_get_ohdr_flags(uint8_t *ohdr_flags)
3285
0
{
3286
0
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
3287
0
    herr_t        ret_value = SUCCEED; /* Return value */
3288
3289
0
    FUNC_ENTER_NOAPI(FAIL)
3290
3291
    /* Sanity check */
3292
0
    assert(ohdr_flags);
3293
0
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
3294
0
    assert(head && *head);
3295
0
    assert(H5P_DEFAULT != (*head)->ctx.dcpl_id);
3296
3297
0
    H5CX_RETRIEVE_PROP_VALID(dcpl, H5P_DATASET_CREATE_DEFAULT, H5O_CRT_OHDR_FLAGS_NAME, ohdr_flags)
3298
3299
    /* Get the value */
3300
0
    *ohdr_flags = (*head)->ctx.ohdr_flags;
3301
3302
0
done:
3303
0
    FUNC_LEAVE_NOAPI(ret_value)
3304
0
} /* End H5CX_get_ohdr_flags() */
3305
3306
/*-------------------------------------------------------------------------
3307
 * Function:    H5CX_pop
3308
 *
3309
 * Purpose:     Pops the context for an API call.
3310
 *
3311
 * Return:      Non-negative on success / Negative on failure
3312
 *
3313
 *-------------------------------------------------------------------------
3314
 */
3315
herr_t
3316
H5CX_pop(bool update_dxpl_props)
3317
113
{
3318
113
    H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
3319
113
    herr_t        ret_value = SUCCEED; /* Return value */
3320
3321
113
    FUNC_ENTER_NOAPI(FAIL)
3322
3323
    /* Sanity check */
3324
113
    head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
3325
113
    assert(head && *head);
3326
3327
    /* Check for cached DXPL properties to return to application */
3328
113
    if (update_dxpl_props) {
3329
        /* actual_selection_io_mode is a special case - we always want to set it in the property list even if
3330
         * it was never set by the library, in that case it indicates no I/O was performed and we don't want
3331
         * to leave the (possibly incorrect) old value in the property list, so set from the default property
3332
         * list */
3333
113
        if ((*head)->ctx.dxpl_id != H5P_DATASET_XFER_DEFAULT && !(*head)->ctx.actual_selection_io_mode_set) {
3334
0
            (*head)->ctx.actual_selection_io_mode     = H5CX_def_dxpl_cache.actual_selection_io_mode;
3335
0
            (*head)->ctx.actual_selection_io_mode_set = true;
3336
0
        }
3337
3338
113
        H5CX_SET_PROP(H5D_XFER_NO_SELECTION_IO_CAUSE_NAME, no_selection_io_cause)
3339
113
        H5CX_SET_PROP(H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME, actual_selection_io_mode)
3340
#ifdef H5_HAVE_PARALLEL
3341
        H5CX_SET_PROP(H5D_MPIO_ACTUAL_CHUNK_OPT_MODE_NAME, mpio_actual_chunk_opt)
3342
        H5CX_SET_PROP(H5D_MPIO_ACTUAL_IO_MODE_NAME, mpio_actual_io_mode)
3343
        H5CX_SET_PROP(H5D_MPIO_LOCAL_NO_COLLECTIVE_CAUSE_NAME, mpio_local_no_coll_cause)
3344
        H5CX_SET_PROP(H5D_MPIO_GLOBAL_NO_COLLECTIVE_CAUSE_NAME, mpio_global_no_coll_cause)
3345
#ifdef H5_HAVE_INSTRUMENTED_LIBRARY
3346
        H5CX_SET_PROP(H5D_XFER_COLL_CHUNK_LINK_HARD_NAME, mpio_coll_chunk_link_hard)
3347
        H5CX_SET_PROP(H5D_XFER_COLL_CHUNK_MULTI_HARD_NAME, mpio_coll_chunk_multi_hard)
3348
        H5CX_SET_PROP(H5D_XFER_COLL_CHUNK_LINK_NUM_TRUE_NAME, mpio_coll_chunk_link_num_true)
3349
        H5CX_SET_PROP(H5D_XFER_COLL_CHUNK_LINK_NUM_FALSE_NAME, mpio_coll_chunk_link_num_false)
3350
        H5CX_SET_PROP(H5D_XFER_COLL_CHUNK_MULTI_RATIO_COLL_NAME, mpio_coll_chunk_multi_ratio_coll)
3351
        H5CX_SET_PROP(H5D_XFER_COLL_CHUNK_MULTI_RATIO_IND_NAME, mpio_coll_chunk_multi_ratio_ind)
3352
        H5CX_SET_PROP(H5D_XFER_COLL_RANK0_BCAST_NAME, mpio_coll_rank0_bcast)
3353
#endif /* H5_HAVE_INSTRUMENTED_LIBRARY */
3354
#endif /* H5_HAVE_PARALLEL */
3355
113
    }  /* end if */
3356
3357
    /* Pop the top context node from the stack */
3358
113
    (*head) = (*head)->next;
3359
3360
113
done:
3361
113
    FUNC_LEAVE_NOAPI(ret_value)
3362
113
} /* end H5CX_pop() */