cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * CDDL HEADER START
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * The contents of this file are subject to the terms of the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Common Development and Distribution License (the "License").
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * You may not use this file except in compliance with the License.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * or http://www.opensolaris.org/os/licensing.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * See the License for the specific language governing permissions
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * and limitations under the License.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * When distributing Covered Code, include this CDDL HEADER in each
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * If applicable, add the following below this CDDL HEADER, with the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * fields enclosed by brackets "[]" replaced with your own identifying
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * information: Portions Copyright [yyyy] [name of copyright owner]
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * CDDL HEADER END
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Use is subject to license terms.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#pragma ident "%Z%%M% %I% %E% SMI"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <assert.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <stdlib.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include <string.h>
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_db.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#include "nscd_log.h"
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Access control structure for a piece of nscd data. This structure
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * is always tagged before the nscd data. nscd_alloc, which should
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * be used to allocate memory that requires access control or usage
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * count control, will initialize this access control structure at the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * start of the memory returned to the caller.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstruct nscd_access_s {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *data; /* addr of real data */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void (*free_func)(nscd_acc_data_t *data); /* destructor */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl mutex_t mutex; /* protect this structure */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl mutex_t *data_mutex;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rwlock_t *data_rwlock;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cond_t *data_cond;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int nUse; /* usage count */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int type;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int delete; /* no longer available */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_seq_num_t seq_num; /* sequence number */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl};
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/* size should be in multiple of 8 */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic int sizeof_access = roundup(sizeof (nscd_access_t));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define ABORT_DUE_TO_NO_VALID_NSCD_ACCESS_DATA 0
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define ASSERT_ACCESS_DATA \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (access->data != data) \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(ABORT_DUE_TO_NO_VALID_NSCD_ACCESS_DATA)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define SET_ACCESS_PTR \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access = (nscd_access_t *) \
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ((void *)((char *)data - sizeof_access))
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void _nscd_free(nscd_acc_data_t *data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_release
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Decrements the usage count maintained in the access data
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * tagged before 'data'. Delete the nscd data item if the delete
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * flag is set and the usage count reaches 0.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_release(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_release";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (data == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "data = %p, access->data = %p, "
cb5caa98562cf06753163f558cbcfe30b8f4673adjl "seq = %lld, nUse = %d\n",
cb5caa98562cf06753163f558cbcfe30b8f4673adjl data, access->data, access->seq_num, access->nUse);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&access->mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->nUse--;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (access->nUse < 0) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl#define ACCESS_NUSE_LESS_THAN_ZERO 0
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(ACCESS_NUSE_LESS_THAN_ZERO);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (access->nUse <= 0 &&
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->delete == 1) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "deleting data %p\n", access->data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (access->free_func)(access->data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if we get here, no other thread could be
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * holding the access->mutex lock, It is safe
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * to free the memory containing the mutex
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * structure. No mutex_unlock is necessary.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_free(data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&access->mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_destroy
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Marks the nscd data item as to-be-deleted and then releases
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * (If the usage count happens to be zero, then _nscd_release()
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * will destroy the data.)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Note that _nscd_destroy should only be called if the
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * caller has created the nscd data with _nscd_alloc
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * (with the exception of _nscd_set). That nscd data
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * item should be private to the caller.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_destroy(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_destroy";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (data == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "data = %p, access->data = %p\n", data, access->data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&access->mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->delete = 1;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&access->mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_release(data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_get
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Increment the usage count by one if 'data' can
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * be found in the internal address database.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_acc_data_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_get(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *ret = data;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rwlock_t *addr_rwlock;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_get";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (data == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "data = %p, access->data = %p, seq#= %lld, nUse = %d\n",
cb5caa98562cf06753163f558cbcfe30b8f4673adjl data, access->data, access->seq_num, access->nUse);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * see if this addr is still valid,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * if so, _nscd_is_int_addr will
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * do a read lock on the returned
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * multiple readers/single writer lock
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * to prevent the access data from being
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * deleted while it is being accessed.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((addr_rwlock = _nscd_is_int_addr(data,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->seq_num)) == NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "internal address %p not found\n", data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(addr_rwlock != NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(&access->mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (access->delete == 1)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ret = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->nUse++;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(&access->mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * done with the multiple readers/single writer lock
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(addr_rwlock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (ret);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_set
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * _nscd_set sets the address of a nscd data item
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * to 'new' and delete the old nscd data (old).
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * The pointer 'new' is returned.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_acc_data_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_set(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *old,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *new)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *old_data, *new_data;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_set";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (new == old)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (old);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "new = %p, old = %p\n", new, old);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl old_data = _nscd_get(old);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl new_data = _nscd_get(new);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (old_data != new_data) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_destroy(old_data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_release(new_data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (new_data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* if old_data == new_data, both must be NULL */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_rdlock
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Lock (rw_rdlock) a nscd data item for reading. The caller
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * needs to call _nscd_rw_unlock() to unlock the data item
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * when done using the data.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_acc_data_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_rdlock(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *ret;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_rdlock";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ret = _nscd_get(data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ret == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "data = %p, access->data = %p\n", data, access->data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(access->data_rwlock != NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_rdlock(access->data_rwlock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (ret);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_wrlock
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Lock (rw_wrlock) a nscd data item for writing. The caller
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * needs to call _nscd_rw_unlock() to unlock the data item
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * when done using the data.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_acc_data_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_wrlock(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *ret;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_wrlock";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ret = _nscd_get(data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ret == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "data = %p, access->data = %p\n", data, access->data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(access->data_rwlock != NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_wrlock(access->data_rwlock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (ret);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_rw_unlock
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Unlock (rw_unlock) a locked nscd data item.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_rw_unlock(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_rw_unlock";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (data == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "data = %p, access->data = %p\n",
cb5caa98562cf06753163f558cbcfe30b8f4673adjl data, access->data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(access->data_rwlock != NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(access->data_rwlock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_release(data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_rw_unlock_no_release
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Unlock (rw_unlock) a locked nscd data item but without release
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * it, i.e., without decrement the usage count to indicate that
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * the data item is still being referenced.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_rw_unlock_no_release(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (data == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(access->data_rwlock != NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rw_unlock(access->data_rwlock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_mutex_lock
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Lock (mutex_lock) a nscd data item. The caller needs
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * to call _nscd_mutex_unlock() to unlock the data item
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * when done using the data.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_acc_data_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_mutex_lock(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void *ret;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_mutex_lock";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ret = _nscd_get(data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (ret == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "data = %p, access->data = %p\n", data, access->data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(access->data_mutex != NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_lock(access->data_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (ret);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_mutex_unlock
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Unlock a locked nscd data item (that were locked by _nscd_mutex_lock)..
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_mutex_unlock(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_mutex_unlock";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (data == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "data = %p, access->data = %p\n", data, access->data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(access->data_mutex != NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_unlock(access->data_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_release(data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_cond_wait
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Perform a condition wait with the cond_t and mutex_t associated
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * with data.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_cond_wait(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data, cond_t *cond)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_cond_wait";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (data == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "data = %p, access->data = %p\n", data, access->data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(access->data_cond != NULL && access->data_mutex != NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (cond == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) cond_wait(access->data_cond, access->data_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) cond_wait(cond, access->data_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_cond_signal
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Perform a condition signal with the cond_t associated with 'data'.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlvoid
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_cond_signal(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl char *me = "_nscd_cond_signal";
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (data == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _NSCD_LOG(NSCD_LOG_ACCESS_INFO, NSCD_LOG_LEVEL_DEBUG)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (me, "data = %p, access->data = %p\n", data, access->data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl assert(access->data_cond != NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) cond_signal(access->data_cond);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_alloc
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Allocate a piece of nscd memory. 'data_free'
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * is the function to invoke to free the data
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * stored in this memory, i.e., the desctrctor.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * 'option' indicate whether a mutex or a
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * readers/writer (or both, or none) should also
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * be allocated.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlnscd_acc_data_t *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_alloc(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int type,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl size_t size,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl void (*data_free)(nscd_acc_data_t *data),
cb5caa98562cf06753163f558cbcfe30b8f4673adjl int option)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *ptr;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_seq_num_t seq_num;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl rwlock_t *rwlock = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl mutex_t *mutex = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl cond_t *cond = NULL;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((ptr = (nscd_acc_data_t *)calloc(1,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl size + sizeof_access)) == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (option & NSCD_ALLOC_MUTEX) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((mutex = (mutex_t *)calloc(1, sizeof (mutex_t))) ==
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(ptr);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) mutex_init(mutex, USYNC_THREAD, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (option & NSCD_ALLOC_RWLOCK) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((rwlock = (rwlock_t *)calloc(1, sizeof (rwlock_t))) ==
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(ptr);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) rwlock_init(rwlock, USYNC_THREAD, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (option & NSCD_ALLOC_COND) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if ((cond = (cond_t *)calloc(1, sizeof (cond_t))) ==
cb5caa98562cf06753163f558cbcfe30b8f4673adjl NULL) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(ptr);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(rwlock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl } else
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) cond_init(cond, USYNC_THREAD, NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* get current sequence number */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl seq_num = _nscd_get_seq_num();
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access = (nscd_access_t *)ptr;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->data = (char *)ptr + sizeof_access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->data_mutex = mutex;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->data_rwlock = rwlock;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->data_cond = cond;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->nUse = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->delete = 0;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->type = type;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->free_func = data_free;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl access->seq_num = seq_num;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* add the address to the internal address database */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (_nscd_add_int_addr(access->data, type,
cb5caa98562cf06753163f558cbcfe30b8f4673adjl seq_num) != NSCD_SUCCESS) {
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(ptr);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (NULL);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl }
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return (access->data);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl/*
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * FUNCTION: _nscd_free
cb5caa98562cf06753163f558cbcfe30b8f4673adjl *
cb5caa98562cf06753163f558cbcfe30b8f4673adjl * Free a piece of nscd memory.
cb5caa98562cf06753163f558cbcfe30b8f4673adjl */
cb5caa98562cf06753163f558cbcfe30b8f4673adjlstatic void
cb5caa98562cf06753163f558cbcfe30b8f4673adjl_nscd_free(
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_acc_data_t *data)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl{
cb5caa98562cf06753163f558cbcfe30b8f4673adjl nscd_access_t *access;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (data == NULL)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl return;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl SET_ACCESS_PTR;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl ASSERT_ACCESS_DATA;
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl /* remove the address from the internal address database */
cb5caa98562cf06753163f558cbcfe30b8f4673adjl _nscd_del_int_addr(access->data, access->seq_num);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (access->data_mutex)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(access->data_mutex);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (access->data_rwlock)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(access->data_rwlock);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl if (access->data_cond)
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(access->data_cond);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl (void) memset(access, 0, sizeof (*access));
cb5caa98562cf06753163f558cbcfe30b8f4673adjl
cb5caa98562cf06753163f558cbcfe30b8f4673adjl free(access);
cb5caa98562cf06753163f558cbcfe30b8f4673adjl}