Allow libconfdb to run standalone (without aisexec)
[openais.git] / include / hdb.h
blob2359dd9af305371969717811dc225bdf7aab0a78
1 /*
2 * Copyright (c) 2002-2006 MontaVista Software, Inc.
3 * Copyright (c) 2006 Red Hat, Inc.
4 * Copyright (c) 2006 Sun Microsystems, Inc.
6 * All rights reserved.
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.
37 #ifndef HDB_H_DEFINED
38 #define HDB_H_DEFINED
40 #include <stdlib.h>
41 #include <string.h>
42 #include <assert.h>
43 #include <pthread.h>
45 enum HDB_HANDLE_STATE {
46 HDB_HANDLE_STATE_EMPTY,
47 HDB_HANDLE_STATE_PENDINGREMOVAL,
48 HDB_HANDLE_STATE_ACTIVE
51 struct hdb_handle {
52 int state;
53 void *instance;
54 int ref_count;
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,
84 int instance_size,
85 unsigned int *handle_id_out)
87 int handle;
88 void *new_handles;
89 int found = 0;
90 void *instance;
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) {
96 found = 1;
97 break;
101 if (found == 0) {
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);
107 return (-1);
109 handle_database->handles = new_handles;
112 instance = (void *)malloc (instance_size);
113 if (instance == 0) {
114 return (-1);
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);
128 return (0);
131 static inline int hdb_handle_get (
132 struct hdb_handle_database *handle_database,
133 unsigned int handle,
134 void **instance)
136 pthread_mutex_lock (&handle_database->mutex);
138 *instance = NULL;
139 if (handle >= handle_database->handle_count) {
140 pthread_mutex_unlock (&handle_database->mutex);
141 return (-1);
144 if (handle_database->handles[handle].state != HDB_HANDLE_STATE_ACTIVE) {
145 pthread_mutex_unlock (&handle_database->mutex);
146 return (-1);
149 *instance = handle_database->handles[handle].instance;
151 handle_database->handles[handle].ref_count += 1;
153 pthread_mutex_unlock (&handle_database->mutex);
154 return (0);
157 static inline void hdb_handle_put (
158 struct hdb_handle_database *handle_database,
159 unsigned int handle)
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,
174 unsigned int handle)
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,
191 void **instance,
192 unsigned int *handle)
194 int res = -1;
196 while (handle_database->iterator < handle_database->handle_count) {
197 *handle = handle_database->iterator;
198 res = hdb_handle_get (
199 handle_database,
200 handle_database->iterator,
201 instance);
203 handle_database->iterator += 1;
204 if (res == 0) {
205 break;
208 return (res);
211 #endif /* HDB_H_DEFINED */