Coverage Report

Created: 2026-10-28 18:12

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