Line | Count | Source (jump to first uncovered line) |
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 COPYING 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: The Virtual Object Layer as described in documentation. |
15 | | * The purpose is to provide an abstraction on how to access the |
16 | | * underlying HDF5 container, whether in a local file with |
17 | | * a specific file format, or remotely on other machines, etc... |
18 | | */ |
19 | | |
20 | | /****************/ |
21 | | /* Module Setup */ |
22 | | /****************/ |
23 | | |
24 | | #include "H5VLmodule.h" /* This source code file is part of the H5VL module */ |
25 | | |
26 | | /***********/ |
27 | | /* Headers */ |
28 | | /***********/ |
29 | | |
30 | | #include "H5private.h" /* Generic Functions */ |
31 | | #include "H5CXprivate.h" /* API Contexts */ |
32 | | #include "H5Eprivate.h" /* Error handling */ |
33 | | #include "H5Iprivate.h" /* IDs */ |
34 | | #include "H5Pprivate.h" /* Property lists */ |
35 | | #include "H5Tprivate.h" /* Datatypes */ |
36 | | #include "H5VLpkg.h" /* Virtual Object Layer */ |
37 | | |
38 | | /* VOL connectors */ |
39 | | #include "H5VLnative.h" /* Native VOL connector */ |
40 | | |
41 | | /****************/ |
42 | | /* Local Macros */ |
43 | | /****************/ |
44 | | |
45 | | /******************/ |
46 | | /* Local Typedefs */ |
47 | | /******************/ |
48 | | |
49 | | /********************/ |
50 | | /* Local Prototypes */ |
51 | | /********************/ |
52 | | |
53 | | /*********************/ |
54 | | /* Package Variables */ |
55 | | /*********************/ |
56 | | |
57 | | /*****************************/ |
58 | | /* Library Private Variables */ |
59 | | /*****************************/ |
60 | | |
61 | | /*******************/ |
62 | | /* Local Variables */ |
63 | | /*******************/ |
64 | | |
65 | | /*------------------------------------------------------------------------- |
66 | | * Function: H5VLregister_connector |
67 | | * |
68 | | * Purpose: Registers a new VOL connector as a member of the virtual object |
69 | | * layer class. |
70 | | * |
71 | | * VIPL_ID is a VOL initialization property list which must be |
72 | | * created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT). |
73 | | * |
74 | | * Return: Success: A VOL connector ID which is good until the |
75 | | * library is closed or the connector is |
76 | | * unregistered. |
77 | | * |
78 | | * Failure: H5I_INVALID_HID |
79 | | * |
80 | | *------------------------------------------------------------------------- |
81 | | */ |
82 | | hid_t |
83 | | H5VLregister_connector(const H5VL_class_t *cls, hid_t vipl_id) |
84 | 0 | { |
85 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
86 | |
|
87 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
88 | 0 | H5TRACE2("i", "*#i", cls, vipl_id); |
89 | | |
90 | | /* Check VOL initialization property list */ |
91 | 0 | if (H5P_DEFAULT == vipl_id) |
92 | 0 | vipl_id = H5P_VOL_INITIALIZE_DEFAULT; |
93 | 0 | else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE)) |
94 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list"); |
95 | | |
96 | | /* Register connector */ |
97 | 0 | if ((ret_value = H5VL__register_connector_by_class(cls, true, vipl_id)) < 0) |
98 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector"); |
99 | | |
100 | 0 | done: |
101 | 0 | FUNC_LEAVE_API(ret_value) |
102 | 0 | } /* end H5VLregister_connector() */ |
103 | | |
104 | | /*------------------------------------------------------------------------- |
105 | | * Function: H5VLregister_connector_by_name |
106 | | * |
107 | | * Purpose: Registers a new VOL connector as a member of the virtual object |
108 | | * layer class. |
109 | | * |
110 | | * VIPL_ID is a VOL initialization property list which must be |
111 | | * created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT). |
112 | | * |
113 | | * Return: Success: A VOL connector ID which is good until the |
114 | | * library is closed or the connector is |
115 | | * unregistered. |
116 | | * |
117 | | * Failure: H5I_INVALID_HID |
118 | | * |
119 | | *------------------------------------------------------------------------- |
120 | | */ |
121 | | hid_t |
122 | | H5VLregister_connector_by_name(const char *name, hid_t vipl_id) |
123 | 0 | { |
124 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
125 | |
|
126 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
127 | 0 | H5TRACE2("i", "*si", name, vipl_id); |
128 | | |
129 | | /* Check arguments */ |
130 | 0 | if (!name) |
131 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, "null VOL connector name is disallowed"); |
132 | 0 | if (0 == strlen(name)) |
133 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, |
134 | 0 | "zero-length VOL connector name is disallowed"); |
135 | | |
136 | | /* Check VOL initialization property list */ |
137 | 0 | if (H5P_DEFAULT == vipl_id) |
138 | 0 | vipl_id = H5P_VOL_INITIALIZE_DEFAULT; |
139 | 0 | else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE)) |
140 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list"); |
141 | | |
142 | | /* Register connector */ |
143 | 0 | if ((ret_value = H5VL__register_connector_by_name(name, true, vipl_id)) < 0) |
144 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector"); |
145 | | |
146 | 0 | done: |
147 | 0 | FUNC_LEAVE_API(ret_value) |
148 | 0 | } /* end H5VLregister_connector_by_name() */ |
149 | | |
150 | | /*------------------------------------------------------------------------- |
151 | | * Function: H5VLregister_connector_by_value |
152 | | * |
153 | | * Purpose: Registers a new VOL connector as a member of the virtual object |
154 | | * layer class. |
155 | | * |
156 | | * VIPL_ID is a VOL initialization property list which must be |
157 | | * created with H5Pcreate(H5P_VOL_INITIALIZE) (or H5P_DEFAULT). |
158 | | * |
159 | | * Return: Success: A VOL connector ID which is good until the |
160 | | * library is closed or the connector is |
161 | | * unregistered. |
162 | | * |
163 | | * Failure: H5I_INVALID_HID |
164 | | * |
165 | | *------------------------------------------------------------------------- |
166 | | */ |
167 | | hid_t |
168 | | H5VLregister_connector_by_value(H5VL_class_value_t value, hid_t vipl_id) |
169 | 0 | { |
170 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
171 | |
|
172 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
173 | 0 | H5TRACE2("i", "VCi", value, vipl_id); |
174 | | |
175 | | /* Check arguments */ |
176 | 0 | if (value < 0) |
177 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, H5I_INVALID_HID, |
178 | 0 | "negative VOL connector value is disallowed"); |
179 | | |
180 | | /* Check VOL initialization property list */ |
181 | 0 | if (H5P_DEFAULT == vipl_id) |
182 | 0 | vipl_id = H5P_VOL_INITIALIZE_DEFAULT; |
183 | 0 | else if (true != H5P_isa_class(vipl_id, H5P_VOL_INITIALIZE)) |
184 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not a VOL initialize property list"); |
185 | | |
186 | | /* Register connector */ |
187 | 0 | if ((ret_value = H5VL__register_connector_by_value(value, true, vipl_id)) < 0) |
188 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register VOL connector"); |
189 | | |
190 | 0 | done: |
191 | 0 | FUNC_LEAVE_API(ret_value) |
192 | 0 | } /* end H5VLregister_connector_by_value() */ |
193 | | |
194 | | /*------------------------------------------------------------------------- |
195 | | * Function: H5VLis_connector_registered_by_name |
196 | | * |
197 | | * Purpose: Tests whether a VOL class has been registered or not |
198 | | * according to a supplied connector name. |
199 | | * |
200 | | * Return: >0 if a VOL connector with that name has been registered |
201 | | * 0 if a VOL connector with that name has NOT been registered |
202 | | * <0 on errors |
203 | | * |
204 | | *------------------------------------------------------------------------- |
205 | | */ |
206 | | htri_t |
207 | | H5VLis_connector_registered_by_name(const char *name) |
208 | 0 | { |
209 | 0 | htri_t ret_value = false; /* Return value */ |
210 | |
|
211 | 0 | FUNC_ENTER_API(FAIL) |
212 | 0 | H5TRACE1("t", "*s", name); |
213 | | |
214 | | /* Check if connector with this name is registered */ |
215 | 0 | if ((ret_value = H5VL__is_connector_registered_by_name(name)) < 0) |
216 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't check for VOL"); |
217 | | |
218 | 0 | done: |
219 | 0 | FUNC_LEAVE_API(ret_value) |
220 | 0 | } /* end H5VLis_connector_registered_by_name() */ |
221 | | |
222 | | /*------------------------------------------------------------------------- |
223 | | * Function: H5VLis_connector_registered_by_value |
224 | | * |
225 | | * Purpose: Tests whether a VOL class has been registered or not |
226 | | * according to a supplied connector value (ID). |
227 | | * |
228 | | * Return: >0 if a VOL connector with that value has been registered |
229 | | * 0 if a VOL connector with that value hasn't been registered |
230 | | * <0 on errors |
231 | | * |
232 | | *------------------------------------------------------------------------- |
233 | | */ |
234 | | htri_t |
235 | | H5VLis_connector_registered_by_value(H5VL_class_value_t connector_value) |
236 | 0 | { |
237 | 0 | htri_t ret_value = false; |
238 | |
|
239 | 0 | FUNC_ENTER_API(FAIL) |
240 | 0 | H5TRACE1("t", "VC", connector_value); |
241 | | |
242 | | /* Check if connector with this value is registered */ |
243 | 0 | if ((ret_value = H5VL__is_connector_registered_by_value(connector_value)) < 0) |
244 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't check for VOL"); |
245 | | |
246 | 0 | done: |
247 | 0 | FUNC_LEAVE_API(ret_value) |
248 | 0 | } /* end H5VLis_connector_registered_by_value() */ |
249 | | |
250 | | /*------------------------------------------------------------------------- |
251 | | * Function: H5VLget_connector_id |
252 | | * |
253 | | * Purpose: Retrieves the VOL connector ID for a given object ID. |
254 | | * |
255 | | * Return: A valid VOL connector ID. This ID will need to be closed |
256 | | * using H5VLclose(). |
257 | | * |
258 | | * H5I_INVALID_HID on error. |
259 | | * |
260 | | *------------------------------------------------------------------------- |
261 | | */ |
262 | | hid_t |
263 | | H5VLget_connector_id(hid_t obj_id) |
264 | 0 | { |
265 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
266 | |
|
267 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
268 | 0 | H5TRACE1("i", "i", obj_id); |
269 | | |
270 | | /* Get connector ID */ |
271 | 0 | if ((ret_value = H5VL__get_connector_id(obj_id, true)) < 0) |
272 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id"); |
273 | | |
274 | 0 | done: |
275 | 0 | FUNC_LEAVE_API(ret_value) |
276 | 0 | } /* end H5VLget_connector_id() */ |
277 | | |
278 | | /*------------------------------------------------------------------------- |
279 | | * Function: H5VLget_connector_id_by_name |
280 | | * |
281 | | * Purpose: Retrieves the ID for a registered VOL connector. |
282 | | * |
283 | | * Return: A valid VOL connector ID if a connector by that name has |
284 | | * been registered. This ID will need to be closed using |
285 | | * H5VLclose(). |
286 | | * |
287 | | * H5I_INVALID_HID on error or if a VOL connector of that |
288 | | * name has not been registered. |
289 | | * |
290 | | *------------------------------------------------------------------------- |
291 | | */ |
292 | | hid_t |
293 | | H5VLget_connector_id_by_name(const char *name) |
294 | 0 | { |
295 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
296 | |
|
297 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
298 | 0 | H5TRACE1("i", "*s", name); |
299 | | |
300 | | /* Get connector ID with this name */ |
301 | 0 | if ((ret_value = H5VL__get_connector_id_by_name(name, true)) < 0) |
302 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id"); |
303 | | |
304 | 0 | done: |
305 | 0 | FUNC_LEAVE_API(ret_value) |
306 | 0 | } /* end H5VLget_connector_id_by_name() */ |
307 | | |
308 | | /*------------------------------------------------------------------------- |
309 | | * Function: H5VLget_connector_id_by_value |
310 | | * |
311 | | * Purpose: Retrieves the ID for a registered VOL connector. |
312 | | * |
313 | | * Return: A valid VOL connector ID if a connector with that value has |
314 | | * been registered. This ID will need to be closed using |
315 | | * H5VLclose(). |
316 | | * |
317 | | * H5I_INVALID_HID on error or if a VOL connector with that |
318 | | * value has not been registered. |
319 | | * |
320 | | *------------------------------------------------------------------------- |
321 | | */ |
322 | | hid_t |
323 | | H5VLget_connector_id_by_value(H5VL_class_value_t connector_value) |
324 | 0 | { |
325 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
326 | |
|
327 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
328 | 0 | H5TRACE1("i", "VC", connector_value); |
329 | | |
330 | | /* Get connector ID with this value */ |
331 | 0 | if ((ret_value = H5VL__get_connector_id_by_value(connector_value, true)) < 0) |
332 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id"); |
333 | | |
334 | 0 | done: |
335 | 0 | FUNC_LEAVE_API(ret_value) |
336 | 0 | } /* end H5VLget_connector_id_by_value() */ |
337 | | |
338 | | /*------------------------------------------------------------------------- |
339 | | * Function: H5VLpeek_connector_id_by_name |
340 | | * |
341 | | * Purpose: Retrieves the ID for a registered VOL connector. |
342 | | * |
343 | | * Return: A valid VOL connector ID if a connector by that name has |
344 | | * been registered. This ID is *not* owned by the caller and |
345 | | * H5VLclose() should not be called. Intended for use by VOL |
346 | | * connectors to find their own ID. |
347 | | * |
348 | | * H5I_INVALID_HID on error or if a VOL connector of that |
349 | | * name has not been registered. |
350 | | * |
351 | | *------------------------------------------------------------------------- |
352 | | */ |
353 | | hid_t |
354 | | H5VLpeek_connector_id_by_name(const char *name) |
355 | 0 | { |
356 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
357 | |
|
358 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
359 | 0 | H5TRACE1("i", "*s", name); |
360 | | |
361 | | /* Get connector ID with this name */ |
362 | 0 | if ((ret_value = H5VL__peek_connector_id_by_name(name)) < 0) |
363 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id"); |
364 | | |
365 | 0 | done: |
366 | 0 | FUNC_LEAVE_API(ret_value) |
367 | 0 | } /* end H5VLpeek_connector_id_by_name() */ |
368 | | |
369 | | /*------------------------------------------------------------------------- |
370 | | * Function: H5VLpeek_connector_id_by_value |
371 | | * |
372 | | * Purpose: Retrieves the ID for a registered VOL connector. |
373 | | * |
374 | | * Return: A valid VOL connector ID if a connector with that value |
375 | | * has been registered. This ID is *not* owned by the caller |
376 | | * and H5VLclose() should not be called. Intended for use by |
377 | | * VOL connectors to find their own ID. |
378 | | * |
379 | | * H5I_INVALID_HID on error or if a VOL connector with that |
380 | | * value has not been registered. |
381 | | * |
382 | | *------------------------------------------------------------------------- |
383 | | */ |
384 | | hid_t |
385 | | H5VLpeek_connector_id_by_value(H5VL_class_value_t value) |
386 | 0 | { |
387 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
388 | |
|
389 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
390 | 0 | H5TRACE1("i", "VC", value); |
391 | | |
392 | | /* Get connector ID with this value */ |
393 | 0 | if ((ret_value = H5VL__peek_connector_id_by_value(value)) < 0) |
394 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, H5I_INVALID_HID, "can't get VOL id"); |
395 | | |
396 | 0 | done: |
397 | 0 | FUNC_LEAVE_API(ret_value) |
398 | 0 | } /* end H5VLpeek_connector_id_by_value() */ |
399 | | |
400 | | /*------------------------------------------------------------------------- |
401 | | * Function: H5VLget_connector_name |
402 | | * |
403 | | * Purpose: Returns the connector name for the VOL associated with the |
404 | | * object or file ID. |
405 | | * |
406 | | * This works like other calls where the caller must provide a |
407 | | * buffer of the appropriate size for the library to fill in. |
408 | | * i.e., passing in a NULL pointer for NAME will return the |
409 | | * required size of the buffer. |
410 | | * |
411 | | * Return: Success: The length of the connector name |
412 | | * |
413 | | * Failure: Negative |
414 | | * |
415 | | *------------------------------------------------------------------------- |
416 | | */ |
417 | | ssize_t |
418 | | H5VLget_connector_name(hid_t obj_id, char *name /*out*/, size_t size) |
419 | 0 | { |
420 | 0 | ssize_t ret_value = -1; |
421 | |
|
422 | 0 | FUNC_ENTER_API(FAIL) |
423 | 0 | H5TRACE3("Zs", "ixz", obj_id, name, size); |
424 | | |
425 | | /* Call internal routine */ |
426 | 0 | if ((ret_value = H5VL__get_connector_name(obj_id, name, size)) < 0) |
427 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "Can't get connector name"); |
428 | | |
429 | 0 | done: |
430 | 0 | FUNC_LEAVE_API(ret_value) |
431 | 0 | } /* end H5VLget_connector_name() */ |
432 | | |
433 | | /*------------------------------------------------------------------------- |
434 | | * Function: H5VLclose |
435 | | * |
436 | | * Purpose: Closes a VOL connector ID. This in no way affects |
437 | | * file access property lists which have been defined to use |
438 | | * this VOL connector or files which are already opened under with |
439 | | * this connector. |
440 | | * |
441 | | * Return: Success: Non-negative |
442 | | * Failure: Negative |
443 | | * |
444 | | *------------------------------------------------------------------------- |
445 | | */ |
446 | | herr_t |
447 | | H5VLclose(hid_t vol_id) |
448 | 0 | { |
449 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
450 | |
|
451 | 0 | FUNC_ENTER_API(FAIL) |
452 | 0 | H5TRACE1("e", "i", vol_id); |
453 | | |
454 | | /* Check args */ |
455 | 0 | if (NULL == H5I_object_verify(vol_id, H5I_VOL)) |
456 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector"); |
457 | | |
458 | | /* Decrement the ref count on the ID, possibly releasing the VOL connector */ |
459 | 0 | if (H5I_dec_app_ref(vol_id) < 0) |
460 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to close VOL connector ID"); |
461 | | |
462 | 0 | done: |
463 | 0 | FUNC_LEAVE_API(ret_value) |
464 | 0 | } /* end H5VLclose() */ |
465 | | |
466 | | /*------------------------------------------------------------------------- |
467 | | * Function: H5VLunregister_connector |
468 | | * |
469 | | * Purpose: Removes a VOL connector ID from the library. This in no way affects |
470 | | * file access property lists which have been defined to use |
471 | | * this VOL connector or files which are already opened under with |
472 | | * this connector. |
473 | | * |
474 | | * The native VOL connector cannot be unregistered and attempts |
475 | | * to do so are considered an error. |
476 | | * |
477 | | * Return: Success: Non-negative |
478 | | * |
479 | | * Failure: Negative |
480 | | * |
481 | | *------------------------------------------------------------------------- |
482 | | */ |
483 | | herr_t |
484 | | H5VLunregister_connector(hid_t vol_id) |
485 | 0 | { |
486 | 0 | hid_t native_id = H5I_INVALID_HID; |
487 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
488 | |
|
489 | 0 | FUNC_ENTER_API(FAIL) |
490 | 0 | H5TRACE1("e", "i", vol_id); |
491 | | |
492 | | /* Check arguments */ |
493 | 0 | if (NULL == H5I_object_verify(vol_id, H5I_VOL)) |
494 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADTYPE, FAIL, "not a VOL connector ID"); |
495 | | |
496 | | /* For the time being, we disallow unregistering the native VOL connector */ |
497 | 0 | if (H5I_INVALID_HID == (native_id = H5VL__get_connector_id_by_name(H5VL_NATIVE_NAME, false))) |
498 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to find the native VOL connector ID"); |
499 | 0 | if (vol_id == native_id) |
500 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "unregistering the native VOL connector is not allowed"); |
501 | | |
502 | | /* The H5VL_class_t struct will be freed by this function */ |
503 | 0 | if (H5I_dec_app_ref(vol_id) < 0) |
504 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to unregister VOL connector"); |
505 | | |
506 | 0 | done: |
507 | 0 | if (native_id != H5I_INVALID_HID) |
508 | 0 | if (H5I_dec_ref(native_id) < 0) |
509 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to decrement count on native_id"); |
510 | | |
511 | 0 | FUNC_LEAVE_API(ret_value) |
512 | 0 | } /* end H5VLunregister_connector() */ |
513 | | |
514 | | /*--------------------------------------------------------------------------- |
515 | | * Function: H5VLcmp_connector_cls |
516 | | * |
517 | | * Purpose: Compares two connector classes (based on their value field) |
518 | | * |
519 | | * Note: This routine is _only_ for HDF5 VOL connector authors! It is |
520 | | * _not_ part of the public API for HDF5 application developers. |
521 | | * |
522 | | * Return: Success: Non-negative, *cmp set to a value like strcmp |
523 | | * |
524 | | * Failure: Negative, *cmp unset |
525 | | * |
526 | | *--------------------------------------------------------------------------- |
527 | | */ |
528 | | herr_t |
529 | | H5VLcmp_connector_cls(int *cmp, hid_t connector_id1, hid_t connector_id2) |
530 | 0 | { |
531 | 0 | H5VL_class_t *cls1, *cls2; /* connectors for IDs */ |
532 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
533 | |
|
534 | 0 | FUNC_ENTER_API(FAIL) |
535 | 0 | H5TRACE3("e", "*Isii", cmp, connector_id1, connector_id2); |
536 | | |
537 | | /* Check args and get class pointers */ |
538 | 0 | if (NULL == (cls1 = (H5VL_class_t *)H5I_object_verify(connector_id1, H5I_VOL))) |
539 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID"); |
540 | 0 | if (NULL == (cls2 = (H5VL_class_t *)H5I_object_verify(connector_id2, H5I_VOL))) |
541 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a VOL connector ID"); |
542 | | |
543 | | /* Compare the two VOL connector classes */ |
544 | 0 | if (H5VL_cmp_connector_cls(cmp, cls1, cls2) < 0) |
545 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTCOMPARE, FAIL, "can't compare connector classes"); |
546 | | |
547 | 0 | done: |
548 | 0 | FUNC_LEAVE_API(ret_value) |
549 | 0 | } /* H5VLcmp_connector_cls() */ |
550 | | |
551 | | /*--------------------------------------------------------------------------- |
552 | | * Function: H5VLwrap_register |
553 | | * |
554 | | * Purpose: Wrap an internal object with a "wrap context" and register an |
555 | | * hid_t for the resulting object. |
556 | | * |
557 | | * Note: This routine is mainly targeted toward wrapping objects for |
558 | | * iteration routine callbacks (i.e. the callbacks from H5Aiterate*, |
559 | | * H5Literate* / H5Lvisit*, and H5Ovisit* ). |
560 | | * |
561 | | * type must be a VOL-managed object class (H5I_FILE, |
562 | | * H5I_GROUP, H5I_DATATYPE, H5I_DATASET, H5I_MAP, or H5I_ATTR). |
563 | | * |
564 | | * Return: Success: Non-negative hid_t for the object. |
565 | | * Failure: Negative (H5I_INVALID_HID) |
566 | | * |
567 | | *--------------------------------------------------------------------------- |
568 | | */ |
569 | | hid_t |
570 | | H5VLwrap_register(void *obj, H5I_type_t type) |
571 | 0 | { |
572 | 0 | hid_t ret_value; /* Return value */ |
573 | | |
574 | | /* Use FUNC_ENTER_API_NOINIT here, so the API context doesn't get reset */ |
575 | 0 | FUNC_ENTER_API_NOINIT |
576 | 0 | H5TRACE2("i", "*xIt", obj, type); |
577 | | |
578 | | /* Check args */ |
579 | | /* Use a switch here for (hopefully) better performance than a series of |
580 | | * equality checks. We could also group these types together in H5I_type_t, |
581 | | * make some assertions here to guarantee that, then just check the range. |
582 | | */ |
583 | 0 | switch (type) { |
584 | 0 | case H5I_FILE: |
585 | 0 | case H5I_GROUP: |
586 | 0 | case H5I_DATATYPE: |
587 | 0 | case H5I_DATASET: |
588 | 0 | case H5I_MAP: |
589 | 0 | case H5I_ATTR: |
590 | | /* VOL-managed objects, call is valid */ |
591 | 0 | break; |
592 | 0 | case H5I_UNINIT: |
593 | 0 | case H5I_BADID: |
594 | 0 | case H5I_DATASPACE: |
595 | 0 | case H5I_VFL: |
596 | 0 | case H5I_VOL: |
597 | 0 | case H5I_GENPROP_CLS: |
598 | 0 | case H5I_GENPROP_LST: |
599 | 0 | case H5I_ERROR_CLASS: |
600 | 0 | case H5I_ERROR_MSG: |
601 | 0 | case H5I_ERROR_STACK: |
602 | 0 | case H5I_SPACE_SEL_ITER: |
603 | 0 | case H5I_EVENTSET: |
604 | 0 | case H5I_NTYPES: |
605 | 0 | default: |
606 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADRANGE, H5I_INVALID_HID, "invalid type number"); |
607 | 0 | } /* end switch */ |
608 | 0 | if (NULL == obj) |
609 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, H5I_INVALID_HID, "obj is NULL"); |
610 | | |
611 | | /* Wrap the object and register an ID for it */ |
612 | 0 | if ((ret_value = H5VL_wrap_register(type, obj, true)) < 0) |
613 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to wrap object"); |
614 | | |
615 | 0 | done: |
616 | 0 | FUNC_LEAVE_API_NOINIT(ret_value) |
617 | 0 | } /* H5VLwrap_register() */ |
618 | | |
619 | | /*--------------------------------------------------------------------------- |
620 | | * Function: H5VLobject |
621 | | * |
622 | | * Purpose: Retrieve the object pointer associated with an hid_t for a |
623 | | * VOL object. |
624 | | * |
625 | | * Note: This routine is mainly targeted toward unwrapping objects for |
626 | | * testing. |
627 | | * |
628 | | * Return: Success: Object pointer |
629 | | * Failure: NULL |
630 | | * |
631 | | *--------------------------------------------------------------------------- |
632 | | */ |
633 | | void * |
634 | | H5VLobject(hid_t id) |
635 | 0 | { |
636 | 0 | void *ret_value; /* Return value */ |
637 | |
|
638 | 0 | FUNC_ENTER_API(NULL) |
639 | 0 | H5TRACE1("*x", "i", id); |
640 | | |
641 | | /* Retrieve the object pointer for the ID */ |
642 | 0 | if (NULL == (ret_value = H5VL_object(id))) |
643 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, NULL, "unable to retrieve object"); |
644 | | |
645 | 0 | done: |
646 | 0 | FUNC_LEAVE_API(ret_value) |
647 | 0 | } /* H5VLobject() */ |
648 | | |
649 | | /*--------------------------------------------------------------------------- |
650 | | * Function: H5VLobject_is_native |
651 | | * |
652 | | * Purpose: Determines whether an object ID represents a native VOL |
653 | | * connector object. |
654 | | * |
655 | | * Return: Non-negative on success/Negative on failure |
656 | | * |
657 | | *--------------------------------------------------------------------------- |
658 | | */ |
659 | | herr_t |
660 | | H5VLobject_is_native(hid_t obj_id, hbool_t *is_native) |
661 | 0 | { |
662 | 0 | H5VL_object_t *vol_obj = NULL; |
663 | 0 | herr_t ret_value = SUCCEED; |
664 | |
|
665 | 0 | FUNC_ENTER_API(FAIL) |
666 | 0 | H5TRACE2("e", "i*b", obj_id, is_native); |
667 | |
|
668 | 0 | if (!is_native) |
669 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "`is_native` argument is NULL"); |
670 | | |
671 | | /* Get the location object for the ID */ |
672 | 0 | if (NULL == (vol_obj = H5VL_vol_object(obj_id))) |
673 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier"); |
674 | | |
675 | 0 | if (H5VL_object_is_native(vol_obj, is_native) < 0) |
676 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't determine if object is a native connector object"); |
677 | | |
678 | 0 | done: |
679 | 0 | FUNC_LEAVE_API(ret_value) |
680 | 0 | } /* H5VLobject_is_native() */ |
681 | | |
682 | | /*------------------------------------------------------------------------- |
683 | | * Function: H5VLget_file_type |
684 | | * |
685 | | * Purpose: Returns a copy of dtype_id with its location set to be in |
686 | | * the file, with updated size, etc. |
687 | | * |
688 | | * Return: Non-negative on success/Negative on failure |
689 | | * |
690 | | *------------------------------------------------------------------------- |
691 | | */ |
692 | | hid_t |
693 | | H5VLget_file_type(void *file_obj, hid_t connector_id, hid_t dtype_id) |
694 | 0 | { |
695 | 0 | H5T_t *dtype; /* unregistered type */ |
696 | 0 | H5T_t *file_type = NULL; /* copied file type */ |
697 | 0 | hid_t file_type_id = -1; /* copied file type id */ |
698 | 0 | H5VL_object_t *file_vol_obj = NULL; /* VOL object for file */ |
699 | 0 | hid_t ret_value = -1; /* Return value */ |
700 | |
|
701 | 0 | FUNC_ENTER_API(FAIL) |
702 | 0 | H5TRACE3("i", "*xii", file_obj, connector_id, dtype_id); |
703 | | |
704 | | /* Check args */ |
705 | 0 | if (!file_obj) |
706 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "no file object supplied"); |
707 | 0 | if (NULL == (dtype = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE))) |
708 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); |
709 | | |
710 | | /* Create VOL object for file if necessary (force_conv will be true if and |
711 | | * only if file needs to be passed to H5T_set_loc) */ |
712 | 0 | if (H5T_GET_FORCE_CONV(dtype) && |
713 | 0 | (NULL == (file_vol_obj = H5VL_create_object_using_vol_id(H5I_FILE, file_obj, connector_id)))) |
714 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTCREATE, FAIL, "can't create VOL object"); |
715 | | |
716 | | /* Copy the datatype */ |
717 | 0 | if (NULL == (file_type = H5T_copy(dtype, H5T_COPY_TRANSIENT))) |
718 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTCOPY, FAIL, "unable to copy datatype"); |
719 | | |
720 | | /* Register file type id */ |
721 | 0 | if ((file_type_id = H5I_register(H5I_DATATYPE, file_type, false)) < 0) { |
722 | 0 | (void)H5T_close_real(file_type); |
723 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, FAIL, "unable to register file datatype"); |
724 | 0 | } /* end if */ |
725 | | |
726 | | /* Set the location of the datatype to be in the file */ |
727 | 0 | if (H5T_set_loc(file_type, file_vol_obj, H5T_LOC_DISK) < 0) |
728 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't set datatype location"); |
729 | | |
730 | | /* Release our reference to file_type */ |
731 | 0 | if (file_vol_obj) { |
732 | 0 | if (H5VL_free_object(file_vol_obj) < 0) |
733 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to free VOL object"); |
734 | 0 | file_vol_obj = NULL; |
735 | 0 | } /* end if */ |
736 | | |
737 | | /* Set return value */ |
738 | 0 | ret_value = file_type_id; |
739 | |
|
740 | 0 | done: |
741 | | /* Cleanup on error */ |
742 | 0 | if (ret_value < 0) { |
743 | 0 | if (file_vol_obj && H5VL_free_object(file_vol_obj) < 0) |
744 | 0 | HDONE_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to free VOL object"); |
745 | 0 | if (file_type_id >= 0 && H5I_dec_ref(file_type_id) < 0) |
746 | 0 | HDONE_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to close file datatype"); |
747 | 0 | } /* end if */ |
748 | |
|
749 | 0 | FUNC_LEAVE_API(ret_value) |
750 | 0 | } /* end H5VLget_file_type() */ |
751 | | |
752 | | /*--------------------------------------------------------------------------- |
753 | | * Function: H5VLretrieve_lib_state |
754 | | * |
755 | | * Purpose: Retrieves a copy of the internal state of the HDF5 library, |
756 | | * so that it can be restored later. |
757 | | * |
758 | | * Note: This routine is _only_ for HDF5 VOL connector authors! It is |
759 | | * _not_ part of the public API for HDF5 application developers. |
760 | | * |
761 | | * Return: Success: Non-negative, *state set |
762 | | * Failure: Negative, *state unset |
763 | | * |
764 | | *--------------------------------------------------------------------------- |
765 | | */ |
766 | | herr_t |
767 | | H5VLretrieve_lib_state(void **state /*out*/) |
768 | 0 | { |
769 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
770 | | |
771 | | /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ |
772 | 0 | FUNC_ENTER_API_NOINIT |
773 | 0 | H5TRACE1("e", "x", state); |
774 | | |
775 | | /* Check args */ |
776 | 0 | if (NULL == state) |
777 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid state pointer"); |
778 | | |
779 | | /* Retrieve the library state */ |
780 | 0 | if (H5VL_retrieve_lib_state(state) < 0) |
781 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't retrieve library state"); |
782 | | |
783 | 0 | done: |
784 | 0 | FUNC_LEAVE_API_NOINIT(ret_value) |
785 | 0 | } /* H5VLretrieve_lib_state() */ |
786 | | |
787 | | /*--------------------------------------------------------------------------- |
788 | | * Function: H5VLstart_lib_state |
789 | | * |
790 | | * Purpose: Opens a new internal state for the HDF5 library. |
791 | | * |
792 | | * Note: This routine is _only_ for HDF5 VOL connector authors! It is |
793 | | * _not_ part of the public API for HDF5 application developers. |
794 | | * |
795 | | * Return: Success: Non-negative |
796 | | * Failure: Negative |
797 | | * |
798 | | *--------------------------------------------------------------------------- |
799 | | */ |
800 | | herr_t |
801 | | H5VLstart_lib_state(void) |
802 | 0 | { |
803 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
804 | | |
805 | | /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ |
806 | 0 | FUNC_ENTER_API_NOINIT |
807 | 0 | H5TRACE0("e", ""); |
808 | | |
809 | | /* Start a new library state */ |
810 | 0 | if (H5VL_start_lib_state() < 0) |
811 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't start new library state"); |
812 | | |
813 | 0 | done: |
814 | 0 | FUNC_LEAVE_API_NOINIT(ret_value) |
815 | 0 | } /* H5VLstart_lib_state() */ |
816 | | |
817 | | /*--------------------------------------------------------------------------- |
818 | | * Function: H5VLrestore_lib_state |
819 | | * |
820 | | * Purpose: Restores the internal state of the HDF5 library. |
821 | | * |
822 | | * Note: This routine is _only_ for HDF5 VOL connector authors! It is |
823 | | * _not_ part of the public API for HDF5 application developers. |
824 | | * |
825 | | * Return: Success: Non-negative |
826 | | * Failure: Negative |
827 | | * |
828 | | *--------------------------------------------------------------------------- |
829 | | */ |
830 | | herr_t |
831 | | H5VLrestore_lib_state(const void *state) |
832 | 0 | { |
833 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
834 | | |
835 | | /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ |
836 | 0 | FUNC_ENTER_API_NOINIT |
837 | 0 | H5TRACE1("e", "*x", state); |
838 | | |
839 | | /* Check args */ |
840 | 0 | if (NULL == state) |
841 | 0 | HGOTO_ERROR(H5E_VOL, H5E_BADVALUE, FAIL, "invalid state pointer"); |
842 | | |
843 | | /* Restore the library state */ |
844 | 0 | if (H5VL_restore_lib_state(state) < 0) |
845 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTSET, FAIL, "can't restore library state"); |
846 | | |
847 | 0 | done: |
848 | 0 | FUNC_LEAVE_API_NOINIT(ret_value) |
849 | 0 | } /* H5VLrestore_lib_state() */ |
850 | | |
851 | | /*--------------------------------------------------------------------------- |
852 | | * Function: H5VLfinish_lib_state |
853 | | * |
854 | | * Purpose: Closes the internal state of the HDF5 library, undoing the |
855 | | * affects of H5VLstart_lib_state. |
856 | | * |
857 | | * Note: This routine is _only_ for HDF5 VOL connector authors! It is |
858 | | * _not_ part of the public API for HDF5 application developers. |
859 | | * |
860 | | * Note: This routine must be called as a "pair" with |
861 | | * H5VLstart_lib_state. It can be called before / after / |
862 | | * independently of H5VLfree_lib_state. |
863 | | * |
864 | | * Return: Success: Non-negative |
865 | | * Failure: Negative |
866 | | * |
867 | | *--------------------------------------------------------------------------- |
868 | | */ |
869 | | herr_t |
870 | | H5VLfinish_lib_state(void) |
871 | 0 | { |
872 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
873 | | |
874 | | /* Must use this, to avoid modifying the API context stack in FUNC_ENTER */ |
875 | 0 | FUNC_ENTER_API_NOINIT |
876 | 0 | H5TRACE0("e", ""); |
877 | | |
878 | | /* Reset the library state */ |
879 | 0 | if (H5VL_finish_lib_state() < 0) |
880 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTRESET, FAIL, "can't reset library state"); |
881 | | |
882 | 0 | done: |
883 | 0 | FUNC_LEAVE_API_NOINIT(ret_value) |
884 | 0 | } /* H5VLfinish_lib_state() */ |
885 | | |
886 | | /*--------------------------------------------------------------------------- |
887 | | * Function: H5VLfree_lib_state |
888 | | * |
889 | | * Purpose: Free a retrieved library state. |
890 | | * |
891 | | * Note: This routine is _only_ for HDF5 VOL connector authors! It is |
892 | | * _not_ part of the public API for HDF5 application developers. |
893 | | * |
894 | | * Note: This routine must be called as a "pair" with |
895 | | * H5VLretrieve_lib_state. |
896 | | * |
897 | | * Return: Success: Non-negative |
898 | | * Failure: Negative |
899 | | * |
900 | | *--------------------------------------------------------------------------- |
901 | | */ |
902 | | herr_t |
903 | | H5VLfree_lib_state(void *state) |
904 | 0 | { |
905 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
906 | |
|
907 | 0 | FUNC_ENTER_API(FAIL) |
908 | 0 | H5TRACE1("e", "*x", state); |
909 | | |
910 | | /* Check args */ |
911 | 0 | if (NULL == state) |
912 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid state pointer"); |
913 | | |
914 | | /* Free the library state */ |
915 | 0 | if (H5VL_free_lib_state(state) < 0) |
916 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "can't free library state"); |
917 | | |
918 | 0 | done: |
919 | 0 | FUNC_LEAVE_API(ret_value) |
920 | 0 | } /* H5VLfree_lib_state() */ |
921 | | |
922 | | /*--------------------------------------------------------------------------- |
923 | | * Function: H5VLquery_optional |
924 | | * |
925 | | * Purpose: Determine if a VOL connector supports a particular optional |
926 | | * callback operation, and a general sense of the operation's |
927 | | * behavior. |
928 | | * |
929 | | * Return: Success: Non-negative |
930 | | * Failure: Negative |
931 | | * |
932 | | *--------------------------------------------------------------------------- |
933 | | */ |
934 | | herr_t |
935 | | H5VLquery_optional(hid_t obj_id, H5VL_subclass_t subcls, int opt_type, uint64_t *flags /*out*/) |
936 | 0 | { |
937 | 0 | H5VL_object_t *vol_obj = NULL; |
938 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
939 | |
|
940 | 0 | FUNC_ENTER_API(FAIL) |
941 | 0 | H5TRACE4("e", "iVSIsx", obj_id, subcls, opt_type, flags); |
942 | | |
943 | | /* Check args */ |
944 | 0 | if (NULL == flags) |
945 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid 'flags' pointer"); |
946 | 0 | if (NULL == (vol_obj = H5VL_vol_object(obj_id))) |
947 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier"); |
948 | | |
949 | | /* Query the connector */ |
950 | 0 | if (H5VL_introspect_opt_query(vol_obj, subcls, opt_type, flags) < 0) |
951 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "unable to query VOL connector operation"); |
952 | | |
953 | 0 | done: |
954 | 0 | FUNC_LEAVE_API(ret_value) |
955 | 0 | } /* H5VLquery_optional() */ |
956 | | |
957 | | /*--------------------------------------------------------------------------- |
958 | | * Function: H5VLregister_opt_operation |
959 | | * |
960 | | * Purpose: Allow a VOL connector to register a new optional operation |
961 | | * for a VOL object subclass. The operation name must be runtime |
962 | | * unique for each operation, preferably avoiding naming clashes |
963 | | * by using a Uniform Type Identifier (UTI, |
964 | | *https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/understanding_utis/understand_utis_conc/understand_utis_conc.html) |
965 | | * for each operation name. The value returned in the 'op_val' |
966 | | * pointer will be unique for that VOL connector to use for its |
967 | | * operation on that subclass. |
968 | | * |
969 | | * For example, registering a 'prefetch' operation for the |
970 | | * caching VOL connector written at the ALCF at Argonne National |
971 | | * Laboratory could have a UTI of: "gov.anl.alcf.cache.prefetch", |
972 | | * and the "evict" operation for the same connector could have a |
973 | | * UTI of: "gov.anl.alcf.cache.evict". Registering a "suspend |
974 | | * background threads" operation for the asynchronous VOL connector |
975 | | * written at NERSC at Lawrence Berkeley National Laboratory could |
976 | | * have a UTI of: "gov.lbnl.nersc.async.suspend_bkg_threads". |
977 | | * |
978 | | * Note: The first 1024 values of each subclass's optional operations |
979 | | * are reserved for the native VOL connector's use. |
980 | | * |
981 | | * Return: Success: Non-negative |
982 | | * Failure: Negative |
983 | | * |
984 | | *--------------------------------------------------------------------------- |
985 | | */ |
986 | | herr_t |
987 | | H5VLregister_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/) |
988 | 0 | { |
989 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
990 | |
|
991 | 0 | FUNC_ENTER_API(FAIL) |
992 | 0 | H5TRACE3("e", "VS*sx", subcls, op_name, op_val); |
993 | | |
994 | | /* Check args */ |
995 | 0 | if (NULL == op_val) |
996 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer"); |
997 | 0 | if (NULL == op_name) |
998 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer"); |
999 | 0 | if ('\0' == *op_name) |
1000 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string"); |
1001 | 0 | if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || |
1002 | 0 | (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || |
1003 | 0 | (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) |
1004 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type"); |
1005 | | |
1006 | | /* Register the operation */ |
1007 | 0 | if (H5VL__register_opt_operation(subcls, op_name, op_val) < 0) |
1008 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREGISTER, FAIL, "can't register dynamic optional operation: '%s'", |
1009 | 0 | op_name); |
1010 | | |
1011 | 0 | done: |
1012 | 0 | FUNC_LEAVE_API(ret_value) |
1013 | 0 | } /* H5VLregister_opt_operation() */ |
1014 | | |
1015 | | /*--------------------------------------------------------------------------- |
1016 | | * Function: H5VLfind_opt_operation |
1017 | | * |
1018 | | * Purpose: Look up a optional operation for a VOL object subclass, by name. |
1019 | | * |
1020 | | * Return: Success: Non-negative |
1021 | | * Failure: Negative |
1022 | | * |
1023 | | *--------------------------------------------------------------------------- |
1024 | | */ |
1025 | | herr_t |
1026 | | H5VLfind_opt_operation(H5VL_subclass_t subcls, const char *op_name, int *op_val /*out*/) |
1027 | 0 | { |
1028 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
1029 | |
|
1030 | 0 | FUNC_ENTER_API(FAIL) |
1031 | 0 | H5TRACE3("e", "VS*sx", subcls, op_name, op_val); |
1032 | | |
1033 | | /* Check args */ |
1034 | 0 | if (NULL == op_val) |
1035 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_val pointer"); |
1036 | 0 | if (NULL == op_name) |
1037 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer"); |
1038 | 0 | if ('\0' == *op_name) |
1039 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string"); |
1040 | 0 | if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || |
1041 | 0 | (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || |
1042 | 0 | (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) |
1043 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type"); |
1044 | | |
1045 | | /* Find the operation */ |
1046 | 0 | if (H5VL__find_opt_operation(subcls, op_name, op_val) < 0) |
1047 | 0 | HGOTO_ERROR(H5E_VOL, H5E_NOTFOUND, FAIL, "can't find dynamic optional operation: '%s'", op_name); |
1048 | | |
1049 | 0 | done: |
1050 | 0 | FUNC_LEAVE_API(ret_value) |
1051 | 0 | } /* H5VLfind_opt_operation() */ |
1052 | | |
1053 | | /*--------------------------------------------------------------------------- |
1054 | | * Function: H5VLunregister_opt_operation |
1055 | | * |
1056 | | * Purpose: Unregister a optional operation for a VOL object subclass, by name. |
1057 | | * |
1058 | | * Return: Success: Non-negative |
1059 | | * Failure: Negative |
1060 | | * |
1061 | | *--------------------------------------------------------------------------- |
1062 | | */ |
1063 | | herr_t |
1064 | | H5VLunregister_opt_operation(H5VL_subclass_t subcls, const char *op_name) |
1065 | 0 | { |
1066 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
1067 | |
|
1068 | 0 | FUNC_ENTER_API(FAIL) |
1069 | 0 | H5TRACE2("e", "VS*s", subcls, op_name); |
1070 | | |
1071 | | /* Check args */ |
1072 | 0 | if (NULL == op_name) |
1073 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name pointer"); |
1074 | 0 | if ('\0' == *op_name) |
1075 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid op_name string"); |
1076 | 0 | if (!((H5VL_SUBCLS_ATTR == subcls) || (H5VL_SUBCLS_DATASET == subcls) || |
1077 | 0 | (H5VL_SUBCLS_DATATYPE == subcls) || (H5VL_SUBCLS_FILE == subcls) || (H5VL_SUBCLS_GROUP == subcls) || |
1078 | 0 | (H5VL_SUBCLS_OBJECT == subcls) || (H5VL_SUBCLS_LINK == subcls) || (H5VL_SUBCLS_REQUEST == subcls))) |
1079 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid VOL subclass type"); |
1080 | | |
1081 | | /* Unregister the operation */ |
1082 | 0 | if (H5VL__unregister_opt_operation(subcls, op_name) < 0) |
1083 | 0 | HGOTO_ERROR(H5E_VOL, H5E_CANTREMOVE, FAIL, "can't unregister dynamic optional operation: '%s'", |
1084 | 0 | op_name); |
1085 | | |
1086 | 0 | done: |
1087 | 0 | FUNC_LEAVE_API(ret_value) |
1088 | 0 | } /* H5VLunregister_opt_operation() */ |