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