diff options
Diffstat (limited to 'usr/src/cmd/vntsd/queue.c')
| -rw-r--r-- | usr/src/cmd/vntsd/queue.c | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/usr/src/cmd/vntsd/queue.c b/usr/src/cmd/vntsd/queue.c new file mode 100644 index 0000000000..4d50428198 --- /dev/null +++ b/usr/src/cmd/vntsd/queue.c @@ -0,0 +1,288 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * utility for vntsd queue handling + */ +#include <stdio.h> +#include <sys/types.h> +#include <sys/ipc.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/socket.h> +#include <sys/ipc.h> +#include <sys/shm.h> +#include <sys/sem.h> +#include <wait.h> +#include <time.h> +#include <netinet/in.h> +#include <thread.h> +#include <signal.h> +#include "vntsd.h" + +/* alloc_que_el() allocates a queue element */ +static vntsd_que_t * +alloc_que_el(void *handle) +{ + vntsd_que_t *el; + + /* allocate a queue element */ + el = (vntsd_que_t *)malloc(sizeof (vntsd_que_t)); + if (el == NULL) { + return (NULL); + } + + + el->nextp = NULL; + el->prevp = NULL; + el->handle = handle; + + return (el); +} + +/* vntsd_que_append() appends a element to a queue */ +int +vntsd_que_append(vntsd_que_t **que_hd, void *handle) +{ + vntsd_que_t *p; + vntsd_que_t *el; + + assert(que_hd); + assert(handle); + + /* allocate a queue element */ + el = alloc_que_el(handle); + + if (el == NULL) { + return (VNTSD_ERR_NO_MEM); + } + + p = *que_hd; + + if (p == NULL) { + /* first one */ + *que_hd = el; + } else { + /* walk to the last one */ + while (p->nextp != NULL) + p = p->nextp; + p->nextp = el; + } + + el->prevp = p; + + return (VNTSD_SUCCESS); +} + +/* vntsd_que_insert_after() inserts element arter the handle */ +int +vntsd_que_insert_after(vntsd_que_t *que, void *handle, void *next) +{ + vntsd_que_t *q, *el; + + assert(que); + + q = que; + + while (q != NULL) { + if (q->handle == handle) { + break; + } + + q = q->nextp; + } + + if (q == NULL) { + /* not in queue */ + return (VNTSD_ERR_EL_NOT_FOUND); + } + + el = alloc_que_el(next); + + if (el == NULL) { + return (VNTSD_ERR_NO_MEM); + } + + el->nextp = q->nextp; + q->nextp = el; + el->prevp = q; + + return (VNTSD_SUCCESS); +} + + + +/* vntsd_que_rm() removes an element from a queue */ +int +vntsd_que_rm(vntsd_que_t **que_hd, void *handle) +{ + vntsd_que_t *p = *que_hd; + vntsd_que_t *prevp = NULL; + + + while (p != NULL) { + /* match handle */ + if (p->handle == handle) { + break; + } + prevp = p; + p = p->nextp; + } + + if (p == NULL) { + /* not found */ + return (VNTSD_ERR_EL_NOT_FOUND); + } + + /* found */ + if (p == *que_hd) { + /* first one */ + *que_hd = p->nextp; + } else { + prevp->nextp = p->nextp; + } + + if (p->nextp != NULL) { + p->nextp->prevp = prevp; + } + + handle = p->handle; + + free(p); + + return (VNTSD_SUCCESS); + +} + +/* vntsd_que_walk() - walk queue and apply function to each element */ +void * +vntsd_que_walk(vntsd_que_t *que_hd, el_func_t el_func) +{ + vntsd_que_t *p = que_hd; + + while (p != NULL) { + if ((*el_func)(p->handle)) { + return (p->handle); + } + + p = p->nextp; + } + return (VNTSD_SUCCESS); +} + + +/* vntsd_que_find() finds first match */ +void * +vntsd_que_find(vntsd_que_t *que_hd, compare_func_t compare_func, void *data) +{ + vntsd_que_t *p = que_hd; + + assert(compare_func != NULL); + while (p != NULL) { + if ((*compare_func)(p->handle, data)) { + /* found match */ + return (p->handle); + } + + p = p->nextp; + } + + /* not found */ + return (NULL); +} + +/* vntsd_free_que() frees entire queue */ +void +vntsd_free_que(vntsd_que_t **q, clean_func_t clean_func) +{ + vntsd_que_t *p; + + while (*q != NULL) { + p = *q; + + *q = p->nextp; + + if (clean_func) { + /* clean func will free the handle */ + (*clean_func)(p->handle); + } else { + free(p->handle); + } + + free(p); + } +} + +/* + * vntsd_que_pos() matches a handle and returns a handle located at "pos" + * relative to the matched handle. pos supported are 1 or -1. + */ +void * +vntsd_que_pos(vntsd_que_t *que_hd, void *handle, int pos) +{ + vntsd_que_t *p = que_hd; + + assert((pos == 1) || (pos == -1)); + + + while (p != NULL) { + if (p->handle == handle) { + /* find match */ + if (pos == 1) { + /* forward 1 */ + if (p->nextp != NULL) { + return (p->nextp->handle); + } + + /* last one go to first */ + return (que_hd->handle); + + } else { + /* backward 1 */ + if (p->prevp != NULL) { + return (p->prevp->handle); + } + + /* first one, return last one */ + while (p->nextp != NULL) { + p = p->nextp; + } + + assert(p != NULL); + assert(p->handle != NULL); + return (p->handle); + + } + } + p = p->nextp; + } + + DERR(stderr, "t@%d vntsd_que_pos can not find handle \n", + thr_self()); + + return (NULL); +} |
