Coverage Report

Created: 2025-10-10 06:41

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
1.92k
{
73
1.92k
    herr_t ret_value = SUCCEED; /* Return value */
74
75
1.92k
    FUNC_ENTER_NOAPI(FAIL)
76
77
    /* Sanity check */
78
1.92k
    assert(f);
79
1.92k
    assert(f->shared);
80
81
    /* Create container used to store open object info */
82
1.92k
    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
1.92k
done:
86
1.92k
    FUNC_LEAVE_NOAPI(ret_value)
87
1.92k
} /* 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
382
{
112
382
    H5FO_open_obj_t *open_obj;  /* Information about open object */
113
382
    void            *ret_value; /* Return value */
114
115
382
    FUNC_ENTER_NOAPI_NOERR
116
117
    /* Sanity check */
118
382
    assert(f);
119
382
    assert(f->shared);
120
382
    assert(f->shared->open_objs);
121
382
    assert(H5_addr_defined(addr));
122
123
    /* Get the object node from the container */
124
382
    if (NULL != (open_obj = (H5FO_open_obj_t *)H5SL_search(f->shared->open_objs, &addr))) {
125
0
        ret_value = open_obj->obj;
126
0
        assert(ret_value != NULL);
127
0
    } /* end if */
128
382
    else
129
382
        ret_value = NULL;
130
131
382
    FUNC_LEAVE_NOAPI(ret_value)
132
382
} /* 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
56
{
158
56
    H5FO_open_obj_t *open_obj;            /* Information about open object */
159
56
    herr_t           ret_value = SUCCEED; /* Return value */
160
161
56
    FUNC_ENTER_NOAPI(FAIL)
162
163
    /* Sanity check */
164
56
    assert(f);
165
56
    assert(f->shared);
166
56
    assert(f->shared->open_objs);
167
56
    assert(H5_addr_defined(addr));
168
56
    assert(obj);
169
170
    /* Allocate new opened object information structure */
171
56
    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
56
    open_obj->addr    = addr;
176
56
    open_obj->obj     = obj;
177
56
    open_obj->deleted = delete_flag;
178
179
    /* Insert into container */
180
56
    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
56
done:
184
56
    FUNC_LEAVE_NOAPI(ret_value)
185
56
} /* 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
56
{
209
56
    H5FO_open_obj_t *open_obj;            /* Information about open object */
210
56
    herr_t           ret_value = SUCCEED; /* Return value */
211
212
56
    FUNC_ENTER_NOAPI(FAIL)
213
214
    /* Sanity check */
215
56
    assert(f);
216
56
    assert(f->shared);
217
56
    assert(f->shared->open_objs);
218
56
    assert(H5_addr_defined(addr));
219
220
    /* Remove from container */
221
56
    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
56
    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
56
    open_obj = H5FL_FREE(H5FO_open_obj_t, open_obj);
232
233
56
done:
234
56
    FUNC_LEAVE_NOAPI(ret_value)
235
56
} /* 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
53
{
303
53
    H5FO_open_obj_t *open_obj;          /* Information about open object */
304
53
    bool             ret_value = false; /* Return value */
305
306
53
    FUNC_ENTER_NOAPI_NOERR
307
308
    /* Sanity check */
309
53
    assert(f);
310
53
    assert(f->shared);
311
53
    assert(f->shared->open_objs);
312
53
    assert(H5_addr_defined(addr));
313
314
    /* Get the object node from the container */
315
53
    if (NULL != (open_obj = (H5FO_open_obj_t *)H5SL_search(f->shared->open_objs, &addr)))
316
0
        ret_value = open_obj->deleted;
317
318
53
    FUNC_LEAVE_NOAPI(ret_value)
319
53
} /* 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
1.92k
{
342
1.92k
    herr_t ret_value = SUCCEED; /* Return value */
343
344
1.92k
    FUNC_ENTER_NOAPI(FAIL)
345
346
    /* Sanity check */
347
1.92k
    assert(f);
348
1.92k
    assert(f->shared);
349
1.92k
    assert(f->shared->open_objs);
350
351
    /* Check if the object info set is empty */
352
1.92k
    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
1.92k
    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
1.92k
    f->shared->open_objs = NULL;
360
361
1.92k
done:
362
1.92k
    FUNC_LEAVE_NOAPI(ret_value)
363
1.92k
} /* 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
1.92k
{
386
1.92k
    herr_t ret_value = SUCCEED; /* Return value */
387
388
1.92k
    FUNC_ENTER_NOAPI(FAIL)
389
390
    /* Sanity check */
391
1.92k
    assert(f);
392
393
    /* Create container used to store open object info */
394
1.92k
    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
1.92k
done:
398
1.92k
    FUNC_LEAVE_NOAPI(ret_value)
399
1.92k
} /* 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
56
{
423
56
    H5FO_obj_count_t *obj_count;           /* Ref. count for object */
424
56
    herr_t            ret_value = SUCCEED; /* Return value */
425
426
56
    FUNC_ENTER_NOAPI(FAIL)
427
428
    /* Sanity check */
429
56
    assert(f);
430
56
    assert(f->obj_count);
431
56
    assert(H5_addr_defined(addr));
432
433
    /* Get the object node from the container */
434
56
    if (NULL != (obj_count = (H5FO_obj_count_t *)H5SL_search(f->obj_count, &addr))) {
435
0
        (obj_count->count)++;
436
0
    } /* end if */
437
56
    else {
438
        /* Allocate new opened object information structure */
439
56
        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
56
        obj_count->addr  = addr;
444
56
        obj_count->count = 1;
445
446
        /* Insert into container */
447
56
        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
56
    } /* end if */
450
451
56
done:
452
56
    FUNC_LEAVE_NOAPI(ret_value)
453
56
} /* 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
56
{
477
56
    H5FO_obj_count_t *obj_count;           /* Ref. count for object */
478
56
    herr_t            ret_value = SUCCEED; /* Return value */
479
480
56
    FUNC_ENTER_NOAPI(FAIL)
481
482
    /* Sanity check */
483
56
    assert(f);
484
56
    assert(f->obj_count);
485
56
    assert(H5_addr_defined(addr));
486
487
    /* Get the object node from the container */
488
56
    if (NULL != (obj_count = (H5FO_obj_count_t *)H5SL_search(f->obj_count, &addr))) {
489
        /* Decrement the reference count for the object */
490
56
        (obj_count->count)--;
491
492
56
        if (obj_count->count == 0) {
493
            /* Remove from container */
494
56
            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
56
            obj_count = H5FL_FREE(H5FO_obj_count_t, obj_count);
499
56
        } /* end if */
500
56
    }     /* end if */
501
0
    else
502
0
        HGOTO_ERROR(H5E_CACHE, H5E_NOTFOUND, FAIL, "can't decrement ref. count");
503
504
56
done:
505
56
    FUNC_LEAVE_NOAPI(ret_value)
506
56
} /* 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
0
{
530
0
    H5FO_obj_count_t *obj_count; /* Ref. count for object */
531
0
    hsize_t           ret_value; /* Return value */
532
533
0
    FUNC_ENTER_NOAPI_NOINIT_NOERR
534
535
    /* Sanity check */
536
0
    assert(f);
537
0
    assert(f->obj_count);
538
0
    assert(H5_addr_defined(addr));
539
540
    /* Get the object node from the container */
541
0
    if (NULL != (obj_count = (H5FO_obj_count_t *)H5SL_search(f->obj_count, &addr)))
542
0
        ret_value = obj_count->count;
543
0
    else
544
0
        ret_value = 0;
545
546
0
    FUNC_LEAVE_NOAPI(ret_value)
547
0
} /* 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
1.92k
{
570
1.92k
    herr_t ret_value = SUCCEED; /* Return value */
571
572
1.92k
    FUNC_ENTER_NOAPI(FAIL)
573
574
    /* Sanity check */
575
1.92k
    assert(f);
576
1.92k
    assert(f->obj_count);
577
578
    /* Check if the object count set is empty */
579
1.92k
    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
1.92k
    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
1.92k
    f->obj_count = NULL;
587
588
1.92k
done:
589
1.92k
    FUNC_LEAVE_NOAPI(ret_value)
590
1.92k
} /* end H5FO_top_dest() */