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, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 #ifdef HAVE_NBTOOL_CONFIG_H
24 #include "nbtool_config.h"
25 #endif
26
27 /*
28 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
30 */
31
32 #pragma ident "%Z%%M% %I% %E% SMI"
33
34 /*
35 * Routines for manipulating a FIFO queue
36 */
37
38 #include <stdlib.h>
39
40 #include "fifo.h"
41 #include "memory.h"
42
43 typedef struct fifonode {
44 void *fn_data;
45 struct fifonode *fn_next;
46 } fifonode_t;
47
48 struct fifo {
49 fifonode_t *f_head;
50 fifonode_t *f_tail;
51 };
52
53 fifo_t *
fifo_new(void)54 fifo_new(void)
55 {
56 fifo_t *f;
57
58 f = xcalloc(sizeof (fifo_t));
59
60 return (f);
61 }
62
63 /* Add to the end of the fifo */
64 void
fifo_add(fifo_t * f,void * data)65 fifo_add(fifo_t *f, void *data)
66 {
67 fifonode_t *fn = xmalloc(sizeof (fifonode_t));
68
69 fn->fn_data = data;
70 fn->fn_next = NULL;
71
72 if (f->f_tail == NULL)
73 f->f_head = f->f_tail = fn;
74 else {
75 f->f_tail->fn_next = fn;
76 f->f_tail = fn;
77 }
78 }
79
80 /* Remove from the front of the fifo */
81 void *
fifo_remove(fifo_t * f)82 fifo_remove(fifo_t *f)
83 {
84 fifonode_t *fn;
85 void *data;
86
87 if ((fn = f->f_head) == NULL)
88 return (NULL);
89
90 data = fn->fn_data;
91 if ((f->f_head = fn->fn_next) == NULL)
92 f->f_tail = NULL;
93
94 free(fn);
95
96 return (data);
97 }
98
99 /*ARGSUSED*/
100 static void
fifo_nullfree(void * arg)101 fifo_nullfree(void *arg)
102 {
103 /* this function intentionally left blank */
104 }
105
106 /* Free an entire fifo */
107 void
fifo_free(fifo_t * f,void (* freefn)(void *))108 fifo_free(fifo_t *f, void (*freefn)(void *))
109 {
110 fifonode_t *fn = f->f_head;
111 fifonode_t *tmp;
112
113 if (freefn == NULL)
114 freefn = fifo_nullfree;
115
116 while (fn) {
117 (*freefn)(fn->fn_data);
118
119 tmp = fn;
120 fn = fn->fn_next;
121 free(tmp);
122 }
123
124 free(f);
125 }
126
127 int
fifo_len(fifo_t * f)128 fifo_len(fifo_t *f)
129 {
130 fifonode_t *fn;
131 int i;
132
133 for (i = 0, fn = f->f_head; fn; fn = fn->fn_next, i++);
134
135 return (i);
136 }
137
138 int
fifo_empty(fifo_t * f)139 fifo_empty(fifo_t *f)
140 {
141 return (f->f_head == NULL);
142 }
143
144 int
fifo_iter(fifo_t * f,int (* iter)(void * data,void * arg),void * arg)145 fifo_iter(fifo_t *f, int (*iter)(void *data, void *arg), void *arg)
146 {
147 fifonode_t *fn;
148 int rc;
149 int ret = 0;
150
151 for (fn = f->f_head; fn; fn = fn->fn_next) {
152 if ((rc = iter(fn->fn_data, arg)) < 0)
153 return (-1);
154 ret += rc;
155 }
156
157 return (ret);
158 }
159