Coverage Report

Created: 2026-10-28 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/isc/counter.c
Line
Count
Source
1
/*
2
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3
 *
4
 * SPDX-License-Identifier: MPL-2.0
5
 *
6
 * This Source Code Form is subject to the terms of the Mozilla Public
7
 * License, v. 2.0. If a copy of the MPL was not distributed with this
8
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9
 *
10
 * See the COPYRIGHT file distributed with this work for additional
11
 * information regarding copyright ownership.
12
 */
13
14
/*! \file */
15
16
#include <stdbool.h>
17
#include <stddef.h>
18
19
#include <isc/atomic.h>
20
#include <isc/counter.h>
21
#include <isc/magic.h>
22
#include <isc/mem.h>
23
#include <isc/refcount.h>
24
#include <isc/util.h>
25
26
0
#define COUNTER_MAGIC  ISC_MAGIC('C', 'n', 't', 'r')
27
#define VALID_COUNTER(r) ISC_MAGIC_VALID(r, COUNTER_MAGIC)
28
29
struct isc_counter {
30
  unsigned int magic;
31
  isc_mem_t *mctx;
32
  isc_refcount_t references;
33
  size_t limit;
34
  atomic_size_t used;
35
};
36
37
void
38
0
isc_counter_create(isc_mem_t *mctx, size_t limit, isc_counter_t **counterp) {
39
0
  REQUIRE(counterp != NULL && *counterp == NULL);
40
41
0
  isc_counter_t *counter = isc_mem_get(mctx, sizeof(*counter));
42
0
  *counter = (isc_counter_t){
43
0
    .magic = COUNTER_MAGIC,
44
0
    .references = 1,
45
0
    .limit = limit,
46
0
  };
47
48
0
  isc_mem_attach(mctx, &counter->mctx);
49
50
0
  *counterp = counter;
51
0
}
52
53
isc_result_t
54
0
isc_counter_increment(isc_counter_t *counter) {
55
0
  size_t used = atomic_fetch_add_relaxed(&counter->used, 1) + 1;
56
57
0
  if (counter->limit != 0 && used >= counter->limit) {
58
0
    return ISC_R_QUOTA;
59
0
  }
60
61
0
  return ISC_R_SUCCESS;
62
0
}
63
64
size_t
65
0
isc_counter_used(isc_counter_t *counter) {
66
0
  REQUIRE(VALID_COUNTER(counter));
67
68
0
  return atomic_load_relaxed(&counter->used);
69
0
}
70
71
size_t
72
0
isc_counter_getlimit(isc_counter_t *counter) {
73
0
  REQUIRE(VALID_COUNTER(counter));
74
75
0
  return counter->limit;
76
0
}
77
78
static void
79
0
isc__counter_destroy(isc_counter_t *counter) {
80
0
  REQUIRE(VALID_COUNTER(counter));
81
82
0
  isc_refcount_destroy(&counter->references);
83
0
  counter->magic = 0;
84
0
  isc_mem_putanddetach(&counter->mctx, counter, sizeof(*counter));
85
0
}
86
87
ISC_REFCOUNT_IMPL(isc_counter, isc__counter_destroy);
Unexecuted instantiation: isc_counter_ref
Unexecuted instantiation: isc_counter_unref
Unexecuted instantiation: isc_counter_detach