1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /*
15 * Open object info algorithms.
16 *
17 * These are used to track the objects currently open in a file, for various
18 * internal mechanisms which need to be aware of such things.
19 *
20 */
21
22 #define H5F_PACKAGE /*suppress error about including H5Fpkg */
23
24
25 #include "H5Eprivate.h" /* Error handling */
26 #include "H5Fpkg.h" /* File access */
27 #include "H5FLprivate.h" /* Free lists */
28 #include "H5FOprivate.h" /* File objects */
29 #include "H5Oprivate.h" /* Object headers */
30
31 /* Private typedefs */
32
33 /* Information about open objects in a file */
34 typedef struct H5FO_open_obj_t {
35 haddr_t addr; /* Address of object header for object */
36 void *obj; /* Pointer to the object */
37 hbool_t deleted; /* Flag to indicate that the object was deleted from the file */
38 } H5FO_open_obj_t;
39
40 /* Information about counted objects in a file */
41 typedef struct H5FO_obj_count_t {
42 haddr_t addr; /* Address of object header for object */
43 hsize_t count; /* Number of times object is opened */
44 } H5FO_obj_count_t;
45
46 /* Declare a free list to manage the H5FO_open_obj_t struct */
47 H5FL_DEFINE_STATIC(H5FO_open_obj_t);
48
49 /* Declare a free list to manage the H5FO_obj_count_t struct */
50 H5FL_DEFINE_STATIC(H5FO_obj_count_t);
51
52
53 /*--------------------------------------------------------------------------
54 NAME
55 H5FO_create
56 PURPOSE
57 Create an open object info set
58 USAGE
59 herr_t H5FO_create(f)
60 H5F_t *f; IN/OUT: File to create opened object info set for
61
62 RETURNS
63 Returns non-negative on success, negative on failure
64 DESCRIPTION
65 Create a new open object info set.
66 GLOBAL VARIABLES
67 COMMENTS, BUGS, ASSUMPTIONS
68 EXAMPLES
69 REVISION LOG
70 --------------------------------------------------------------------------*/
71 herr_t
H5FO_create(const H5F_t * f)72 H5FO_create(const H5F_t *f)
73 {
74 herr_t ret_value=SUCCEED; /* Return value */
75
76 FUNC_ENTER_NOAPI(FAIL)
77
78 /* Sanity check */
79 HDassert(f);
80 HDassert(f->shared);
81
82 /* Create container used to store open object info */
83 if((f->shared->open_objs = H5SL_create(H5SL_TYPE_HADDR, NULL)) == NULL)
84 HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create open object container")
85
86 done:
87 FUNC_LEAVE_NOAPI(ret_value)
88 } /* end H5FO_create() */
89
90
91 /*--------------------------------------------------------------------------
92 NAME
93 H5FO_opened
94 PURPOSE
95 Checks if an object at an address is already open in the file.
96 USAGE
97 void * H5FO_opened(f,addr)
98 const H5F_t *f; IN: File to check opened object info set
99 haddr_t addr; IN: Address of object to check
100
101 RETURNS
102 Returns a pointer to the object on success, NULL on failure
103 DESCRIPTION
104 Check is an object at an address (the address of the object's object header)
105 is already open in the file and return the ID for that object if it is open.
106 GLOBAL VARIABLES
107 COMMENTS, BUGS, ASSUMPTIONS
108 EXAMPLES
109 REVISION LOG
110 --------------------------------------------------------------------------*/
111 void *
H5FO_opened(const H5F_t * f,haddr_t addr)112 H5FO_opened(const H5F_t *f, haddr_t addr)
113 {
114 H5FO_open_obj_t *open_obj; /* Information about open object */
115 void *ret_value; /* Return value */
116
117 FUNC_ENTER_NOAPI_NOERR
118
119 /* Sanity check */
120 HDassert(f);
121 HDassert(f->shared);
122 HDassert(f->shared->open_objs);
123 HDassert(H5F_addr_defined(addr));
124
125 /* Get the object node from the container */
126 if(NULL != (open_obj = (H5FO_open_obj_t *)H5SL_search(f->shared->open_objs,&addr))) {
127 ret_value = open_obj->obj;
128 HDassert(ret_value != NULL);
129 } /* end if */
130 else
131 ret_value = NULL;
132
133 FUNC_LEAVE_NOAPI(ret_value)
134 } /* end H5FO_opened() */
135
136
137 /*--------------------------------------------------------------------------
138 NAME
139 H5FO_insert
140 PURPOSE
141 Insert a newly opened object/pointer pair into the opened object info set
142 USAGE
143 herr_t H5FO_insert(f,addr,obj)
144 H5F_t *f; IN/OUT: File's opened object info set
145 haddr_t addr; IN: Address of object to insert
146 void *obj; IN: Pointer to object to insert
147 hbool_t delete_flag; IN: Whether to 'mark' this object for deletion
148
149 RETURNS
150 Returns a non-negative on success, negative on failure
151 DESCRIPTION
152 Insert an object/ID pair into the opened object info set.
153 GLOBAL VARIABLES
154 COMMENTS, BUGS, ASSUMPTIONS
155 EXAMPLES
156 REVISION LOG
157 --------------------------------------------------------------------------*/
158 herr_t
H5FO_insert(const H5F_t * f,haddr_t addr,void * obj,hbool_t delete_flag)159 H5FO_insert(const H5F_t *f, haddr_t addr, void *obj, hbool_t delete_flag)
160 {
161 H5FO_open_obj_t *open_obj; /* Information about open object */
162 herr_t ret_value=SUCCEED; /* Return value */
163
164 FUNC_ENTER_NOAPI(FAIL)
165
166 /* Sanity check */
167 HDassert(f);
168 HDassert(f->shared);
169 HDassert(f->shared->open_objs);
170 HDassert(H5F_addr_defined(addr));
171 HDassert(obj);
172
173 /* Allocate new opened object information structure */
174 if((open_obj=H5FL_MALLOC(H5FO_open_obj_t))==NULL)
175 HGOTO_ERROR(H5E_CACHE,H5E_NOSPACE,FAIL,"memory allocation failed")
176
177 /* Assign information */
178 open_obj->addr=addr;
179 open_obj->obj=obj;
180 open_obj->deleted=delete_flag;
181
182 /* Insert into container */
183 if(H5SL_insert(f->shared->open_objs,&open_obj->addr,open_obj)<0)
184 HGOTO_ERROR(H5E_CACHE,H5E_CANTINSERT,FAIL,"can't insert object into container")
185
186 done:
187 FUNC_LEAVE_NOAPI(ret_value)
188 } /* end H5FO_insert() */
189
190
191 /*--------------------------------------------------------------------------
192 NAME
193 H5FO_delete
194 PURPOSE
195 Remove an opened object/ID pair from the opened object info set
196 USAGE
197 herr_t H5FO_delete(f,addr)
198 H5F_t *f; IN/OUT: File's opened object info set
199 haddr_t addr; IN: Address of object to remove
200
201 RETURNS
202 Returns a non-negative on success, negative on failure
203 DESCRIPTION
204 Remove an object/ID pair from the opened object info.
205 GLOBAL VARIABLES
206 COMMENTS, BUGS, ASSUMPTIONS
207 EXAMPLES
208 REVISION LOG
209 --------------------------------------------------------------------------*/
210 herr_t
H5FO_delete(H5F_t * f,hid_t dxpl_id,haddr_t addr)211 H5FO_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
212 {
213 H5FO_open_obj_t *open_obj; /* Information about open object */
214 herr_t ret_value=SUCCEED; /* Return value */
215
216 FUNC_ENTER_NOAPI(FAIL)
217
218 /* Sanity check */
219 HDassert(f);
220 HDassert(f->shared);
221 HDassert(f->shared->open_objs);
222 HDassert(H5F_addr_defined(addr));
223
224 /* Remove from container */
225 if(NULL == (open_obj = (H5FO_open_obj_t *)H5SL_remove(f->shared->open_objs, &addr)))
226 HGOTO_ERROR(H5E_CACHE,H5E_CANTRELEASE,FAIL,"can't remove object from container")
227
228 /* Check if the object was deleted from the file */
229 if(open_obj->deleted) {
230 if(H5O_delete(f, dxpl_id, addr) < 0)
231 HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file")
232 } /* end if */
233
234 /* Release the object information */
235 open_obj = H5FL_FREE(H5FO_open_obj_t, open_obj);
236
237 done:
238 FUNC_LEAVE_NOAPI(ret_value)
239 } /* end H5FO_delete() */
240
241
242 /*--------------------------------------------------------------------------
243 NAME
244 H5FO_mark
245 PURPOSE
246 Mark an object to be deleted when it is closed
247 USAGE
248 herr_t H5FO_mark(f,addr)
249 const H5F_t *f; IN: File opened object is in
250 haddr_t addr; IN: Address of object to delete
251
252 RETURNS
253 Returns a non-negative ID for the object on success, negative on failure
254 DESCRIPTION
255 Mark an opened object for deletion from the file when it is closed.
256 GLOBAL VARIABLES
257 COMMENTS, BUGS, ASSUMPTIONS
258 EXAMPLES
259 REVISION LOG
260 --------------------------------------------------------------------------*/
261 herr_t
H5FO_mark(const H5F_t * f,haddr_t addr,hbool_t deleted)262 H5FO_mark(const H5F_t *f, haddr_t addr, hbool_t deleted)
263 {
264 H5FO_open_obj_t *open_obj; /* Information about open object */
265 herr_t ret_value=SUCCEED; /* Return value */
266
267 FUNC_ENTER_NOAPI_NOERR
268
269 /* Sanity check */
270 HDassert(f);
271 HDassert(f->shared);
272 HDassert(f->shared->open_objs);
273 HDassert(H5F_addr_defined(addr));
274
275 /* Get the object node from the container */
276 if(NULL != (open_obj = (H5FO_open_obj_t *)H5SL_search(f->shared->open_objs, &addr)))
277 open_obj->deleted = deleted;
278 else
279 ret_value = FAIL;
280
281 FUNC_LEAVE_NOAPI(ret_value)
282 } /* end H5FO_mark() */
283
284
285 /*--------------------------------------------------------------------------
286 NAME
287 H5FO_marked
288 PURPOSE
289 Check if an object is marked to be deleted when it is closed
290 USAGE
291 hbool_t H5FO_marked(f,addr)
292 const H5F_t *f; IN: File opened object is in
293 haddr_t addr; IN: Address of object to delete
294
295 RETURNS
296 Returns a TRUE/FALSE on success
297 DESCRIPTION
298 Checks if the object is currently in the "opened objects" tree and
299 whether its marks for deletion from the file when it is closed.
300 GLOBAL VARIABLES
301 COMMENTS, BUGS, ASSUMPTIONS
302 EXAMPLES
303 REVISION LOG
304 --------------------------------------------------------------------------*/
305 hbool_t
H5FO_marked(const H5F_t * f,haddr_t addr)306 H5FO_marked(const H5F_t *f, haddr_t addr)
307 {
308 H5FO_open_obj_t *open_obj; /* Information about open object */
309 hbool_t ret_value = FALSE; /* Return value */
310
311 FUNC_ENTER_NOAPI_NOERR
312
313 /* Sanity check */
314 HDassert(f);
315 HDassert(f->shared);
316 HDassert(f->shared->open_objs);
317 HDassert(H5F_addr_defined(addr));
318
319 /* Get the object node from the container */
320 if(NULL != (open_obj = (H5FO_open_obj_t *)H5SL_search(f->shared->open_objs, &addr)))
321 ret_value = open_obj->deleted;
322
323 FUNC_LEAVE_NOAPI(ret_value)
324 } /* end H5FO_marked() */
325
326
327 /*--------------------------------------------------------------------------
328 NAME
329 H5FO_dest
330 PURPOSE
331 Destroy an open object info set
332 USAGE
333 herr_t H5FO_dest(f)
334 H5F_t *f; IN/OUT: File's opened object info set
335
336 RETURNS
337 Returns a non-negative on success, negative on failure
338 DESCRIPTION
339 Destroy an existing open object info set.
340 GLOBAL VARIABLES
341 COMMENTS, BUGS, ASSUMPTIONS
342 EXAMPLES
343 REVISION LOG
344 --------------------------------------------------------------------------*/
345 herr_t
H5FO_dest(const H5F_t * f)346 H5FO_dest(const H5F_t *f)
347 {
348 herr_t ret_value=SUCCEED; /* Return value */
349
350 FUNC_ENTER_NOAPI(FAIL)
351
352 /* Sanity check */
353 HDassert(f);
354 HDassert(f->shared);
355 HDassert(f->shared->open_objs);
356
357 /* Check if the object info set is empty */
358 if(H5SL_count(f->shared->open_objs)!=0)
359 HGOTO_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "objects still in open object info set")
360
361 /* Release the open object info set container */
362 if(H5SL_close(f->shared->open_objs)<0)
363 HGOTO_ERROR(H5E_CACHE, H5E_CANTCLOSEOBJ, FAIL, "can't close open object info set")
364
365 f->shared->open_objs=NULL;
366
367 done:
368 FUNC_LEAVE_NOAPI(ret_value)
369 } /* end H5FO_dest() */
370
371
372 /*--------------------------------------------------------------------------
373 NAME
374 H5FO_top_create
375 PURPOSE
376 Create the "top" open object count set
377 USAGE
378 herr_t H5FO_create(f)
379 H5F_t *f; IN/OUT: File to create opened object count set for
380
381 RETURNS
382 Returns non-negative on success, negative on failure
383 DESCRIPTION
384 Create a new open object count set.
385 GLOBAL VARIABLES
386 COMMENTS, BUGS, ASSUMPTIONS
387 EXAMPLES
388 REVISION LOG
389 --------------------------------------------------------------------------*/
390 herr_t
H5FO_top_create(H5F_t * f)391 H5FO_top_create(H5F_t *f)
392 {
393 herr_t ret_value = SUCCEED; /* Return value */
394
395 FUNC_ENTER_NOAPI(FAIL)
396
397 /* Sanity check */
398 HDassert(f);
399
400 /* Create container used to store open object info */
401 if((f->obj_count = H5SL_create(H5SL_TYPE_HADDR, NULL)) == NULL)
402 HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to create open object container")
403
404 done:
405 FUNC_LEAVE_NOAPI(ret_value)
406 } /* end H5FO_top_create() */
407
408
409 /*--------------------------------------------------------------------------
410 NAME
411 H5FO_top_incr
412 PURPOSE
413 Increment the "top" reference count for an object in a file
414 USAGE
415 herr_t H5FO_top_incr(f, addr)
416 H5F_t *f; IN/OUT: File's opened object info set
417 haddr_t addr; IN: Address of object to increment
418
419 RETURNS
420 Returns a non-negative on success, negative on failure
421 DESCRIPTION
422 Increment the reference count for an object in the opened object count set.
423 GLOBAL VARIABLES
424 COMMENTS, BUGS, ASSUMPTIONS
425 EXAMPLES
426 REVISION LOG
427 --------------------------------------------------------------------------*/
428 herr_t
H5FO_top_incr(const H5F_t * f,haddr_t addr)429 H5FO_top_incr(const H5F_t *f, haddr_t addr)
430 {
431 H5FO_obj_count_t *obj_count; /* Ref. count for object */
432 herr_t ret_value = SUCCEED; /* Return value */
433
434 FUNC_ENTER_NOAPI(FAIL)
435
436 /* Sanity check */
437 HDassert(f);
438 HDassert(f->obj_count);
439 HDassert(H5F_addr_defined(addr));
440
441 /* Get the object node from the container */
442 if(NULL != (obj_count = (H5FO_obj_count_t *)H5SL_search(f->obj_count, &addr))) {
443 (obj_count->count)++;
444 } /* end if */
445 else {
446 /* Allocate new opened object information structure */
447 if(NULL == (obj_count = H5FL_MALLOC(H5FO_obj_count_t)))
448 HGOTO_ERROR(H5E_CACHE,H5E_NOSPACE,FAIL,"memory allocation failed")
449
450 /* Assign information */
451 obj_count->addr = addr;
452 obj_count->count = 1;
453
454 /* Insert into container */
455 if(H5SL_insert(f->obj_count, &obj_count->addr, obj_count) < 0)
456 HGOTO_ERROR(H5E_CACHE,H5E_CANTINSERT,FAIL,"can't insert object into container")
457 } /* end if */
458
459 done:
460 FUNC_LEAVE_NOAPI(ret_value)
461 } /* end H5FO_top_incr() */
462
463
464 /*--------------------------------------------------------------------------
465 NAME
466 H5FO_top_decr
467 PURPOSE
468 Decrement the "top" reference count for an object in a file
469 USAGE
470 herr_t H5FO_top_decr(f, addr)
471 H5F_t *f; IN/OUT: File's opened object info set
472 haddr_t addr; IN: Address of object to decrement
473
474 RETURNS
475 Returns a non-negative on success, negative on failure
476 DESCRIPTION
477 Decrement the reference count for an object in the opened object count set.
478 GLOBAL VARIABLES
479 COMMENTS, BUGS, ASSUMPTIONS
480 EXAMPLES
481 REVISION LOG
482 --------------------------------------------------------------------------*/
483 herr_t
H5FO_top_decr(const H5F_t * f,haddr_t addr)484 H5FO_top_decr(const H5F_t *f, haddr_t addr)
485 {
486 H5FO_obj_count_t *obj_count; /* Ref. count for object */
487 herr_t ret_value = SUCCEED; /* Return value */
488
489 FUNC_ENTER_NOAPI(FAIL)
490
491 /* Sanity check */
492 HDassert(f);
493 HDassert(f->obj_count);
494 HDassert(H5F_addr_defined(addr));
495
496 /* Get the object node from the container */
497 if(NULL != (obj_count = (H5FO_obj_count_t *)H5SL_search(f->obj_count, &addr))) {
498 /* Decrement the reference count for the object */
499 (obj_count->count)--;
500
501 if(obj_count->count == 0) {
502 /* Remove from container */
503 if(NULL == (obj_count = (H5FO_obj_count_t *)H5SL_remove(f->obj_count, &addr)))
504 HGOTO_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "can't remove object from container")
505
506 /* Release the object information */
507 obj_count = H5FL_FREE(H5FO_obj_count_t, obj_count);
508 } /* end if */
509 } /* end if */
510 else
511 HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, "can't decrement ref. count")
512
513 done:
514 FUNC_LEAVE_NOAPI(ret_value)
515 } /* end H5FO_top_decr() */
516
517
518 /*--------------------------------------------------------------------------
519 NAME
520 H5FO_top_count
521 PURPOSE
522 Return the "top" reference count for an object in a file
523 USAGE
524 hsize_t H5FO_top_incr(f, addr)
525 H5F_t *f; IN/OUT: File's opened object info set
526 haddr_t addr; IN: Address of object to increment
527
528 RETURNS
529 Returns a non-negative on success, negative on failure
530 DESCRIPTION
531 Retrieves the reference count for an object in the opened object count set.
532 GLOBAL VARIABLES
533 COMMENTS, BUGS, ASSUMPTIONS
534 EXAMPLES
535 REVISION LOG
536 --------------------------------------------------------------------------*/
537 hsize_t
H5FO_top_count(const H5F_t * f,haddr_t addr)538 H5FO_top_count(const H5F_t *f, haddr_t addr)
539 {
540 H5FO_obj_count_t *obj_count; /* Ref. count for object */
541 hsize_t ret_value; /* Return value */
542
543 FUNC_ENTER_NOAPI_NOINIT_NOERR
544
545 /* Sanity check */
546 HDassert(f);
547 HDassert(f->obj_count);
548 HDassert(H5F_addr_defined(addr));
549
550 /* Get the object node from the container */
551 if(NULL != (obj_count = (H5FO_obj_count_t *)H5SL_search(f->obj_count, &addr)))
552 ret_value = obj_count->count;
553 else
554 ret_value = 0;
555
556 FUNC_LEAVE_NOAPI(ret_value)
557 } /* end H5FO_top_count() */
558
559
560 /*--------------------------------------------------------------------------
561 NAME
562 H5FO_top_dest
563 PURPOSE
564 Destroy an open object info set
565 USAGE
566 herr_t H5FO_top_dest(f)
567 H5F_t *f; IN/OUT: File's opened object info set
568
569 RETURNS
570 Returns a non-negative on success, negative on failure
571 DESCRIPTION
572 Destroy an existing open object info set.
573 GLOBAL VARIABLES
574 COMMENTS, BUGS, ASSUMPTIONS
575 EXAMPLES
576 REVISION LOG
577 --------------------------------------------------------------------------*/
578 herr_t
H5FO_top_dest(H5F_t * f)579 H5FO_top_dest(H5F_t *f)
580 {
581 herr_t ret_value = SUCCEED; /* Return value */
582
583 FUNC_ENTER_NOAPI(FAIL)
584
585 /* Sanity check */
586 HDassert(f);
587 HDassert(f->obj_count);
588
589 /* Check if the object count set is empty */
590 if(H5SL_count(f->obj_count) != 0)
591 HGOTO_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "objects still in open object info set")
592
593 /* Release the open object count set container */
594 if(H5SL_close(f->obj_count) < 0)
595 HGOTO_ERROR(H5E_CACHE, H5E_CANTCLOSEOBJ, FAIL, "can't close open object info set")
596
597 f->obj_count = NULL;
598
599 done:
600 FUNC_LEAVE_NOAPI(ret_value)
601 } /* end H5FO_top_dest() */
602
603