1*1ae08745Sheppo /* 2*1ae08745Sheppo * CDDL HEADER START 3*1ae08745Sheppo * 4*1ae08745Sheppo * The contents of this file are subject to the terms of the 5*1ae08745Sheppo * Common Development and Distribution License (the "License"). 6*1ae08745Sheppo * You may not use this file except in compliance with the License. 7*1ae08745Sheppo * 8*1ae08745Sheppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*1ae08745Sheppo * or http://www.opensolaris.org/os/licensing. 10*1ae08745Sheppo * See the License for the specific language governing permissions 11*1ae08745Sheppo * and limitations under the License. 12*1ae08745Sheppo * 13*1ae08745Sheppo * When distributing Covered Code, include this CDDL HEADER in each 14*1ae08745Sheppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*1ae08745Sheppo * If applicable, add the following below this CDDL HEADER, with the 16*1ae08745Sheppo * fields enclosed by brackets "[]" replaced with your own identifying 17*1ae08745Sheppo * information: Portions Copyright [yyyy] [name of copyright owner] 18*1ae08745Sheppo * 19*1ae08745Sheppo * CDDL HEADER END 20*1ae08745Sheppo */ 21*1ae08745Sheppo /* 22*1ae08745Sheppo * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*1ae08745Sheppo * Use is subject to license terms. 24*1ae08745Sheppo */ 25*1ae08745Sheppo #pragma ident "%Z%%M% %I% %E% SMI" 26*1ae08745Sheppo 27*1ae08745Sheppo /* 28*1ae08745Sheppo * utility for vntsd queue handling 29*1ae08745Sheppo */ 30*1ae08745Sheppo #include <stdio.h> 31*1ae08745Sheppo #include <sys/types.h> 32*1ae08745Sheppo #include <sys/ipc.h> 33*1ae08745Sheppo #include <stdlib.h> 34*1ae08745Sheppo #include <string.h> 35*1ae08745Sheppo #include <unistd.h> 36*1ae08745Sheppo #include <sys/socket.h> 37*1ae08745Sheppo #include <sys/ipc.h> 38*1ae08745Sheppo #include <sys/shm.h> 39*1ae08745Sheppo #include <sys/sem.h> 40*1ae08745Sheppo #include <wait.h> 41*1ae08745Sheppo #include <time.h> 42*1ae08745Sheppo #include <netinet/in.h> 43*1ae08745Sheppo #include <thread.h> 44*1ae08745Sheppo #include <signal.h> 45*1ae08745Sheppo #include "vntsd.h" 46*1ae08745Sheppo 47*1ae08745Sheppo /* alloc_que_el() allocates a queue element */ 48*1ae08745Sheppo static vntsd_que_t * 49*1ae08745Sheppo alloc_que_el(void *handle) 50*1ae08745Sheppo { 51*1ae08745Sheppo vntsd_que_t *el; 52*1ae08745Sheppo 53*1ae08745Sheppo /* allocate a queue element */ 54*1ae08745Sheppo el = (vntsd_que_t *)malloc(sizeof (vntsd_que_t)); 55*1ae08745Sheppo if (el == NULL) { 56*1ae08745Sheppo return (NULL); 57*1ae08745Sheppo } 58*1ae08745Sheppo 59*1ae08745Sheppo 60*1ae08745Sheppo el->nextp = NULL; 61*1ae08745Sheppo el->prevp = NULL; 62*1ae08745Sheppo el->handle = handle; 63*1ae08745Sheppo 64*1ae08745Sheppo return (el); 65*1ae08745Sheppo } 66*1ae08745Sheppo 67*1ae08745Sheppo /* vntsd_que_append() appends a element to a queue */ 68*1ae08745Sheppo int 69*1ae08745Sheppo vntsd_que_append(vntsd_que_t **que_hd, void *handle) 70*1ae08745Sheppo { 71*1ae08745Sheppo vntsd_que_t *p; 72*1ae08745Sheppo vntsd_que_t *el; 73*1ae08745Sheppo 74*1ae08745Sheppo assert(que_hd); 75*1ae08745Sheppo assert(handle); 76*1ae08745Sheppo 77*1ae08745Sheppo /* allocate a queue element */ 78*1ae08745Sheppo el = alloc_que_el(handle); 79*1ae08745Sheppo 80*1ae08745Sheppo if (el == NULL) { 81*1ae08745Sheppo return (VNTSD_ERR_NO_MEM); 82*1ae08745Sheppo } 83*1ae08745Sheppo 84*1ae08745Sheppo p = *que_hd; 85*1ae08745Sheppo 86*1ae08745Sheppo if (p == NULL) { 87*1ae08745Sheppo /* first one */ 88*1ae08745Sheppo *que_hd = el; 89*1ae08745Sheppo } else { 90*1ae08745Sheppo /* walk to the last one */ 91*1ae08745Sheppo while (p->nextp != NULL) 92*1ae08745Sheppo p = p->nextp; 93*1ae08745Sheppo p->nextp = el; 94*1ae08745Sheppo } 95*1ae08745Sheppo 96*1ae08745Sheppo el->prevp = p; 97*1ae08745Sheppo 98*1ae08745Sheppo return (VNTSD_SUCCESS); 99*1ae08745Sheppo } 100*1ae08745Sheppo 101*1ae08745Sheppo /* vntsd_que_insert_after() inserts element arter the handle */ 102*1ae08745Sheppo int 103*1ae08745Sheppo vntsd_que_insert_after(vntsd_que_t *que, void *handle, void *next) 104*1ae08745Sheppo { 105*1ae08745Sheppo vntsd_que_t *q, *el; 106*1ae08745Sheppo 107*1ae08745Sheppo assert(que); 108*1ae08745Sheppo 109*1ae08745Sheppo q = que; 110*1ae08745Sheppo 111*1ae08745Sheppo while (q != NULL) { 112*1ae08745Sheppo if (q->handle == handle) { 113*1ae08745Sheppo break; 114*1ae08745Sheppo } 115*1ae08745Sheppo 116*1ae08745Sheppo q = q->nextp; 117*1ae08745Sheppo } 118*1ae08745Sheppo 119*1ae08745Sheppo if (q == NULL) { 120*1ae08745Sheppo /* not in queue */ 121*1ae08745Sheppo return (VNTSD_ERR_EL_NOT_FOUND); 122*1ae08745Sheppo } 123*1ae08745Sheppo 124*1ae08745Sheppo el = alloc_que_el(next); 125*1ae08745Sheppo 126*1ae08745Sheppo if (el == NULL) { 127*1ae08745Sheppo return (VNTSD_ERR_NO_MEM); 128*1ae08745Sheppo } 129*1ae08745Sheppo 130*1ae08745Sheppo el->nextp = q->nextp; 131*1ae08745Sheppo q->nextp = el; 132*1ae08745Sheppo el->prevp = q; 133*1ae08745Sheppo 134*1ae08745Sheppo return (VNTSD_SUCCESS); 135*1ae08745Sheppo } 136*1ae08745Sheppo 137*1ae08745Sheppo 138*1ae08745Sheppo 139*1ae08745Sheppo /* vntsd_que_rm() removes an element from a queue */ 140*1ae08745Sheppo int 141*1ae08745Sheppo vntsd_que_rm(vntsd_que_t **que_hd, void *handle) 142*1ae08745Sheppo { 143*1ae08745Sheppo vntsd_que_t *p = *que_hd; 144*1ae08745Sheppo vntsd_que_t *prevp = NULL; 145*1ae08745Sheppo 146*1ae08745Sheppo 147*1ae08745Sheppo while (p != NULL) { 148*1ae08745Sheppo /* match handle */ 149*1ae08745Sheppo if (p->handle == handle) { 150*1ae08745Sheppo break; 151*1ae08745Sheppo } 152*1ae08745Sheppo prevp = p; 153*1ae08745Sheppo p = p->nextp; 154*1ae08745Sheppo } 155*1ae08745Sheppo 156*1ae08745Sheppo if (p == NULL) { 157*1ae08745Sheppo /* not found */ 158*1ae08745Sheppo return (VNTSD_ERR_EL_NOT_FOUND); 159*1ae08745Sheppo } 160*1ae08745Sheppo 161*1ae08745Sheppo /* found */ 162*1ae08745Sheppo if (p == *que_hd) { 163*1ae08745Sheppo /* first one */ 164*1ae08745Sheppo *que_hd = p->nextp; 165*1ae08745Sheppo } else { 166*1ae08745Sheppo prevp->nextp = p->nextp; 167*1ae08745Sheppo } 168*1ae08745Sheppo 169*1ae08745Sheppo if (p->nextp != NULL) { 170*1ae08745Sheppo p->nextp->prevp = prevp; 171*1ae08745Sheppo } 172*1ae08745Sheppo 173*1ae08745Sheppo handle = p->handle; 174*1ae08745Sheppo 175*1ae08745Sheppo free(p); 176*1ae08745Sheppo 177*1ae08745Sheppo return (VNTSD_SUCCESS); 178*1ae08745Sheppo 179*1ae08745Sheppo } 180*1ae08745Sheppo 181*1ae08745Sheppo /* vntsd_que_walk() - walk queue and apply function to each element */ 182*1ae08745Sheppo void * 183*1ae08745Sheppo vntsd_que_walk(vntsd_que_t *que_hd, el_func_t el_func) 184*1ae08745Sheppo { 185*1ae08745Sheppo vntsd_que_t *p = que_hd; 186*1ae08745Sheppo 187*1ae08745Sheppo while (p != NULL) { 188*1ae08745Sheppo if ((*el_func)(p->handle)) { 189*1ae08745Sheppo return (p->handle); 190*1ae08745Sheppo } 191*1ae08745Sheppo 192*1ae08745Sheppo p = p->nextp; 193*1ae08745Sheppo } 194*1ae08745Sheppo return (VNTSD_SUCCESS); 195*1ae08745Sheppo } 196*1ae08745Sheppo 197*1ae08745Sheppo 198*1ae08745Sheppo /* vntsd_que_find() finds first match */ 199*1ae08745Sheppo void * 200*1ae08745Sheppo vntsd_que_find(vntsd_que_t *que_hd, compare_func_t compare_func, void *data) 201*1ae08745Sheppo { 202*1ae08745Sheppo vntsd_que_t *p = que_hd; 203*1ae08745Sheppo 204*1ae08745Sheppo assert(compare_func != NULL); 205*1ae08745Sheppo while (p != NULL) { 206*1ae08745Sheppo if ((*compare_func)(p->handle, data)) { 207*1ae08745Sheppo /* found match */ 208*1ae08745Sheppo return (p->handle); 209*1ae08745Sheppo } 210*1ae08745Sheppo 211*1ae08745Sheppo p = p->nextp; 212*1ae08745Sheppo } 213*1ae08745Sheppo 214*1ae08745Sheppo /* not found */ 215*1ae08745Sheppo return (NULL); 216*1ae08745Sheppo } 217*1ae08745Sheppo 218*1ae08745Sheppo /* vntsd_free_que() frees entire queue */ 219*1ae08745Sheppo void 220*1ae08745Sheppo vntsd_free_que(vntsd_que_t **q, clean_func_t clean_func) 221*1ae08745Sheppo { 222*1ae08745Sheppo vntsd_que_t *p; 223*1ae08745Sheppo 224*1ae08745Sheppo while (*q != NULL) { 225*1ae08745Sheppo p = *q; 226*1ae08745Sheppo 227*1ae08745Sheppo *q = p->nextp; 228*1ae08745Sheppo 229*1ae08745Sheppo if (clean_func) { 230*1ae08745Sheppo /* clean func will free the handle */ 231*1ae08745Sheppo (*clean_func)(p->handle); 232*1ae08745Sheppo } else { 233*1ae08745Sheppo free(p->handle); 234*1ae08745Sheppo } 235*1ae08745Sheppo 236*1ae08745Sheppo free(p); 237*1ae08745Sheppo } 238*1ae08745Sheppo } 239*1ae08745Sheppo 240*1ae08745Sheppo /* 241*1ae08745Sheppo * vntsd_que_pos() matches a handle and returns a handle located at "pos" 242*1ae08745Sheppo * relative to the matched handle. pos supported are 1 or -1. 243*1ae08745Sheppo */ 244*1ae08745Sheppo void * 245*1ae08745Sheppo vntsd_que_pos(vntsd_que_t *que_hd, void *handle, int pos) 246*1ae08745Sheppo { 247*1ae08745Sheppo vntsd_que_t *p = que_hd; 248*1ae08745Sheppo 249*1ae08745Sheppo assert((pos == 1) || (pos == -1)); 250*1ae08745Sheppo 251*1ae08745Sheppo 252*1ae08745Sheppo while (p != NULL) { 253*1ae08745Sheppo if (p->handle == handle) { 254*1ae08745Sheppo /* find match */ 255*1ae08745Sheppo if (pos == 1) { 256*1ae08745Sheppo /* forward 1 */ 257*1ae08745Sheppo if (p->nextp != NULL) { 258*1ae08745Sheppo return (p->nextp->handle); 259*1ae08745Sheppo } 260*1ae08745Sheppo 261*1ae08745Sheppo /* last one go to first */ 262*1ae08745Sheppo return (que_hd->handle); 263*1ae08745Sheppo 264*1ae08745Sheppo } else { 265*1ae08745Sheppo /* backward 1 */ 266*1ae08745Sheppo if (p->prevp != NULL) { 267*1ae08745Sheppo return (p->prevp->handle); 268*1ae08745Sheppo } 269*1ae08745Sheppo 270*1ae08745Sheppo /* first one, return last one */ 271*1ae08745Sheppo while (p->nextp != NULL) { 272*1ae08745Sheppo p = p->nextp; 273*1ae08745Sheppo } 274*1ae08745Sheppo 275*1ae08745Sheppo assert(p != NULL); 276*1ae08745Sheppo assert(p->handle != NULL); 277*1ae08745Sheppo return (p->handle); 278*1ae08745Sheppo 279*1ae08745Sheppo } 280*1ae08745Sheppo } 281*1ae08745Sheppo p = p->nextp; 282*1ae08745Sheppo } 283*1ae08745Sheppo 284*1ae08745Sheppo DERR(stderr, "t@%d vntsd_que_pos can not find handle \n", 285*1ae08745Sheppo thr_self()); 286*1ae08745Sheppo 287*1ae08745Sheppo return (NULL); 288*1ae08745Sheppo } 289