1*6ba597c5SAnurag S. Maskey /* 2*6ba597c5SAnurag S. Maskey * CDDL HEADER START 3*6ba597c5SAnurag S. Maskey * 4*6ba597c5SAnurag S. Maskey * The contents of this file are subject to the terms of the 5*6ba597c5SAnurag S. Maskey * Common Development and Distribution License (the "License"). 6*6ba597c5SAnurag S. Maskey * You may not use this file except in compliance with the License. 7*6ba597c5SAnurag S. Maskey * 8*6ba597c5SAnurag S. Maskey * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*6ba597c5SAnurag S. Maskey * or http://www.opensolaris.org/os/licensing. 10*6ba597c5SAnurag S. Maskey * See the License for the specific language governing permissions 11*6ba597c5SAnurag S. Maskey * and limitations under the License. 12*6ba597c5SAnurag S. Maskey * 13*6ba597c5SAnurag S. Maskey * When distributing Covered Code, include this CDDL HEADER in each 14*6ba597c5SAnurag S. Maskey * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*6ba597c5SAnurag S. Maskey * If applicable, add the following below this CDDL HEADER, with the 16*6ba597c5SAnurag S. Maskey * fields enclosed by brackets "[]" replaced with your own identifying 17*6ba597c5SAnurag S. Maskey * information: Portions Copyright [yyyy] [name of copyright owner] 18*6ba597c5SAnurag S. Maskey * 19*6ba597c5SAnurag S. Maskey * CDDL HEADER END 20*6ba597c5SAnurag S. Maskey */ 21*6ba597c5SAnurag S. Maskey 22*6ba597c5SAnurag S. Maskey /* 23*6ba597c5SAnurag S. Maskey * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24*6ba597c5SAnurag S. Maskey * Use is subject to license terms. 25*6ba597c5SAnurag S. Maskey */ 26*6ba597c5SAnurag S. Maskey 27*6ba597c5SAnurag S. Maskey #include <assert.h> 28*6ba597c5SAnurag S. Maskey #include <stdlib.h> 29*6ba597c5SAnurag S. Maskey #include <string.h> 30*6ba597c5SAnurag S. Maskey #include <pthread.h> 31*6ba597c5SAnurag S. Maskey #include <signal.h> 32*6ba597c5SAnurag S. Maskey #include <errno.h> 33*6ba597c5SAnurag S. Maskey #include <syslog.h> 34*6ba597c5SAnurag S. Maskey #include <libuutil.h> 35*6ba597c5SAnurag S. Maskey #include <errno.h> 36*6ba597c5SAnurag S. Maskey 37*6ba597c5SAnurag S. Maskey #include "events.h" 38*6ba597c5SAnurag S. Maskey #include "objects.h" 39*6ba597c5SAnurag S. Maskey #include "util.h" 40*6ba597c5SAnurag S. Maskey 41*6ba597c5SAnurag S. Maskey /* 42*6ba597c5SAnurag S. Maskey * objects.c - contains routines which manipulate object lists of NCUs, 43*6ba597c5SAnurag S. Maskey * locations, ENMs and known WLANs. 44*6ba597c5SAnurag S. Maskey */ 45*6ba597c5SAnurag S. Maskey 46*6ba597c5SAnurag S. Maskey typedef struct nwamd_object_list { 47*6ba597c5SAnurag S. Maskey nwam_object_type_t object_type; 48*6ba597c5SAnurag S. Maskey uu_list_t *object_list; 49*6ba597c5SAnurag S. Maskey nwamd_event_method_t *object_event_methods; 50*6ba597c5SAnurag S. Maskey pthread_rwlock_t object_list_lock; 51*6ba597c5SAnurag S. Maskey } nwamd_object_list_t; 52*6ba597c5SAnurag S. Maskey 53*6ba597c5SAnurag S. Maskey nwamd_event_method_t enm_event_methods[] = 54*6ba597c5SAnurag S. Maskey { 55*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_INIT, nwamd_enm_handle_init_event }, 56*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_FINI, nwamd_enm_handle_fini_event }, 57*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_ACTION, nwamd_enm_handle_action_event }, 58*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_STATE, nwamd_enm_handle_state_event }, 59*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_NOOP, NULL } 60*6ba597c5SAnurag S. Maskey }; 61*6ba597c5SAnurag S. Maskey 62*6ba597c5SAnurag S. Maskey nwamd_event_method_t loc_event_methods[] = 63*6ba597c5SAnurag S. Maskey { 64*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_INIT, nwamd_loc_handle_init_event }, 65*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_FINI, nwamd_loc_handle_fini_event }, 66*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_ACTION, nwamd_loc_handle_action_event }, 67*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_STATE, nwamd_loc_handle_state_event }, 68*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_NOOP, NULL } 69*6ba597c5SAnurag S. Maskey }; 70*6ba597c5SAnurag S. Maskey 71*6ba597c5SAnurag S. Maskey nwamd_event_method_t ncu_event_methods[] = 72*6ba597c5SAnurag S. Maskey { 73*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_IF_STATE, nwamd_ncu_handle_if_state_event }, 74*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_IF_ACTION, nwamd_ncu_handle_if_action_event }, 75*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_LINK_STATE, nwamd_ncu_handle_link_state_event }, 76*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_LINK_ACTION, nwamd_ncu_handle_link_action_event }, 77*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_INIT, nwamd_ncu_handle_init_event }, 78*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_FINI, nwamd_ncu_handle_fini_event }, 79*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_ACTION, nwamd_ncu_handle_action_event }, 80*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_STATE, nwamd_ncu_handle_state_event }, 81*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_PERIODIC_SCAN, nwamd_ncu_handle_periodic_scan_event }, 82*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_NOOP, NULL } 83*6ba597c5SAnurag S. Maskey }; 84*6ba597c5SAnurag S. Maskey 85*6ba597c5SAnurag S. Maskey nwamd_event_method_t ncp_event_methods[] = 86*6ba597c5SAnurag S. Maskey { 87*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_ACTION, nwamd_ncp_handle_action_event }, 88*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_STATE, nwamd_ncp_handle_state_event }, 89*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_UPGRADE, nwamd_handle_upgrade }, 90*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_NOOP, NULL } 91*6ba597c5SAnurag S. Maskey }; 92*6ba597c5SAnurag S. Maskey 93*6ba597c5SAnurag S. Maskey nwamd_event_method_t known_wlan_event_methods[] = 94*6ba597c5SAnurag S. Maskey { 95*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_INIT, nwamd_known_wlan_handle_init_event }, 96*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_FINI, NULL }, 97*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_OBJECT_ACTION, nwamd_known_wlan_handle_action_event }, 98*6ba597c5SAnurag S. Maskey { NWAM_EVENT_TYPE_NOOP, NULL } 99*6ba597c5SAnurag S. Maskey }; 100*6ba597c5SAnurag S. Maskey 101*6ba597c5SAnurag S. Maskey /* Should be kept in same order as object types */ 102*6ba597c5SAnurag S. Maskey nwamd_object_list_t object_lists[] = { 103*6ba597c5SAnurag S. Maskey { NWAM_OBJECT_TYPE_NCP, NULL, ncp_event_methods, 104*6ba597c5SAnurag S. Maskey PTHREAD_RWLOCK_INITIALIZER }, 105*6ba597c5SAnurag S. Maskey { NWAM_OBJECT_TYPE_NCU, NULL, ncu_event_methods, 106*6ba597c5SAnurag S. Maskey PTHREAD_RWLOCK_INITIALIZER }, 107*6ba597c5SAnurag S. Maskey { NWAM_OBJECT_TYPE_LOC, NULL, loc_event_methods, 108*6ba597c5SAnurag S. Maskey PTHREAD_RWLOCK_INITIALIZER }, 109*6ba597c5SAnurag S. Maskey { NWAM_OBJECT_TYPE_ENM, NULL, enm_event_methods, 110*6ba597c5SAnurag S. Maskey PTHREAD_RWLOCK_INITIALIZER }, 111*6ba597c5SAnurag S. Maskey { NWAM_OBJECT_TYPE_KNOWN_WLAN, NULL, known_wlan_event_methods, 112*6ba597c5SAnurag S. Maskey PTHREAD_RWLOCK_INITIALIZER } 113*6ba597c5SAnurag S. Maskey }; 114*6ba597c5SAnurag S. Maskey 115*6ba597c5SAnurag S. Maskey uu_list_pool_t *object_list_pool = NULL; 116*6ba597c5SAnurag S. Maskey 117*6ba597c5SAnurag S. Maskey /* 118*6ba597c5SAnurag S. Maskey * Comparison function for objects, passed in as callback to 119*6ba597c5SAnurag S. Maskey * uu_list_pool_create(). 120*6ba597c5SAnurag S. Maskey */ 121*6ba597c5SAnurag S. Maskey /* ARGSUSED */ 122*6ba597c5SAnurag S. Maskey static int 123*6ba597c5SAnurag S. Maskey nwamd_object_compare(const void *l_arg, const void *r_arg, void *private) 124*6ba597c5SAnurag S. Maskey { 125*6ba597c5SAnurag S. Maskey nwamd_object_t l = (nwamd_object_t)l_arg; 126*6ba597c5SAnurag S. Maskey nwamd_object_t r = (nwamd_object_t)r_arg; 127*6ba597c5SAnurag S. Maskey int rv; 128*6ba597c5SAnurag S. Maskey 129*6ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&l->nwamd_object_mutex); 130*6ba597c5SAnurag S. Maskey if (l != r) 131*6ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&r->nwamd_object_mutex); 132*6ba597c5SAnurag S. Maskey 133*6ba597c5SAnurag S. Maskey rv = strcmp(l->nwamd_object_name, r->nwamd_object_name); 134*6ba597c5SAnurag S. Maskey if (l != r) 135*6ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&r->nwamd_object_mutex); 136*6ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&l->nwamd_object_mutex); 137*6ba597c5SAnurag S. Maskey 138*6ba597c5SAnurag S. Maskey return (rv); 139*6ba597c5SAnurag S. Maskey } 140*6ba597c5SAnurag S. Maskey 141*6ba597c5SAnurag S. Maskey void 142*6ba597c5SAnurag S. Maskey nwamd_object_lists_init(void) 143*6ba597c5SAnurag S. Maskey { 144*6ba597c5SAnurag S. Maskey int i; 145*6ba597c5SAnurag S. Maskey 146*6ba597c5SAnurag S. Maskey object_list_pool = uu_list_pool_create("object_list_pool", 147*6ba597c5SAnurag S. Maskey sizeof (struct nwamd_object), 148*6ba597c5SAnurag S. Maskey offsetof(struct nwamd_object, nwamd_object_node), 149*6ba597c5SAnurag S. Maskey nwamd_object_compare, UU_LIST_POOL_DEBUG); 150*6ba597c5SAnurag S. Maskey if (object_list_pool == NULL) 151*6ba597c5SAnurag S. Maskey pfail("uu_list_pool_create failed with error %d", uu_error()); 152*6ba597c5SAnurag S. Maskey 153*6ba597c5SAnurag S. Maskey for (i = 0; 154*6ba597c5SAnurag S. Maskey i < sizeof (object_lists) / sizeof (struct nwamd_object_list); 155*6ba597c5SAnurag S. Maskey i++) { 156*6ba597c5SAnurag S. Maskey object_lists[i].object_list = uu_list_create(object_list_pool, 157*6ba597c5SAnurag S. Maskey NULL, 0); 158*6ba597c5SAnurag S. Maskey if (object_lists[i].object_list == NULL) 159*6ba597c5SAnurag S. Maskey pfail("uu_list_create failed with error %d", 160*6ba597c5SAnurag S. Maskey uu_error()); 161*6ba597c5SAnurag S. Maskey } 162*6ba597c5SAnurag S. Maskey } 163*6ba597c5SAnurag S. Maskey 164*6ba597c5SAnurag S. Maskey void 165*6ba597c5SAnurag S. Maskey nwamd_object_lists_fini(void) 166*6ba597c5SAnurag S. Maskey { 167*6ba597c5SAnurag S. Maskey int i; 168*6ba597c5SAnurag S. Maskey nwamd_object_t object; 169*6ba597c5SAnurag S. Maskey void *cookie = NULL; 170*6ba597c5SAnurag S. Maskey 171*6ba597c5SAnurag S. Maskey for (i = 0; 172*6ba597c5SAnurag S. Maskey i < sizeof (object_lists) / sizeof (struct nwamd_object_list); 173*6ba597c5SAnurag S. Maskey i++) { 174*6ba597c5SAnurag S. Maskey while ((object = uu_list_teardown(object_lists[i].object_list, 175*6ba597c5SAnurag S. Maskey &cookie)) != NULL) { 176*6ba597c5SAnurag S. Maskey free(object); 177*6ba597c5SAnurag S. Maskey } 178*6ba597c5SAnurag S. Maskey uu_list_destroy(object_lists[i].object_list); 179*6ba597c5SAnurag S. Maskey } 180*6ba597c5SAnurag S. Maskey if (object_list_pool != NULL) 181*6ba597c5SAnurag S. Maskey uu_list_pool_destroy(object_list_pool); 182*6ba597c5SAnurag S. Maskey } 183*6ba597c5SAnurag S. Maskey 184*6ba597c5SAnurag S. Maskey static nwamd_object_list_t * 185*6ba597c5SAnurag S. Maskey nwamd_get_object_list(nwam_object_type_t type) 186*6ba597c5SAnurag S. Maskey { 187*6ba597c5SAnurag S. Maskey assert(type < sizeof (object_lists) / sizeof (object_lists[0])); 188*6ba597c5SAnurag S. Maskey return (&object_lists[type]); 189*6ba597c5SAnurag S. Maskey } 190*6ba597c5SAnurag S. Maskey 191*6ba597c5SAnurag S. Maskey static int 192*6ba597c5SAnurag S. Maskey nwamd_object_list_lock(nwam_object_type_t type) 193*6ba597c5SAnurag S. Maskey { 194*6ba597c5SAnurag S. Maskey nwamd_object_list_t *object_list = nwamd_get_object_list(type); 195*6ba597c5SAnurag S. Maskey 196*6ba597c5SAnurag S. Maskey (void) pthread_rwlock_wrlock(&object_list->object_list_lock); 197*6ba597c5SAnurag S. Maskey return (0); 198*6ba597c5SAnurag S. Maskey } 199*6ba597c5SAnurag S. Maskey 200*6ba597c5SAnurag S. Maskey static int 201*6ba597c5SAnurag S. Maskey nwamd_object_list_rlock(nwam_object_type_t type) 202*6ba597c5SAnurag S. Maskey { 203*6ba597c5SAnurag S. Maskey nwamd_object_list_t *object_list = nwamd_get_object_list(type); 204*6ba597c5SAnurag S. Maskey 205*6ba597c5SAnurag S. Maskey if (pthread_rwlock_rdlock(&object_list->object_list_lock) == -1) { 206*6ba597c5SAnurag S. Maskey nlog(LOG_ERR, "cannot get lock for object list: %s", 207*6ba597c5SAnurag S. Maskey strerror(errno)); 208*6ba597c5SAnurag S. Maskey return (-1); 209*6ba597c5SAnurag S. Maskey } 210*6ba597c5SAnurag S. Maskey return (0); 211*6ba597c5SAnurag S. Maskey } 212*6ba597c5SAnurag S. Maskey 213*6ba597c5SAnurag S. Maskey static void 214*6ba597c5SAnurag S. Maskey nwamd_object_list_unlock(nwam_object_type_t type) 215*6ba597c5SAnurag S. Maskey { 216*6ba597c5SAnurag S. Maskey nwamd_object_list_t *object_list = nwamd_get_object_list(type); 217*6ba597c5SAnurag S. Maskey 218*6ba597c5SAnurag S. Maskey (void) pthread_rwlock_unlock(&object_list->object_list_lock); 219*6ba597c5SAnurag S. Maskey } 220*6ba597c5SAnurag S. Maskey 221*6ba597c5SAnurag S. Maskey /* 222*6ba597c5SAnurag S. Maskey * Initialize object and return it in locked state. 223*6ba597c5SAnurag S. Maskey */ 224*6ba597c5SAnurag S. Maskey nwamd_object_t 225*6ba597c5SAnurag S. Maskey nwamd_object_init(nwam_object_type_t type, const char *name, void *handle, 226*6ba597c5SAnurag S. Maskey void *data) 227*6ba597c5SAnurag S. Maskey { 228*6ba597c5SAnurag S. Maskey nwamd_object_t object; 229*6ba597c5SAnurag S. Maskey struct nwamd_object_list *object_list = nwamd_get_object_list(type); 230*6ba597c5SAnurag S. Maskey 231*6ba597c5SAnurag S. Maskey object = calloc(1, sizeof (struct nwamd_object)); 232*6ba597c5SAnurag S. Maskey if (object == NULL) 233*6ba597c5SAnurag S. Maskey return (NULL); 234*6ba597c5SAnurag S. Maskey 235*6ba597c5SAnurag S. Maskey (void) strlcpy(object->nwamd_object_name, name, NWAM_MAX_NAME_LEN); 236*6ba597c5SAnurag S. Maskey 237*6ba597c5SAnurag S. Maskey /* 1 for the list and 1 for the returned object */ 238*6ba597c5SAnurag S. Maskey object->nwamd_object_refcount = 2; 239*6ba597c5SAnurag S. Maskey object->nwamd_object_handle = handle; 240*6ba597c5SAnurag S. Maskey object->nwamd_object_data = data; 241*6ba597c5SAnurag S. Maskey object->nwamd_object_type = type; 242*6ba597c5SAnurag S. Maskey object->nwamd_object_state = NWAM_STATE_INITIALIZED; 243*6ba597c5SAnurag S. Maskey object->nwamd_object_aux_state = NWAM_AUX_STATE_INITIALIZED; 244*6ba597c5SAnurag S. Maskey 245*6ba597c5SAnurag S. Maskey /* Add object to appropriate object list */ 246*6ba597c5SAnurag S. Maskey if (nwamd_object_list_lock(type) != 0) { 247*6ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_object_init: could not lock list to init " 248*6ba597c5SAnurag S. Maskey "object %s", name); 249*6ba597c5SAnurag S. Maskey free(object); 250*6ba597c5SAnurag S. Maskey return (NULL); 251*6ba597c5SAnurag S. Maskey } 252*6ba597c5SAnurag S. Maskey 253*6ba597c5SAnurag S. Maskey if (pthread_mutex_init(&object->nwamd_object_mutex, NULL) == -1) { 254*6ba597c5SAnurag S. Maskey nlog(LOG_ERR, "pthread_mutex_init failed: %s", 255*6ba597c5SAnurag S. Maskey strerror(errno)); 256*6ba597c5SAnurag S. Maskey free(object); 257*6ba597c5SAnurag S. Maskey nwamd_object_list_unlock(type); 258*6ba597c5SAnurag S. Maskey return (NULL); 259*6ba597c5SAnurag S. Maskey } 260*6ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&object->nwamd_object_mutex); 261*6ba597c5SAnurag S. Maskey 262*6ba597c5SAnurag S. Maskey uu_list_node_init(object, &object->nwamd_object_node, object_list_pool); 263*6ba597c5SAnurag S. Maskey (void) uu_list_insert_after(object_list->object_list, 264*6ba597c5SAnurag S. Maskey uu_list_last(object_list->object_list), object); 265*6ba597c5SAnurag S. Maskey 266*6ba597c5SAnurag S. Maskey nwamd_object_list_unlock(type); 267*6ba597c5SAnurag S. Maskey 268*6ba597c5SAnurag S. Maskey return (object); 269*6ba597c5SAnurag S. Maskey } 270*6ba597c5SAnurag S. Maskey 271*6ba597c5SAnurag S. Maskey /* 272*6ba597c5SAnurag S. Maskey * Find object in object list, returning it holding a lock and with the 273*6ba597c5SAnurag S. Maskey * reference count incremented. The opposite function to this is 274*6ba597c5SAnurag S. Maskey * nwamd_object_release(). 275*6ba597c5SAnurag S. Maskey */ 276*6ba597c5SAnurag S. Maskey nwamd_object_t 277*6ba597c5SAnurag S. Maskey nwamd_object_find(nwam_object_type_t type, const char *name) 278*6ba597c5SAnurag S. Maskey { 279*6ba597c5SAnurag S. Maskey nwamd_object_t object; 280*6ba597c5SAnurag S. Maskey struct nwamd_object_list *object_list = nwamd_get_object_list(type); 281*6ba597c5SAnurag S. Maskey 282*6ba597c5SAnurag S. Maskey assert(name != NULL); 283*6ba597c5SAnurag S. Maskey 284*6ba597c5SAnurag S. Maskey if (nwamd_object_list_rlock(type) != 0) 285*6ba597c5SAnurag S. Maskey return (NULL); 286*6ba597c5SAnurag S. Maskey 287*6ba597c5SAnurag S. Maskey for (object = uu_list_first(object_list->object_list); 288*6ba597c5SAnurag S. Maskey object != NULL; 289*6ba597c5SAnurag S. Maskey object = uu_list_next(object_list->object_list, object)) { 290*6ba597c5SAnurag S. Maskey if (strcmp(object->nwamd_object_name, name) == 0) 291*6ba597c5SAnurag S. Maskey break; 292*6ba597c5SAnurag S. Maskey } 293*6ba597c5SAnurag S. Maskey if (object != NULL) { 294*6ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&object->nwamd_object_mutex); 295*6ba597c5SAnurag S. Maskey object->nwamd_object_refcount++; 296*6ba597c5SAnurag S. Maskey } 297*6ba597c5SAnurag S. Maskey nwamd_object_list_unlock(type); 298*6ba597c5SAnurag S. Maskey 299*6ba597c5SAnurag S. Maskey return (object); 300*6ba597c5SAnurag S. Maskey } 301*6ba597c5SAnurag S. Maskey 302*6ba597c5SAnurag S. Maskey /* Removes object from list, destroy mutex, and free storage. */ 303*6ba597c5SAnurag S. Maskey static void 304*6ba597c5SAnurag S. Maskey nwamd_object_fini(nwamd_object_t object, nwam_object_type_t objtype) 305*6ba597c5SAnurag S. Maskey { 306*6ba597c5SAnurag S. Maskey nwamd_object_t o; 307*6ba597c5SAnurag S. Maskey struct nwamd_object_list *object_list; 308*6ba597c5SAnurag S. Maskey 309*6ba597c5SAnurag S. Maskey assert(object != NULL); 310*6ba597c5SAnurag S. Maskey 311*6ba597c5SAnurag S. Maskey object_list = nwamd_get_object_list(objtype); 312*6ba597c5SAnurag S. Maskey 313*6ba597c5SAnurag S. Maskey for (o = uu_list_first(object_list->object_list); 314*6ba597c5SAnurag S. Maskey o != NULL; 315*6ba597c5SAnurag S. Maskey o = uu_list_next(object_list->object_list, o)) { 316*6ba597c5SAnurag S. Maskey if (o == object) { 317*6ba597c5SAnurag S. Maskey uu_list_remove(object_list->object_list, object); 318*6ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock( 319*6ba597c5SAnurag S. Maskey &object->nwamd_object_mutex); 320*6ba597c5SAnurag S. Maskey (void) pthread_mutex_destroy( 321*6ba597c5SAnurag S. Maskey &object->nwamd_object_mutex); 322*6ba597c5SAnurag S. Maskey uu_list_node_fini(object, &object->nwamd_object_node, 323*6ba597c5SAnurag S. Maskey object_list_pool); 324*6ba597c5SAnurag S. Maskey switch (objtype) { 325*6ba597c5SAnurag S. Maskey case NWAM_OBJECT_TYPE_NCU: 326*6ba597c5SAnurag S. Maskey nwamd_ncu_free(object->nwamd_object_data); 327*6ba597c5SAnurag S. Maskey nwam_ncu_free(object->nwamd_object_handle); 328*6ba597c5SAnurag S. Maskey break; 329*6ba597c5SAnurag S. Maskey case NWAM_OBJECT_TYPE_LOC: 330*6ba597c5SAnurag S. Maskey nwam_loc_free(object->nwamd_object_handle); 331*6ba597c5SAnurag S. Maskey break; 332*6ba597c5SAnurag S. Maskey case NWAM_OBJECT_TYPE_ENM: 333*6ba597c5SAnurag S. Maskey nwam_enm_free(object->nwamd_object_handle); 334*6ba597c5SAnurag S. Maskey break; 335*6ba597c5SAnurag S. Maskey default: 336*6ba597c5SAnurag S. Maskey nlog(LOG_ERR, "nwamd_object_fini: " 337*6ba597c5SAnurag S. Maskey "got unexpected object type %d", objtype); 338*6ba597c5SAnurag S. Maskey break; 339*6ba597c5SAnurag S. Maskey } 340*6ba597c5SAnurag S. Maskey free(object); 341*6ba597c5SAnurag S. Maskey break; 342*6ba597c5SAnurag S. Maskey } 343*6ba597c5SAnurag S. Maskey } 344*6ba597c5SAnurag S. Maskey } 345*6ba597c5SAnurag S. Maskey 346*6ba597c5SAnurag S. Maskey static void 347*6ba597c5SAnurag S. Maskey nwamd_object_decref(nwamd_object_t object, int num) 348*6ba597c5SAnurag S. Maskey { 349*6ba597c5SAnurag S. Maskey nwam_object_type_t objtype; 350*6ba597c5SAnurag S. Maskey 351*6ba597c5SAnurag S. Maskey assert(object->nwamd_object_refcount >= num); 352*6ba597c5SAnurag S. Maskey object->nwamd_object_refcount -= num; 353*6ba597c5SAnurag S. Maskey if (object->nwamd_object_refcount == 0) { 354*6ba597c5SAnurag S. Maskey /* 355*6ba597c5SAnurag S. Maskey * We need to maintain the locking hierarchy of owning the 356*6ba597c5SAnurag S. Maskey * list lock before we get the object lock when we are 357*6ba597c5SAnurag S. Maskey * destroying the object. If we merely release and then 358*6ba597c5SAnurag S. Maskey * reacquire in the right order we might not find the right 359*6ba597c5SAnurag S. Maskey * object. Instead we bump the ref count so that it can't 360*6ba597c5SAnurag S. Maskey * be destroyed, we drop the object lock, we acquire the 361*6ba597c5SAnurag S. Maskey * list lock, we acquire the object lock, decrement the ref 362*6ba597c5SAnurag S. Maskey * count, check to make sure we are really destroying it and 363*6ba597c5SAnurag S. Maskey * somebody else hasn't gotten it, and then, if its unref'd, 364*6ba597c5SAnurag S. Maskey * destroying it. 365*6ba597c5SAnurag S. Maskey */ 366*6ba597c5SAnurag S. Maskey object->nwamd_object_refcount++; 367*6ba597c5SAnurag S. Maskey objtype = object->nwamd_object_type; 368*6ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&object->nwamd_object_mutex); 369*6ba597c5SAnurag S. Maskey (void) nwamd_object_list_lock(objtype); 370*6ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&object->nwamd_object_mutex); 371*6ba597c5SAnurag S. Maskey if (--object->nwamd_object_refcount != 0) 372*6ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock( 373*6ba597c5SAnurag S. Maskey &object->nwamd_object_mutex); 374*6ba597c5SAnurag S. Maskey else 375*6ba597c5SAnurag S. Maskey nwamd_object_fini(object, objtype); 376*6ba597c5SAnurag S. Maskey nwamd_object_list_unlock(objtype); 377*6ba597c5SAnurag S. Maskey } else { 378*6ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&object->nwamd_object_mutex); 379*6ba597c5SAnurag S. Maskey } 380*6ba597c5SAnurag S. Maskey } 381*6ba597c5SAnurag S. Maskey 382*6ba597c5SAnurag S. Maskey /* 383*6ba597c5SAnurag S. Maskey * Drop mutex without decreasing reference count. Used where we wish to 384*6ba597c5SAnurag S. Maskey * let go of an object but ensure it will not go away. 385*6ba597c5SAnurag S. Maskey */ 386*6ba597c5SAnurag S. Maskey void 387*6ba597c5SAnurag S. Maskey nwamd_object_release_and_preserve(nwamd_object_t object) 388*6ba597c5SAnurag S. Maskey { 389*6ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&object->nwamd_object_mutex); 390*6ba597c5SAnurag S. Maskey } 391*6ba597c5SAnurag S. Maskey 392*6ba597c5SAnurag S. Maskey void 393*6ba597c5SAnurag S. Maskey nwamd_object_release(nwamd_object_t object) 394*6ba597c5SAnurag S. Maskey { 395*6ba597c5SAnurag S. Maskey nwamd_object_decref(object, 1); 396*6ba597c5SAnurag S. Maskey } 397*6ba597c5SAnurag S. Maskey 398*6ba597c5SAnurag S. Maskey void 399*6ba597c5SAnurag S. Maskey nwamd_object_release_and_destroy(nwamd_object_t object) 400*6ba597c5SAnurag S. Maskey { 401*6ba597c5SAnurag S. Maskey nwamd_object_decref(object, 2); 402*6ba597c5SAnurag S. Maskey } 403*6ba597c5SAnurag S. Maskey 404*6ba597c5SAnurag S. Maskey void 405*6ba597c5SAnurag S. Maskey nwamd_object_release_and_destroy_after_preserve(nwamd_object_t object) 406*6ba597c5SAnurag S. Maskey { 407*6ba597c5SAnurag S. Maskey nwamd_object_decref(object, 3); 408*6ba597c5SAnurag S. Maskey } 409*6ba597c5SAnurag S. Maskey 410*6ba597c5SAnurag S. Maskey void 411*6ba597c5SAnurag S. Maskey nwamd_object_release_after_preserve(nwamd_object_t object) 412*6ba597c5SAnurag S. Maskey { 413*6ba597c5SAnurag S. Maskey nwamd_object_decref(object, 2); 414*6ba597c5SAnurag S. Maskey } 415*6ba597c5SAnurag S. Maskey 416*6ba597c5SAnurag S. Maskey void 417*6ba597c5SAnurag S. Maskey nwamd_object_set_state_timed(nwam_object_type_t type, const char *name, 418*6ba597c5SAnurag S. Maskey nwam_state_t state, nwam_aux_state_t aux_state, uint32_t when) 419*6ba597c5SAnurag S. Maskey { 420*6ba597c5SAnurag S. Maskey nwamd_event_t event = nwamd_event_init_object_state(type, name, 421*6ba597c5SAnurag S. Maskey state, aux_state); 422*6ba597c5SAnurag S. Maskey 423*6ba597c5SAnurag S. Maskey nlog(LOG_INFO, "nwamd_object_set_state: state event (%s, %s) for %s", 424*6ba597c5SAnurag S. Maskey nwam_state_to_string(state), 425*6ba597c5SAnurag S. Maskey nwam_aux_state_to_string(aux_state), name); 426*6ba597c5SAnurag S. Maskey if (event != NULL) 427*6ba597c5SAnurag S. Maskey nwamd_event_enqueue_timed(event, when); 428*6ba597c5SAnurag S. Maskey } 429*6ba597c5SAnurag S. Maskey 430*6ba597c5SAnurag S. Maskey void 431*6ba597c5SAnurag S. Maskey nwamd_object_set_state(nwam_object_type_t type, const char *name, 432*6ba597c5SAnurag S. Maskey nwam_state_t state, nwam_aux_state_t aux_state) 433*6ba597c5SAnurag S. Maskey { 434*6ba597c5SAnurag S. Maskey nwamd_object_set_state_timed(type, name, state, aux_state, 0); 435*6ba597c5SAnurag S. Maskey } 436*6ba597c5SAnurag S. Maskey 437*6ba597c5SAnurag S. Maskey nwamd_event_method_t * 438*6ba597c5SAnurag S. Maskey nwamd_object_event_methods(nwam_object_type_t type) 439*6ba597c5SAnurag S. Maskey { 440*6ba597c5SAnurag S. Maskey struct nwamd_object_list *object_list = nwamd_get_object_list(type); 441*6ba597c5SAnurag S. Maskey 442*6ba597c5SAnurag S. Maskey return (object_list->object_event_methods); 443*6ba597c5SAnurag S. Maskey } 444*6ba597c5SAnurag S. Maskey 445*6ba597c5SAnurag S. Maskey /* 446*6ba597c5SAnurag S. Maskey * Walk all objects of specified type calling callback function cb. 447*6ba597c5SAnurag S. Maskey * Object is locked for duration of callback. 448*6ba597c5SAnurag S. Maskey */ 449*6ba597c5SAnurag S. Maskey int 450*6ba597c5SAnurag S. Maskey nwamd_walk_objects(nwam_object_type_t type, int (*cb)(nwamd_object_t, void *), 451*6ba597c5SAnurag S. Maskey void *data) 452*6ba597c5SAnurag S. Maskey { 453*6ba597c5SAnurag S. Maskey nwamd_object_t object; 454*6ba597c5SAnurag S. Maskey struct nwamd_object_list *object_list = nwamd_get_object_list(type); 455*6ba597c5SAnurag S. Maskey int ret = 0; 456*6ba597c5SAnurag S. Maskey 457*6ba597c5SAnurag S. Maskey if (nwamd_object_list_rlock(type) != 0) 458*6ba597c5SAnurag S. Maskey return (-1); 459*6ba597c5SAnurag S. Maskey 460*6ba597c5SAnurag S. Maskey for (object = uu_list_first(object_list->object_list); 461*6ba597c5SAnurag S. Maskey object != NULL; 462*6ba597c5SAnurag S. Maskey object = uu_list_next(object_list->object_list, object)) { 463*6ba597c5SAnurag S. Maskey (void) pthread_mutex_lock(&object->nwamd_object_mutex); 464*6ba597c5SAnurag S. Maskey ret = cb(object, data); 465*6ba597c5SAnurag S. Maskey (void) pthread_mutex_unlock(&object->nwamd_object_mutex); 466*6ba597c5SAnurag S. Maskey if (ret != 0) { 467*6ba597c5SAnurag S. Maskey nwamd_object_list_unlock(type); 468*6ba597c5SAnurag S. Maskey return (ret); 469*6ba597c5SAnurag S. Maskey } 470*6ba597c5SAnurag S. Maskey } 471*6ba597c5SAnurag S. Maskey nwamd_object_list_unlock(type); 472*6ba597c5SAnurag S. Maskey 473*6ba597c5SAnurag S. Maskey return (0); 474*6ba597c5SAnurag S. Maskey } 475