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:
35 #include <sys/types.h>
45 typedef struct iovec {
52 static int ioqtobuf();
53 static int ioqtoiov();
54 static void enqueuecc();
55 static int dequeuecc();
60 struct qelem *makeqt();
68 extern s_char num_teles[];
77 * copy batch of pointers into the passed
78 * iovec, but don't actually dequeue the data.
79 * return # of iovec initialized.
82 ioq_peekiov(ioq, iov, max)
89 return ioqtoiov(ioq, iov, max);
93 * Copy the specified number of characters into the buffer
94 * provided, without actually dequeueing the data. Return
95 * number of bytes actually found.
98 ioq_peek(ioq, buf, cc)
103 return ioqtobuf(ioq, buf, cc);
111 if (dequeuecc(ioq, cc) != cc)
117 ioq_read(ioq, buf, cc)
124 n = ioqtobuf(ioq, buf, cc);
131 ioq_write(ioq, buf, cc)
136 enqueuecc(ioq, buf, cc);
153 while ((qp = ioq->queue.q_forw) != &ioq->queue) {
154 io = (struct io *) qp;
156 (void) remque(&io->queue);
163 ioq_gets(ioq, buf, cc)
169 register s_char *end;
172 nbytes = ioqtobuf(ioq, buf, cc);
176 for (p = buf; p < end && *p; p++) {
179 dequeuecc(ioq, (p - buf) + 1);
187 * all the rest are local to this module
192 * copy cc bytes from ioq to buf.
193 * this routine doesn't free memory; this is
194 * 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 bcopy(io->data + io->offset, 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.
239 ioqtoiov(ioq, iov, max)
240 register struct ioqueue *ioq;
241 register struct iovec *iov;
244 register struct io *io;
251 qp = ioq->queue.q_forw;
252 for (qp = ioq->queue.q_forw; qp != &ioq->queue; qp = qp->q_forw) {
253 io = (struct io *) qp;
254 if (niov >= MAXIOV || cc >= max)
256 iov->iov_base = io->data + io->offset;
257 iov->iov_len = io->nbytes - io->offset;
258 cc += io->nbytes - io->offset;
266 * append a buffer to the end of the ioq.
269 enqueuecc(ioq, buf, cc)
276 io = (struct io *) malloc(sizeof(*io));
280 insque(&io->queue, ioq->queue.q_back);
285 * remove cc bytes from ioqueue ioq
286 * free memory, dequeue io elements
287 * which are no longer used.
292 register struct ioqueue *ioq;
295 register struct io *io;
296 register struct qelem *qp;
301 while ((qp = ioq->queue.q_forw) != &ioq->queue) {
302 io = (struct io *) qp;
303 there = io->nbytes - io->offset;
305 fprintf(stderr, "dequeuecc: nbytes %d, offset %d\n",
306 io->nbytes, io->offset);
312 (void) remque(&io->queue);