1 /* $NetBSD: counter.c,v 1.1.1.2 2014/12/10 03:34:43 christos Exp $ */
4 * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
25 #include <isc/counter.h>
26 #include <isc/magic.h>
30 #define COUNTER_MAGIC ISC_MAGIC('C', 'n', 't', 'r')
31 #define VALID_COUNTER(r) ISC_MAGIC_VALID(r, COUNTER_MAGIC)
37 unsigned int references
;
43 isc_counter_create(isc_mem_t
*mctx
, int limit
, isc_counter_t
**counterp
) {
45 isc_counter_t
*counter
;
47 REQUIRE(counterp
!= NULL
&& *counterp
== NULL
);
49 counter
= isc_mem_get(mctx
, sizeof(*counter
));
51 return (ISC_R_NOMEMORY
);
53 result
= isc_mutex_init(&counter
->lock
);
54 if (result
!= ISC_R_SUCCESS
) {
55 isc_mem_put(mctx
, counter
, sizeof(*counter
));
60 isc_mem_attach(mctx
, &counter
->mctx
);
62 counter
->references
= 1;
63 counter
->limit
= limit
;
66 counter
->magic
= COUNTER_MAGIC
;
68 return (ISC_R_SUCCESS
);
72 isc_counter_increment(isc_counter_t
*counter
) {
73 isc_result_t result
= ISC_R_SUCCESS
;
77 if (counter
->limit
!= 0 && counter
->used
>= counter
->limit
)
79 UNLOCK(&counter
->lock
);
85 isc_counter_used(isc_counter_t
*counter
) {
86 REQUIRE(VALID_COUNTER(counter
));
88 return (counter
->used
);
92 isc_counter_setlimit(isc_counter_t
*counter
, int limit
) {
93 REQUIRE(VALID_COUNTER(counter
));
96 counter
->limit
= limit
;
97 UNLOCK(&counter
->lock
);
101 isc_counter_attach(isc_counter_t
*source
, isc_counter_t
**targetp
) {
102 REQUIRE(VALID_COUNTER(source
));
103 REQUIRE(targetp
!= NULL
&& *targetp
== NULL
);
106 source
->references
++;
107 INSIST(source
->references
> 0);
108 UNLOCK(&source
->lock
);
114 destroy(isc_counter_t
*counter
) {
116 isc_mutex_destroy(&counter
->lock
);
117 isc_mem_putanddetach(&counter
->mctx
, counter
, sizeof(*counter
));
121 isc_counter_detach(isc_counter_t
**counterp
) {
122 isc_counter_t
*counter
;
123 isc_boolean_t want_destroy
= ISC_FALSE
;
125 REQUIRE(counterp
!= NULL
&& *counterp
!= NULL
);
127 REQUIRE(VALID_COUNTER(counter
));
131 LOCK(&counter
->lock
);
132 INSIST(counter
->references
> 0);
133 counter
->references
--;
134 if (counter
->references
== 0)
135 want_destroy
= ISC_TRUE
;
136 UNLOCK(&counter
->lock
);