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