dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / nscd / nscd_intaddr.c
blobf427d0c98a9ea4e5cdb74cf5ebc3774ade23565e
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include "nscd_db.h"
31 #include "nscd_log.h"
33 static rwlock_t addrDB_rwlock = DEFAULTRWLOCK;
34 static nscd_db_t *addrDB = NULL;
37 * internal structure representing a nscd internal address
39 typedef struct nscd_int_addr {
40 int to_delete; /* no longer valid */
41 int type;
42 void *ptr;
43 nscd_seq_num_t seq_num;
44 rwlock_t rwlock; /* used to serialize get and destroy */
45 } nscd_int_addr_t;
48 * FUNCTION: _nscd_create_int_addrDB
50 * Create the internal address database to keep track of the
51 * memory allocated by _nscd_alloc.
53 void *
54 _nscd_create_int_addrDB()
57 nscd_db_t *ret;
58 char *me = "_nscd_create_int_addrDB";
60 _NSCD_LOG(NSCD_LOG_INT_ADDR | NSCD_LOG_CONFIG, NSCD_LOG_LEVEL_DEBUG)
61 (me, "initializing the internal address database\n");
63 (void) rw_wrlock(&addrDB_rwlock);
65 if (addrDB != NULL) {
66 (void) rw_unlock(&addrDB_rwlock);
67 return (addrDB);
70 ret = _nscd_alloc_db(NSCD_DB_SIZE_LARGE);
72 if (ret != NULL)
73 addrDB = ret;
75 (void) rw_unlock(&addrDB_rwlock);
77 return (ret);
81 * FUNCTION: _nscd_add_int_addr
83 * Add an address of 'type' to the internal address database.
85 nscd_rc_t
86 _nscd_add_int_addr(
87 void *ptr,
88 int type,
89 nscd_seq_num_t seq_num)
91 int size;
92 char buf[2 * sizeof (ptr) + 1];
93 nscd_db_entry_t *db_entry;
94 nscd_int_addr_t *int_addr;
96 if (ptr == NULL)
97 return (NSCD_INVALID_ARGUMENT);
99 (void) snprintf(buf, sizeof (buf), "%p", ptr);
101 size = sizeof (*int_addr);
103 db_entry = _nscd_alloc_db_entry(NSCD_DATA_ADDR,
104 (const char *)buf, size, 1, 1);
105 if (db_entry == NULL)
106 return (NSCD_NO_MEMORY);
108 int_addr = (nscd_int_addr_t *)*(db_entry->data_array);
109 int_addr->ptr = ptr;
110 int_addr->type = type;
111 int_addr->seq_num = seq_num;
112 (void) rwlock_init(&int_addr->rwlock, USYNC_THREAD, NULL);
114 (void) rw_wrlock(&addrDB_rwlock);
115 (void) _nscd_add_db_entry(addrDB, buf, db_entry,
116 NSCD_ADD_DB_ENTRY_FIRST);
117 (void) rw_unlock(&addrDB_rwlock);
119 return (NSCD_SUCCESS);
123 * FUNCTION: _nscd_is_int_addr
125 * Check to see if an address can be found in the internal
126 * address database, if so, obtain a reader lock on the
127 * associated rw_lock. The caller needs to unlock it when
128 * done using the data.
130 rwlock_t *
131 _nscd_is_int_addr(
132 void *ptr,
133 nscd_seq_num_t seq_num)
135 char *me = "_nscd_is_int_addr";
136 char ptrstr[1 + 2 * sizeof (ptr)];
137 rwlock_t *addr_rwlock;
138 const nscd_db_entry_t *db_entry;
140 if (ptr == NULL)
141 return (NULL);
143 (void) snprintf(ptrstr, sizeof (ptrstr), "%p", ptr);
145 (void) rw_rdlock(&addrDB_rwlock);
147 db_entry = _nscd_get_db_entry(addrDB, NSCD_DATA_ADDR,
148 (const char *)ptrstr, NSCD_GET_FIRST_DB_ENTRY, 0);
150 if (db_entry != NULL) {
151 nscd_int_addr_t *int_addr;
153 int_addr = (nscd_int_addr_t *)*(db_entry->data_array);
154 addr_rwlock = &int_addr->rwlock;
155 (void) rw_rdlock(addr_rwlock);
158 * If the data is marked as to be deleted
159 * or the sequence number does not match,
160 * return NULL.
162 if (int_addr->to_delete == 1 ||
163 int_addr->seq_num != seq_num) {
164 (void) rw_unlock(addr_rwlock);
165 addr_rwlock = NULL;
168 _NSCD_LOG(NSCD_LOG_INT_ADDR, NSCD_LOG_LEVEL_DEBUG)
169 (me, "found %p, seq# = %lld\n", ptr, int_addr->seq_num);
170 } else
171 addr_rwlock = NULL;
173 (void) rw_unlock(&addrDB_rwlock);
175 return (addr_rwlock);
179 * FUNCTION: _nscd_del_int_addr
181 * Delete an address from the internal address database.
183 void
184 _nscd_del_int_addr(
185 void *ptr,
186 nscd_seq_num_t seq_num)
188 char *me = "_nscd_del_int_addr";
189 char ptrstr[1 + 2 * sizeof (ptr)];
190 rwlock_t *addr_rwlock;
191 nscd_int_addr_t *int_addr;
192 const nscd_db_entry_t *db_entry;
194 if (ptr == NULL)
195 return;
197 _NSCD_LOG(NSCD_LOG_INT_ADDR, NSCD_LOG_LEVEL_DEBUG)
198 (me, "deleting int addr %p (%d)\n", ptr, seq_num);
199 (void) snprintf(ptrstr, sizeof (ptrstr), "%p", ptr);
201 (void) rw_rdlock(&addrDB_rwlock);
203 * first find the db entry and make sure that
204 * no one is currently locking it. i.e.,
205 * no one is waiting to use the same address.
206 * If it is locked, rw_wrlock() will not return
207 * until it is unlocked.
209 db_entry = _nscd_get_db_entry(addrDB,
210 NSCD_DATA_ADDR,
211 (const char *)ptrstr,
212 NSCD_GET_FIRST_DB_ENTRY, 0);
213 if (db_entry != NULL) {
214 int_addr = (nscd_int_addr_t *)*(db_entry->data_array);
215 addr_rwlock = &int_addr->rwlock;
216 (void) rw_wrlock(addr_rwlock);
217 } else {
218 (void) rw_unlock(&addrDB_rwlock);
219 return;
221 (void) rw_unlock(&addrDB_rwlock);
224 * delete the db entry if the sequence numbers match
226 if (int_addr->seq_num == seq_num) {
227 (void) rw_wrlock(&addrDB_rwlock);
228 (void) _nscd_delete_db_entry(addrDB,
229 NSCD_DATA_ADDR,
230 (const char *)ptrstr,
231 NSCD_DEL_FIRST_DB_ENTRY, 0);
232 (void) rw_unlock(&addrDB_rwlock);
237 * FUNCTION: _nscd_destroy_int_addrDB
239 * Destroy the internal address database.
241 void
242 _nscd_destroy_int_addrDB()
244 (void) rw_wrlock(&addrDB_rwlock);
245 _nscd_free_db(addrDB);
246 addrDB = NULL;
247 (void) rw_unlock(&addrDB_rwlock);