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