Coverage Report

Created: 2025-08-26 06:30

/src/hdf5/src/H5ACproxy_entry.c
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 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
 *
15
 * Created:             H5ACproxy_entry.c
16
 *
17
 * Purpose:             Functions and a cache client for a "proxy" cache entry.
18
 *      A proxy cache entry is used as a placeholder for entire
19
 *      data structures to attach flush dependencies, etc.
20
 *
21
 *-------------------------------------------------------------------------
22
 */
23
24
/****************/
25
/* Module Setup */
26
/****************/
27
#include "H5ACmodule.h" /* This source code file is part of the H5AC module */
28
29
/***********/
30
/* Headers */
31
/***********/
32
#include "H5private.h"   /* Generic Functions                    */
33
#include "H5ACpkg.h"     /* Metadata cache                       */
34
#include "H5Eprivate.h"  /* Error handling                       */
35
#include "H5FLprivate.h" /* Free Lists                               */
36
#include "H5MFprivate.h" /* File memory management    */
37
#include "H5SLprivate.h" /* Skip Lists                               */
38
39
/****************/
40
/* Local Macros */
41
/****************/
42
43
/******************/
44
/* Local Typedefs */
45
/******************/
46
47
/********************/
48
/* Package Typedefs */
49
/********************/
50
51
/********************/
52
/* Local Prototypes */
53
/********************/
54
55
/* Metadata cache (H5AC) callbacks */
56
static herr_t H5AC__proxy_entry_image_len(const void *thing, size_t *image_len);
57
static herr_t H5AC__proxy_entry_serialize(const H5F_t *f, void *image_ptr, size_t len, void *thing);
58
static herr_t H5AC__proxy_entry_notify(H5AC_notify_action_t action, void *thing);
59
static herr_t H5AC__proxy_entry_free_icr(void *thing);
60
61
/*********************/
62
/* Package Variables */
63
/*********************/
64
65
/* H5AC proxy entries inherit cache-like properties from H5AC */
66
const H5AC_class_t H5AC_PROXY_ENTRY[1] = {{
67
    H5AC_PROXY_ENTRY_ID,         /* Metadata client ID */
68
    "Proxy entry",               /* Metadata client name (for debugging) */
69
    H5FD_MEM_SUPER,              /* File space memory type for client */
70
    0,                           /* Client class behavior flags */
71
    NULL,                        /* 'get_initial_load_size' callback */
72
    NULL,                        /* 'get_final_load_size' callback */
73
    NULL,                        /* 'verify_chksum' callback */
74
    NULL,                        /* 'deserialize' callback */
75
    H5AC__proxy_entry_image_len, /* 'image_len' callback */
76
    NULL,                        /* 'pre_serialize' callback */
77
    H5AC__proxy_entry_serialize, /* 'serialize' callback */
78
    H5AC__proxy_entry_notify,    /* 'notify' callback */
79
    H5AC__proxy_entry_free_icr,  /* 'free_icr' callback */
80
    NULL,                        /* 'fsf_size' callback */
81
}};
82
83
/*****************************/
84
/* Library Private Variables */
85
/*****************************/
86
87
/*******************/
88
/* Local Variables */
89
/*******************/
90
91
/* Declare a free list to manage H5AC_proxy_entry_t objects */
92
H5FL_DEFINE_STATIC(H5AC_proxy_entry_t);
93
94
/*-------------------------------------------------------------------------
95
 * Function:    H5AC_proxy_entry_create
96
 *
97
 * Purpose:     Create a new proxy entry
98
 *
99
 * Return:  Success:  Pointer to the new proxy entry object.
100
 *    Failure:  NULL
101
 *
102
 *-------------------------------------------------------------------------
103
 */
104
H5AC_proxy_entry_t *
105
H5AC_proxy_entry_create(void)
106
0
{
107
0
    H5AC_proxy_entry_t *pentry    = NULL; /* Pointer to new proxy entry */
108
0
    H5AC_proxy_entry_t *ret_value = NULL; /* Return value */
109
110
0
    FUNC_ENTER_NOAPI(NULL)
111
112
    /* Allocate new proxy entry */
113
0
    if (NULL == (pentry = H5FL_CALLOC(H5AC_proxy_entry_t)))
114
0
        HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "can't allocate proxy entry");
115
116
    /* Set non-zero fields */
117
0
    pentry->addr = HADDR_UNDEF;
118
119
    /* Set return value */
120
0
    ret_value = pentry;
121
122
0
done:
123
    /* Release resources on error */
124
0
    if (!ret_value)
125
0
        if (pentry)
126
0
            pentry = H5FL_FREE(H5AC_proxy_entry_t, pentry);
127
128
0
    FUNC_LEAVE_NOAPI(ret_value)
129
0
} /* end H5AC_proxy_entry_create() */
130
131
/*-------------------------------------------------------------------------
132
 * Function:    H5AC_proxy_entry_add_parent
133
 *
134
 * Purpose:     Add a parent to a proxy entry
135
 *
136
 * Return:      Non-negative on success/Negative on failure
137
 *
138
 *-------------------------------------------------------------------------
139
 */
140
herr_t
141
H5AC_proxy_entry_add_parent(H5AC_proxy_entry_t *pentry, void *_parent)
142
0
{
143
0
    H5AC_info_t *parent    = (H5AC_info_t *)_parent; /* Parent entry's cache info */
144
0
    herr_t       ret_value = SUCCEED;                /* Return value */
145
146
0
    FUNC_ENTER_NOAPI(FAIL)
147
148
    /* Sanity checks */
149
0
    assert(parent);
150
0
    assert(pentry);
151
152
    /* Add parent to the list of parents */
153
0
    if (NULL == pentry->parents)
154
0
        if (NULL == (pentry->parents = H5SL_create(H5SL_TYPE_HADDR, NULL)))
155
0
            HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, FAIL,
156
0
                        "unable to create skip list for parents of proxy entry");
157
158
    /* Insert parent address into skip list */
159
0
    if (H5SL_insert(pentry->parents, parent, &parent->addr) < 0)
160
0
        HGOTO_ERROR(H5E_CACHE, H5E_CANTINSERT, FAIL, "unable to insert parent into proxy's skip list");
161
162
    /* Add flush dependency on parent */
163
0
    if (pentry->nchildren > 0) {
164
        /* Sanity check */
165
0
        assert(H5_addr_defined(pentry->addr));
166
167
0
        if (H5AC_create_flush_dependency(parent, pentry) < 0)
168
0
            HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "unable to set flush dependency on proxy entry");
169
0
    } /* end if */
170
171
0
done:
172
0
    FUNC_LEAVE_NOAPI(ret_value)
173
0
} /* end H5AC_proxy_entry_add_parent() */
174
175
/*-------------------------------------------------------------------------
176
 * Function:    H5AC_proxy_entry_remove_parent
177
 *
178
 * Purpose:     Removes a parent from a proxy entry
179
 *
180
 * Return:      Non-negative on success/Negative on failure
181
 *
182
 *-------------------------------------------------------------------------
183
 */
184
herr_t
185
H5AC_proxy_entry_remove_parent(H5AC_proxy_entry_t *pentry, void *_parent)
186
0
{
187
0
    H5AC_info_t *parent = (H5AC_info_t *)_parent; /* Pointer to the parent entry */
188
0
    H5AC_info_t *rem_parent;                      /* Pointer to the removed parent entry */
189
0
    herr_t       ret_value = SUCCEED;             /* Return value */
190
191
0
    FUNC_ENTER_NOAPI(FAIL)
192
193
    /* Sanity checks */
194
0
    assert(pentry);
195
0
    assert(pentry->parents);
196
0
    assert(parent);
197
198
    /* Remove parent from skip list */
199
0
    if (NULL == (rem_parent = (H5AC_info_t *)H5SL_remove(pentry->parents, &parent->addr)))
200
0
        HGOTO_ERROR(H5E_CACHE, H5E_CANTREMOVE, FAIL, "unable to remove proxy entry parent from skip list");
201
0
    if (!H5_addr_eq(rem_parent->addr, parent->addr))
202
0
        HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "removed proxy entry parent not the same as real parent");
203
204
    /* Shut down the skip list, if this is the last parent */
205
0
    if (0 == H5SL_count(pentry->parents)) {
206
        /* Sanity check */
207
0
        assert(0 == pentry->nchildren);
208
209
0
        if (H5SL_close(pentry->parents) < 0)
210
0
            HGOTO_ERROR(H5E_CACHE, H5E_CLOSEERROR, FAIL, "can't close proxy parent skip list");
211
0
        pentry->parents = NULL;
212
0
    } /* end if */
213
214
    /* Remove flush dependency between the proxy entry and a parent */
215
0
    if (pentry->nchildren > 0)
216
0
        if (H5AC_destroy_flush_dependency(parent, pentry) < 0)
217
0
            HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL,
218
0
                        "unable to remove flush dependency on proxy entry");
219
220
0
done:
221
0
    FUNC_LEAVE_NOAPI(ret_value)
222
0
} /* end H5AC_proxy_entry_remove_parent() */
223
224
/*-------------------------------------------------------------------------
225
 * Function:  H5AC__proxy_entry_add_child_cb
226
 *
227
 * Purpose: Callback routine for adding an entry as a flush dependency for
228
 *    a proxy entry.
229
 *
230
 * Return:  Success:  Non-negative on success
231
 *    Failure:  Negative
232
 *
233
 *-------------------------------------------------------------------------
234
 */
235
static int
236
H5AC__proxy_entry_add_child_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata)
237
0
{
238
0
    H5AC_info_t        *parent    = (H5AC_info_t *)_item;         /* Pointer to the parent entry */
239
0
    H5AC_proxy_entry_t *pentry    = (H5AC_proxy_entry_t *)_udata; /* Pointer to the proxy entry */
240
0
    int                 ret_value = H5_ITER_CONT;                 /* Callback return value */
241
242
0
    FUNC_ENTER_PACKAGE
243
244
    /* Add flush dependency on parent for proxy entry */
245
0
    if (H5AC_create_flush_dependency(parent, pentry) < 0)
246
0
        HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, H5_ITER_ERROR,
247
0
                    "unable to set flush dependency for virtual entry");
248
249
0
done:
250
0
    FUNC_LEAVE_NOAPI(ret_value)
251
0
} /* end H5AC__proxy_entry_add_child_cb() */
252
253
/*-------------------------------------------------------------------------
254
 * Function:    H5AC_proxy_entry_add_child
255
 *
256
 * Purpose:     Add a child a proxy entry
257
 *
258
 * Return:      Non-negative on success/Negative on failure
259
 *
260
 *-------------------------------------------------------------------------
261
 */
262
herr_t
263
H5AC_proxy_entry_add_child(H5AC_proxy_entry_t *pentry, H5F_t *f, void *child)
264
0
{
265
0
    herr_t ret_value = SUCCEED; /* Return value */
266
267
0
    FUNC_ENTER_NOAPI(FAIL)
268
269
    /* Sanity checks */
270
0
    assert(pentry);
271
0
    assert(child);
272
273
    /* Check for first child */
274
0
    if (0 == pentry->nchildren) {
275
        /* Get an address, if the proxy doesn't already have one */
276
0
        if (!H5_addr_defined(pentry->addr))
277
0
            if (HADDR_UNDEF == (pentry->addr = H5MF_alloc_tmp(f, 1)))
278
0
                HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, FAIL,
279
0
                            "temporary file space allocation failed for proxy entry");
280
281
        /* Insert the proxy entry into the cache */
282
0
        if (H5AC_insert_entry(f, H5AC_PROXY_ENTRY, pentry->addr, pentry, H5AC__PIN_ENTRY_FLAG) < 0)
283
0
            HGOTO_ERROR(H5E_CACHE, H5E_CANTINSERT, FAIL, "unable to cache proxy entry");
284
285
        /* Proxies start out clean (insertions are automatically marked dirty) */
286
0
        if (H5AC_mark_entry_clean(pentry) < 0)
287
0
            HGOTO_ERROR(H5E_CACHE, H5E_CANTCLEAN, FAIL, "can't mark proxy entry clean");
288
289
        /* Proxies start out serialized (insertions are automatically marked unserialized) */
290
0
        if (H5AC_mark_entry_serialized(pentry) < 0)
291
0
            HGOTO_ERROR(H5E_CACHE, H5E_CANTSERIALIZE, FAIL, "can't mark proxy entry clean");
292
293
        /* If there are currently parents, iterate over the list of parents, creating flush dependency on them
294
         */
295
0
        if (pentry->parents)
296
0
            if (H5SL_iterate(pentry->parents, H5AC__proxy_entry_add_child_cb, pentry) < 0)
297
0
                HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "can't visit parents");
298
0
    } /* end if */
299
300
    /* Add flush dependency on proxy entry */
301
0
    if (H5AC_create_flush_dependency(pentry, child) < 0)
302
0
        HGOTO_ERROR(H5E_CACHE, H5E_CANTDEPEND, FAIL, "unable to set flush dependency on proxy entry");
303
304
    /* Increment count of children */
305
0
    pentry->nchildren++;
306
307
0
done:
308
0
    FUNC_LEAVE_NOAPI(ret_value)
309
0
} /* end H5AC_proxy_entry_add_child() */
310
311
/*-------------------------------------------------------------------------
312
 * Function:  H5AC__proxy_entry_remove_child_cb
313
 *
314
 * Purpose: Callback routine for removing an entry as a flush dependency for
315
 *    proxy entry.
316
 *
317
 * Return:  Success:  Non-negative on success
318
 *    Failure:  Negative
319
 *
320
 *-------------------------------------------------------------------------
321
 */
322
static int
323
H5AC__proxy_entry_remove_child_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata)
324
0
{
325
0
    H5AC_info_t        *parent    = (H5AC_info_t *)_item;         /* Pointer to the parent entry */
326
0
    H5AC_proxy_entry_t *pentry    = (H5AC_proxy_entry_t *)_udata; /* Pointer to the proxy entry */
327
0
    int                 ret_value = H5_ITER_CONT;                 /* Callback return value */
328
329
0
    FUNC_ENTER_PACKAGE
330
331
    /* Remove flush dependency on parent for proxy entry */
332
0
    if (H5AC_destroy_flush_dependency(parent, pentry) < 0)
333
0
        HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, H5_ITER_ERROR,
334
0
                    "unable to remove flush dependency for proxy entry");
335
336
0
done:
337
0
    FUNC_LEAVE_NOAPI(ret_value)
338
0
} /* end H5AC__proxy_entry_remove_child_cb() */
339
340
/*-------------------------------------------------------------------------
341
 * Function:    H5AC_proxy_entry_remove_child
342
 *
343
 * Purpose:     Remove a child a proxy entry
344
 *
345
 * Return:      Non-negative on success/Negative on failure
346
 *
347
 *-------------------------------------------------------------------------
348
 */
349
herr_t
350
H5AC_proxy_entry_remove_child(H5AC_proxy_entry_t *pentry, void *child)
351
0
{
352
0
    herr_t ret_value = SUCCEED; /* Return value */
353
354
0
    FUNC_ENTER_NOAPI(FAIL)
355
356
    /* Sanity checks */
357
0
    assert(pentry);
358
0
    assert(child);
359
360
    /* Remove flush dependency on proxy entry */
361
0
    if (H5AC_destroy_flush_dependency(pentry, child) < 0)
362
0
        HGOTO_ERROR(H5E_CACHE, H5E_CANTUNDEPEND, FAIL, "unable to remove flush dependency on proxy entry");
363
364
    /* Decrement count of children */
365
0
    pentry->nchildren--;
366
367
    /* Check for last child */
368
0
    if (0 == pentry->nchildren) {
369
        /* Check for flush dependencies on proxy's parents */
370
0
        if (pentry->parents)
371
            /* Iterate over the list of parents, removing flush dependency on them */
372
0
            if (H5SL_iterate(pentry->parents, H5AC__proxy_entry_remove_child_cb, pentry) < 0)
373
0
                HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "can't visit parents");
374
375
        /* Unpin proxy */
376
0
        if (H5AC_unpin_entry(pentry) < 0)
377
0
            HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPIN, FAIL, "can't unpin proxy entry");
378
379
        /* Remove proxy entry from cache */
380
0
        if (H5AC_remove_entry(pentry) < 0)
381
0
            HGOTO_ERROR(H5E_CACHE, H5E_CANTREMOVE, FAIL, "unable to remove proxy entry");
382
0
    } /* end if */
383
384
0
done:
385
0
    FUNC_LEAVE_NOAPI(ret_value)
386
0
} /* end H5AC_proxy_entry_remove_child() */
387
388
/*-------------------------------------------------------------------------
389
 * Function:    H5AC_proxy_entry_dest
390
 *
391
 * Purpose:     Destroys a proxy entry in memory.
392
 *
393
 * Return:      Non-negative on success/Negative on failure
394
 *
395
 *-------------------------------------------------------------------------
396
 */
397
herr_t
398
H5AC_proxy_entry_dest(H5AC_proxy_entry_t *pentry)
399
0
{
400
0
    herr_t ret_value = SUCCEED; /* Return value */
401
402
0
    FUNC_ENTER_NOAPI(FAIL)
403
404
    /* Sanity checks */
405
0
    assert(pentry);
406
0
    assert(NULL == pentry->parents);
407
0
    assert(0 == pentry->nchildren);
408
0
    assert(0 == pentry->ndirty_children);
409
0
    assert(0 == pentry->nunser_children);
410
411
    /* Free the proxy entry object */
412
0
    pentry = H5FL_FREE(H5AC_proxy_entry_t, pentry);
413
414
0
done:
415
0
    FUNC_LEAVE_NOAPI(ret_value)
416
0
} /* end H5AC_proxy_entry_dest() */
417
418
/*-------------------------------------------------------------------------
419
 * Function:    H5AC__proxy_entry_image_len
420
 *
421
 * Purpose:     Compute the size of the data structure on disk.
422
 *
423
 * Return:      Non-negative on success/Negative on failure
424
 *
425
 *-------------------------------------------------------------------------
426
 */
427
static herr_t
428
H5AC__proxy_entry_image_len(const void H5_ATTR_UNUSED *thing, size_t *image_len)
429
0
{
430
0
    FUNC_ENTER_PACKAGE_NOERR
431
432
    /* Check arguments */
433
0
    assert(image_len);
434
435
    /* Set the image length size to 1 byte */
436
0
    *image_len = 1;
437
438
0
    FUNC_LEAVE_NOAPI(SUCCEED)
439
0
} /* end H5AC__proxy_entry_image_len() */
440
441
/*-------------------------------------------------------------------------
442
 * Function:    H5AC__proxy_entry_serialize
443
 *
444
 * Purpose: Serializes a data structure for writing to disk.
445
 *
446
 * Note:  Should never be invoked.
447
 *
448
 * Return:      Non-negative on success/Negative on failure
449
 *
450
 *-------------------------------------------------------------------------
451
 */
452
static herr_t
453
H5AC__proxy_entry_serialize(const H5F_t H5_ATTR_UNUSED *f, void H5_ATTR_UNUSED *image,
454
                            size_t H5_ATTR_UNUSED len, void H5_ATTR_UNUSED *thing)
455
0
{
456
0
    FUNC_ENTER_PACKAGE_NOERR /* Yes, even though this pushes an error on the stack */
457
0
458
0
        /* Should never be invoked */
459
0
        assert(0 && "Invalid callback?!?");
460
461
0
    HERROR(H5E_CACHE, H5E_CANTSERIALIZE, "called unreachable fcn.");
462
463
0
    FUNC_LEAVE_NOAPI(FAIL)
464
0
} /* end H5AC__proxy_entry_serialize() */
465
466
/*-------------------------------------------------------------------------
467
 * Function:    H5AC__proxy_entry_notify
468
 *
469
 * Purpose:     Handle cache action notifications
470
 *
471
 * Return:      Non-negative on success/Negative on failure
472
 *
473
 *-------------------------------------------------------------------------
474
 */
475
static herr_t
476
H5AC__proxy_entry_notify(H5AC_notify_action_t action, void *_thing)
477
0
{
478
0
    H5AC_proxy_entry_t *pentry    = (H5AC_proxy_entry_t *)_thing;
479
0
    herr_t              ret_value = SUCCEED; /* Return value */
480
481
0
    FUNC_ENTER_PACKAGE
482
483
    /* Sanity check */
484
0
    assert(pentry);
485
486
0
    switch (action) {
487
0
        case H5AC_NOTIFY_ACTION_AFTER_INSERT:
488
0
            break;
489
490
0
        case H5AC_NOTIFY_ACTION_AFTER_LOAD:
491
0
#ifdef NDEBUG
492
0
            HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "invalid notify action from metadata cache");
493
#else  /* NDEBUG */
494
            assert(0 && "Invalid action?!?");
495
#endif /* NDEBUG */
496
0
            break;
497
498
0
        case H5AC_NOTIFY_ACTION_AFTER_FLUSH:
499
0
#ifdef NDEBUG
500
0
            HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "invalid notify action from metadata cache");
501
#else  /* NDEBUG */
502
            assert(0 && "Invalid action?!?");
503
#endif /* NDEBUG */
504
0
            break;
505
506
0
        case H5AC_NOTIFY_ACTION_BEFORE_EVICT:
507
            /* Sanity checks */
508
0
            assert(0 == pentry->ndirty_children);
509
0
            assert(0 == pentry->nunser_children);
510
511
            /* No action */
512
0
            break;
513
514
0
        case H5AC_NOTIFY_ACTION_ENTRY_DIRTIED:
515
            /* Sanity checks */
516
0
            assert(pentry->ndirty_children > 0);
517
518
            /* No action */
519
0
            break;
520
521
0
        case H5AC_NOTIFY_ACTION_ENTRY_CLEANED:
522
            /* Sanity checks */
523
0
            assert(0 == pentry->ndirty_children);
524
525
            /* No action */
526
0
            break;
527
528
0
        case H5AC_NOTIFY_ACTION_CHILD_DIRTIED:
529
            /* Increment # of dirty children */
530
0
            pentry->ndirty_children++;
531
532
            /* Check for first dirty child */
533
0
            if (1 == pentry->ndirty_children)
534
0
                if (H5AC_mark_entry_dirty(pentry) < 0)
535
0
                    HGOTO_ERROR(H5E_CACHE, H5E_CANTDIRTY, FAIL, "can't mark proxy entry dirty");
536
0
            break;
537
538
0
        case H5AC_NOTIFY_ACTION_CHILD_CLEANED:
539
            /* Sanity check */
540
0
            assert(pentry->ndirty_children > 0);
541
542
            /* Decrement # of dirty children */
543
0
            pentry->ndirty_children--;
544
545
            /* Check for last dirty child */
546
0
            if (0 == pentry->ndirty_children)
547
0
                if (H5AC_mark_entry_clean(pentry) < 0)
548
0
                    HGOTO_ERROR(H5E_CACHE, H5E_CANTCLEAN, FAIL, "can't mark proxy entry clean");
549
0
            break;
550
551
0
        case H5AC_NOTIFY_ACTION_CHILD_UNSERIALIZED:
552
            /* Increment # of unserialized children */
553
0
            pentry->nunser_children++;
554
555
            /* Check for first unserialized child */
556
0
            if (1 == pentry->nunser_children)
557
0
                if (H5AC_mark_entry_unserialized(pentry) < 0)
558
0
                    HGOTO_ERROR(H5E_CACHE, H5E_CANTUNSERIALIZE, FAIL, "can't mark proxy entry unserialized");
559
0
            break;
560
561
0
        case H5AC_NOTIFY_ACTION_CHILD_SERIALIZED:
562
            /* Sanity check */
563
0
            assert(pentry->nunser_children > 0);
564
565
            /* Decrement # of unserialized children */
566
0
            pentry->nunser_children--;
567
568
            /* Check for last unserialized child */
569
0
            if (0 == pentry->nunser_children)
570
0
                if (H5AC_mark_entry_serialized(pentry) < 0)
571
0
                    HGOTO_ERROR(H5E_CACHE, H5E_CANTSERIALIZE, FAIL, "can't mark proxy entry serialized");
572
0
            break;
573
574
0
        default:
575
0
#ifdef NDEBUG
576
0
            HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "unknown notify action from metadata cache");
577
#else  /* NDEBUG */
578
            assert(0 && "Unknown action?!?");
579
#endif /* NDEBUG */
580
0
    }  /* end switch */
581
582
0
done:
583
0
    FUNC_LEAVE_NOAPI(ret_value)
584
0
} /* end H5AC__proxy_entry_notify() */
585
586
/*-------------------------------------------------------------------------
587
 * Function:  H5AC__proxy_entry_free_icr
588
 *
589
 * Purpose: Destroy/release an "in core representation" of a data
590
 *              structure
591
 *
592
 * Return:  Non-negative on success/Negative on failure
593
 *
594
 *-------------------------------------------------------------------------
595
 */
596
static herr_t
597
H5AC__proxy_entry_free_icr(void *_thing)
598
0
{
599
0
    H5AC_proxy_entry_t *pentry    = (H5AC_proxy_entry_t *)_thing;
600
0
    herr_t              ret_value = SUCCEED; /* Return value */
601
602
0
    FUNC_ENTER_PACKAGE
603
604
    /* Destroy the proxy entry */
605
0
    if (H5AC_proxy_entry_dest(pentry) < 0)
606
0
        HGOTO_ERROR(H5E_CACHE, H5E_CANTFREE, FAIL, "unable to destroy proxy entry");
607
608
0
done:
609
0
    FUNC_LEAVE_NOAPI(ret_value)
610
0
} /* H5AC__proxy_entry_free_icr() */