iPXE
refcnt.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 #include <stdlib.h>
28 #include <ipxe/refcnt.h>
29 
30 /** @file
31  *
32  * Reference counting
33  *
34  */
35 
36 /**
37  * Increment reference count
38  *
39  * @v refcnt Reference counter, or NULL
40  *
41  * If @c refcnt is NULL, no action is taken.
42  */
43 void ref_increment ( struct refcnt *refcnt ) {
44 
45  if ( refcnt ) {
46  refcnt->count++;
47  DBGC2 ( refcnt, "REFCNT %p incremented to %d\n",
48  refcnt, refcnt->count );
49  }
50 }
51 
52 /**
53  * Decrement reference count
54  *
55  * @v refcnt Reference counter, or NULL
56  *
57  * If the reference count decreases below zero, the object's free()
58  * method will be called.
59  *
60  * If @c refcnt is NULL, no action is taken.
61  */
62 void ref_decrement ( struct refcnt *refcnt ) {
63 
64  if ( ! refcnt )
65  return;
66 
67  refcnt->count--;
68  DBGC2 ( refcnt, "REFCNT %p decremented to %d\n",
69  refcnt, refcnt->count );
70 
71  if ( refcnt->count >= 0 )
72  return;
73 
74  if ( refcnt->count < -1 ) {
75  DBGC ( refcnt, "REFCNT %p decremented too far (%d)!\n",
76  refcnt, refcnt->count );
77  /* Avoid multiple calls to free(), which typically
78  * result in memory corruption that is very hard to
79  * track down.
80  */
81  return;
82  }
83 
84  if ( refcnt->free ) {
85  DBGC ( refcnt, "REFCNT %p being freed via method %p\n",
86  refcnt, refcnt->free );
87  refcnt->free ( refcnt );
88  } else {
89  DBGC ( refcnt, "REFCNT %p being freed\n", refcnt );
90  free ( refcnt );
91  }
92 }
93 
94 /**
95  * Do not free reference-counted object
96  *
97  * @v refcnt Reference counter
98  *
99  * This is meant for initializing a reference counter structure in a
100  * statically allocated object.
101  */
102 void ref_no_free ( struct refcnt *refcnt __unused ) {
103  /* Do nothing */
104 }
#define DBGC(...)
Definition: compiler.h:505
FILE_SECBOOT(PERMITTED)
void ref_decrement(struct refcnt *refcnt)
Decrement reference count.
Definition: refcnt.c:62
A reference counter.
Definition: refcnt.h:27
int count
Current reference count.
Definition: refcnt.h:33
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
void ref_increment(struct refcnt *refcnt)
Increment reference count.
Definition: refcnt.c:43
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
#define DBGC2(...)
Definition: compiler.h:522
Reference counting.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
void ref_no_free(struct refcnt *refcnt __unused)
Do not free reference-counted object.
Definition: refcnt.c:102
void(* free)(struct refcnt *refcnt)
Free containing object.
Definition: refcnt.h:44