2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23 * related information and legal notices. It is expected that any future
24 * projects/authors will amend these files as needed.
28 * ioqueue.c: Manage an i/o queue
30 * Known contributors to this file:
37 #include <sys/types.h>
47 typedef struct iovec {
54 static int ioqtobuf(register struct ioqueue *ioq, s_char *buf, int cc);
55 static int ioqtoiov(register struct ioqueue *ioq, register struct iovec *iov, register int max);
56 static void enqueuecc(struct ioqueue *ioq, s_char *buf, int cc);
57 static int dequeuecc(register struct ioqueue *ioq, register int cc);
59 void insque(struct qelem *, struct qelem *);
60 void remque(struct qelem *);
61 void initque(struct qelem *p);
62 struct qelem *makeqt(int nelem);
65 ioq_init(struct ioqueue *ioq, int bsize)
67 extern s_char num_teles[];
76 * copy batch of pointers into the passed
77 * iovec, but don't actually dequeue the data.
78 * return # of iovec initialized.
81 ioq_peekiov(struct ioqueue *ioq, struct iovec *iov, int max)
85 return ioqtoiov(ioq, iov, max);
89 * Copy the specified number of characters into the buffer
90 * provided, without actually dequeueing the data. Return
91 * number of bytes actually found.
94 ioq_peek(struct ioqueue *ioq, s_char *buf, int cc)
96 return ioqtobuf(ioq, buf, cc);
100 ioq_dequeue(struct ioqueue *ioq, int cc)
102 if (dequeuecc(ioq, cc) != cc)
108 ioq_read(struct ioqueue *ioq, s_char *buf, int cc)
112 n = ioqtobuf(ioq, buf, cc);
119 ioq_write(struct ioqueue *ioq, s_char *buf, int cc)
121 enqueuecc(ioq, buf, cc);
125 ioq_qsize(struct ioqueue *ioq)
131 ioq_drain(struct ioqueue *ioq)
136 while ((qp = ioq->queue.q_forw) != &ioq->queue) {
137 io = (struct io *)qp;
139 (void)remque(&io->queue);
146 ioq_gets(struct ioqueue *ioq, s_char *buf, int cc)
149 register s_char *end;
152 nbytes = ioqtobuf(ioq, buf, cc);
156 for (p = buf; p < end && *p; p++) {
159 dequeuecc(ioq, (p - buf) + 1);
167 * all the rest are local to this module
172 * copy cc bytes from ioq to buf.
173 * this routine doesn't free memory; this is
174 * left for a higher level.
177 ioqtobuf(register struct ioqueue *ioq, s_char *buf, int cc)
179 register struct io *io;
187 for (qp = ioq->queue.q_forw; qp != &ioq->queue; qp = qp->q_forw) {
188 io = (struct io *)qp;
189 if ((nbytes = io->nbytes - io->offset) < 0) {
190 fprintf(stderr, "ioqtobuf: offset %d nbytes %d\n",
191 io->offset, io->nbytes);
197 memcpy(offset, io->data + io->offset, nbytes);
206 * translate "around" max bytes to an iovec
207 * array. The limit max is only advisory,
208 * and more may get buffered. It is an attempt to limit
209 * really silly sends -- like sending 40k on a socket
210 * with one writev for example. This makes the processing
211 * of a full ioqueue still be quick.
214 ioqtoiov(register struct ioqueue *ioq, register struct iovec *iov, register int max)
216 register struct io *io;
223 qp = ioq->queue.q_forw;
224 for (qp = ioq->queue.q_forw; qp != &ioq->queue; qp = qp->q_forw) {
225 io = (struct io *)qp;
226 if (niov >= MAXIOV || cc >= max)
228 iov->iov_base = io->data + io->offset;
229 iov->iov_len = io->nbytes - io->offset;
230 cc += io->nbytes - io->offset;
238 * append a buffer to the end of the ioq.
241 enqueuecc(struct ioqueue *ioq, s_char *buf, int cc)
245 io = (struct io *)malloc(sizeof(*io));
249 insque(&io->queue, ioq->queue.q_back);
254 * remove cc bytes from ioqueue ioq
255 * free memory, dequeue io elements
256 * which are no longer used.
259 dequeuecc(register struct ioqueue *ioq, register int cc)
261 register struct io *io;
262 register struct qelem *qp;
267 while ((qp = ioq->queue.q_forw) != &ioq->queue) {
268 io = (struct io *)qp;
269 there = io->nbytes - io->offset;
271 fprintf(stderr, "dequeuecc: nbytes %d, offset %d\n",
272 io->nbytes, io->offset);
278 (void)remque(&io->queue);