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();
55 static int ioqtoiov();
56 static void enqueuecc();
57 static int dequeuecc();
62 struct qelem *makeqt();
69 extern s_char num_teles[];
78 * copy batch of pointers into the passed
79 * iovec, but don't actually dequeue the data.
80 * return # of iovec initialized.
83 ioq_peekiov(ioq, iov, max)
90 return ioqtoiov(ioq, iov, max);
94 * Copy the specified number of characters into the buffer
95 * provided, without actually dequeueing the data. Return
96 * number of bytes actually found.
99 ioq_peek(ioq, buf, cc)
104 return ioqtobuf(ioq, buf, cc);
112 if (dequeuecc(ioq, cc) != cc)
118 ioq_read(ioq, buf, cc)
125 n = ioqtobuf(ioq, buf, cc);
132 ioq_write(ioq, buf, cc)
137 enqueuecc(ioq, buf, cc);
154 while ((qp = ioq->queue.q_forw) != &ioq->queue) {
155 io = (struct io *)qp;
157 (void)remque(&io->queue);
164 ioq_gets(ioq, buf, cc)
170 register s_char *end;
173 nbytes = ioqtobuf(ioq, buf, cc);
177 for (p = buf; p < end && *p; p++) {
180 dequeuecc(ioq, (p - buf) + 1);
188 * all the rest are local to this module
193 * copy cc bytes from ioq to buf.
194 * this routine doesn't free memory; this is
195 * left for a higher level.
198 ioqtobuf(ioq, buf, cc)
199 register struct ioqueue *ioq;
203 register struct io *io;
211 for (qp = ioq->queue.q_forw; qp != &ioq->queue; qp = qp->q_forw) {
212 io = (struct io *)qp;
213 if ((nbytes = io->nbytes - io->offset) < 0) {
214 fprintf(stderr, "ioqtobuf: offset %d nbytes %d\n",
215 io->offset, io->nbytes);
221 memcpy(offset, io->data + io->offset, nbytes);
230 * translate "around" max bytes to an iovec
231 * array. The limit max is only advisory,
232 * and more may get buffered. It is an attempt to limit
233 * really silly sends -- like sending 40k on a socket
234 * with one writev for example. This makes the processing
235 * of a full ioqueue still be quick.
238 ioqtoiov(ioq, iov, max)
239 register struct ioqueue *ioq;
240 register struct iovec *iov;
243 register struct io *io;
250 qp = ioq->queue.q_forw;
251 for (qp = ioq->queue.q_forw; qp != &ioq->queue; qp = qp->q_forw) {
252 io = (struct io *)qp;
253 if (niov >= MAXIOV || cc >= max)
255 iov->iov_base = io->data + io->offset;
256 iov->iov_len = io->nbytes - io->offset;
257 cc += io->nbytes - io->offset;
265 * append a buffer to the end of the ioq.
268 enqueuecc(ioq, buf, cc)
275 io = (struct io *)malloc(sizeof(*io));
279 insque(&io->queue, ioq->queue.q_back);
284 * remove cc bytes from ioqueue ioq
285 * free memory, dequeue io elements
286 * which are no longer used.
290 register struct ioqueue *ioq;
293 register struct io *io;
294 register struct qelem *qp;
299 while ((qp = ioq->queue.q_forw) != &ioq->queue) {
300 io = (struct io *)qp;
301 there = io->nbytes - io->offset;
303 fprintf(stderr, "dequeuecc: nbytes %d, offset %d\n",
304 io->nbytes, io->offset);
310 (void)remque(&io->queue);