1178481Sjb/*
2178481Sjb * CDDL HEADER START
3178481Sjb *
4178481Sjb * The contents of this file are subject to the terms of the
5178481Sjb * Common Development and Distribution License, Version 1.0 only
6178481Sjb * (the "License").  You may not use this file except in compliance
7178481Sjb * with the License.
8178481Sjb *
9178481Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10178481Sjb * or http://www.opensolaris.org/os/licensing.
11178481Sjb * See the License for the specific language governing permissions
12178481Sjb * and limitations under the License.
13178481Sjb *
14178481Sjb * When distributing Covered Code, include this CDDL HEADER in each
15178481Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16178481Sjb * If applicable, add the following below this CDDL HEADER, with the
17178481Sjb * fields enclosed by brackets "[]" replaced with your own identifying
18178481Sjb * information: Portions Copyright [yyyy] [name of copyright owner]
19178481Sjb *
20178481Sjb * CDDL HEADER END
21178481Sjb */
22178481Sjb/*
23178481Sjb * Copyright 2002 Sun Microsystems, Inc.  All rights reserved.
24178481Sjb * Use is subject to license terms.
25178481Sjb */
26178481Sjb
27178481Sjb#pragma ident	"%Z%%M%	%I%	%E% SMI"
28178481Sjb
29178481Sjb/*
30178481Sjb * Routines for manipulating a FIFO queue
31178481Sjb */
32178481Sjb
33178481Sjb#include <stdlib.h>
34178481Sjb
35178481Sjb#include "fifo.h"
36178481Sjb#include "memory.h"
37178481Sjb
38178481Sjbtypedef struct fifonode {
39178481Sjb	void *fn_data;
40178481Sjb	struct fifonode *fn_next;
41178481Sjb} fifonode_t;
42178481Sjb
43178481Sjbstruct fifo {
44178481Sjb	fifonode_t *f_head;
45178481Sjb	fifonode_t *f_tail;
46178481Sjb};
47178481Sjb
48178481Sjbfifo_t *
49178481Sjbfifo_new(void)
50178481Sjb{
51178481Sjb	fifo_t *f;
52178481Sjb
53178481Sjb	f = xcalloc(sizeof (fifo_t));
54178481Sjb
55178481Sjb	return (f);
56178481Sjb}
57178481Sjb
58178481Sjb/* Add to the end of the fifo */
59178481Sjbvoid
60178481Sjbfifo_add(fifo_t *f, void *data)
61178481Sjb{
62178481Sjb	fifonode_t *fn = xmalloc(sizeof (fifonode_t));
63178481Sjb
64178481Sjb	fn->fn_data = data;
65178481Sjb	fn->fn_next = NULL;
66178481Sjb
67178481Sjb	if (f->f_tail == NULL)
68178481Sjb		f->f_head = f->f_tail = fn;
69178481Sjb	else {
70178481Sjb		f->f_tail->fn_next = fn;
71178481Sjb		f->f_tail = fn;
72178481Sjb	}
73178481Sjb}
74178481Sjb
75178481Sjb/* Remove from the front of the fifo */
76178481Sjbvoid *
77178481Sjbfifo_remove(fifo_t *f)
78178481Sjb{
79178481Sjb	fifonode_t *fn;
80178481Sjb	void *data;
81178481Sjb
82178481Sjb	if ((fn = f->f_head) == NULL)
83178481Sjb		return (NULL);
84178481Sjb
85178481Sjb	data = fn->fn_data;
86178481Sjb	if ((f->f_head = fn->fn_next) == NULL)
87178481Sjb		f->f_tail = NULL;
88178481Sjb
89178481Sjb	free(fn);
90178481Sjb
91178481Sjb	return (data);
92178481Sjb}
93178481Sjb
94178481Sjb/*ARGSUSED*/
95178481Sjbstatic void
96178481Sjbfifo_nullfree(void *arg)
97178481Sjb{
98178481Sjb	/* this function intentionally left blank */
99178481Sjb}
100178481Sjb
101178481Sjb/* Free an entire fifo */
102178481Sjbvoid
103178481Sjbfifo_free(fifo_t *f, void (*freefn)(void *))
104178481Sjb{
105178481Sjb	fifonode_t *fn = f->f_head;
106178481Sjb	fifonode_t *tmp;
107178481Sjb
108178481Sjb	if (freefn == NULL)
109178481Sjb		freefn = fifo_nullfree;
110178481Sjb
111178481Sjb	while (fn) {
112178481Sjb		(*freefn)(fn->fn_data);
113178481Sjb
114178481Sjb		tmp = fn;
115178481Sjb		fn = fn->fn_next;
116178481Sjb		free(tmp);
117178481Sjb	}
118178481Sjb
119178481Sjb	free(f);
120178481Sjb}
121178481Sjb
122178481Sjbint
123178481Sjbfifo_len(fifo_t *f)
124178481Sjb{
125178481Sjb	fifonode_t *fn;
126178481Sjb	int i;
127178481Sjb
128178481Sjb	for (i = 0, fn = f->f_head; fn; fn = fn->fn_next, i++);
129178481Sjb
130178481Sjb	return (i);
131178481Sjb}
132178481Sjb
133178481Sjbint
134178481Sjbfifo_empty(fifo_t *f)
135178481Sjb{
136178481Sjb	return (f->f_head == NULL);
137178481Sjb}
138178481Sjb
139178481Sjbint
140178481Sjbfifo_iter(fifo_t *f, int (*iter)(void *data, void *arg), void *arg)
141178481Sjb{
142178481Sjb	fifonode_t *fn;
143178481Sjb	int rc;
144178481Sjb	int ret = 0;
145178481Sjb
146178481Sjb	for (fn = f->f_head; fn; fn = fn->fn_next) {
147178481Sjb		if ((rc = iter(fn->fn_data, arg)) < 0)
148178481Sjb			return (-1);
149178481Sjb		ret += rc;
150178481Sjb	}
151178481Sjb
152178481Sjb	return (ret);
153178481Sjb}
154