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:
36 #include <sys/types.h>
46 typedef struct iovec {
53 static int ioqtobuf();
54 static int ioqtoiov();
55 static void enqueuecc();
56 static int dequeuecc();
61 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.
197 ioqtobuf(ioq, buf, cc)
198 register struct ioqueue *ioq;
202 register struct io *io;
210 for (qp = ioq->queue.q_forw; qp != &ioq->queue; qp = qp->q_forw) {
211 io = (struct io *)qp;
212 if ((nbytes = io->nbytes - io->offset) < 0) {
213 fprintf(stderr, "ioqtobuf: offset %d nbytes %d\n",
214 io->offset, io->nbytes);
220 memcpy(offset, io->data + io->offset, nbytes);
229 * translate "around" max bytes to an iovec
230 * array. The limit max is only advisory,
231 * and more may get buffered. It is an attempt to limit
232 * really silly sends -- like sending 40k on a socket
233 * with one writev for example. This makes the processing
234 * of a full ioqueue still be quick.
237 ioqtoiov(ioq, iov, max)
238 register struct ioqueue *ioq;
239 register struct iovec *iov;
242 register struct io *io;
249 qp = ioq->queue.q_forw;
250 for (qp = ioq->queue.q_forw; qp != &ioq->queue; qp = qp->q_forw) {
251 io = (struct io *)qp;
252 if (niov >= MAXIOV || cc >= max)
254 iov->iov_base = io->data + io->offset;
255 iov->iov_len = io->nbytes - io->offset;
256 cc += io->nbytes - io->offset;
264 * append a buffer to the end of the ioq.
267 enqueuecc(ioq, buf, cc)
274 io = (struct io *)malloc(sizeof(*io));
278 insque(&io->queue, ioq->queue.q_back);
283 * remove cc bytes from ioqueue ioq
284 * free memory, dequeue io elements
285 * which are no longer used.
289 register struct ioqueue *ioq;
292 register struct io *io;
293 register struct qelem *qp;
298 while ((qp = ioq->queue.q_forw) != &ioq->queue) {
299 io = (struct io *)qp;
300 there = io->nbytes - io->offset;
302 fprintf(stderr, "dequeuecc: nbytes %d, offset %d\n",
303 io->nbytes, io->offset);
309 (void)remque(&io->queue);