2 * Copyright (c) 2002-2006 MontaVista Software, Inc.
3 * Copyright (c) 2006 Red Hat, Inc.
4 * Copyright (c) 2006 Sun Microsystems, Inc.
8 * Author: Steven Dake (sdake@mvista.com)
10 * This software licensed under BSD license, the text of which follows:
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
15 * - Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * - Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 * - Neither the name of the MontaVista Software, Inc. nor the names of its
21 * contributors may be used to endorse or promote products derived from this
22 * software without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34 * THE POSSIBILITY OF SUCH DAMAGE.
45 enum HDB_HANDLE_STATE
{
46 HDB_HANDLE_STATE_EMPTY
,
47 HDB_HANDLE_STATE_PENDINGREMOVAL
,
48 HDB_HANDLE_STATE_ACTIVE
57 struct hdb_handle_database
{
58 unsigned int handle_count
;
59 struct hdb_handle
*handles
;
60 unsigned int iterator
;
61 pthread_mutex_t mutex
;
64 static inline void hdb_create (
65 struct hdb_handle_database
*handle_database
)
67 memset (handle_database
, 0, sizeof (struct hdb_handle_database
));
68 pthread_mutex_init (&handle_database
->mutex
, NULL
);
71 static inline void hdb_destroy (
72 struct hdb_handle_database
*handle_database
)
74 if (handle_database
->handles
) {
75 free (handle_database
->handles
);
77 pthread_mutex_destroy (&handle_database
->mutex
);
78 memset (handle_database
, 0, sizeof (struct hdb_handle_database
));
82 static inline int hdb_handle_create (
83 struct hdb_handle_database
*handle_database
,
85 unsigned int *handle_id_out
)
92 pthread_mutex_lock (&handle_database
->mutex
);
94 for (handle
= 0; handle
< handle_database
->handle_count
; handle
++) {
95 if (handle_database
->handles
[handle
].state
== HDB_HANDLE_STATE_EMPTY
) {
102 handle_database
->handle_count
+= 1;
103 new_handles
= (struct hdb_handle
*)realloc (handle_database
->handles
,
104 sizeof (struct hdb_handle
) * handle_database
->handle_count
);
105 if (new_handles
== NULL
) {
106 pthread_mutex_unlock (&handle_database
->mutex
);
109 handle_database
->handles
= new_handles
;
112 instance
= (void *)malloc (instance_size
);
116 memset (instance
, 0, instance_size
);
118 handle_database
->handles
[handle
].state
= HDB_HANDLE_STATE_ACTIVE
;
120 handle_database
->handles
[handle
].instance
= instance
;
122 handle_database
->handles
[handle
].ref_count
= 1;
124 *handle_id_out
= handle
;
126 pthread_mutex_unlock (&handle_database
->mutex
);
131 static inline int hdb_handle_get (
132 struct hdb_handle_database
*handle_database
,
136 pthread_mutex_lock (&handle_database
->mutex
);
139 if (handle
>= handle_database
->handle_count
) {
140 pthread_mutex_unlock (&handle_database
->mutex
);
144 if (handle_database
->handles
[handle
].state
!= HDB_HANDLE_STATE_ACTIVE
) {
145 pthread_mutex_unlock (&handle_database
->mutex
);
149 *instance
= handle_database
->handles
[handle
].instance
;
151 handle_database
->handles
[handle
].ref_count
+= 1;
153 pthread_mutex_unlock (&handle_database
->mutex
);
157 static inline void hdb_handle_put (
158 struct hdb_handle_database
*handle_database
,
161 pthread_mutex_lock (&handle_database
->mutex
);
162 handle_database
->handles
[handle
].ref_count
-= 1;
163 assert (handle_database
->handles
[handle
].ref_count
>= 0);
165 if (handle_database
->handles
[handle
].ref_count
== 0) {
166 free (handle_database
->handles
[handle
].instance
);
167 memset (&handle_database
->handles
[handle
], 0, sizeof (struct hdb_handle
));
169 pthread_mutex_unlock (&handle_database
->mutex
);
172 static inline void hdb_handle_destroy (
173 struct hdb_handle_database
*handle_database
,
176 pthread_mutex_lock (&handle_database
->mutex
);
178 handle_database
->handles
[handle
].state
= HDB_HANDLE_STATE_PENDINGREMOVAL
;
179 pthread_mutex_unlock (&handle_database
->mutex
);
180 hdb_handle_put (handle_database
, handle
);
183 static inline void hdb_iterator_reset (
184 struct hdb_handle_database
*handle_database
)
186 handle_database
->iterator
= 0;
189 static inline int hdb_iterator_next (
190 struct hdb_handle_database
*handle_database
,
192 unsigned int *handle
)
196 while (handle_database
->iterator
< handle_database
->handle_count
) {
197 *handle
= handle_database
->iterator
;
198 res
= hdb_handle_get (
200 handle_database
->iterator
,
203 handle_database
->iterator
+= 1;
211 #endif /* HDB_H_DEFINED */