Date: Thu, 20 Nov 1997 08:25:48 -0800 (PST) From: "Jamil J. Weatherbee" <jamil@trojanhorse.ml.org> To: Joerg Wunsch <joerg_wunsch@uriah.heep.sax.de> Cc: hackers@freebsd.org Subject: Re: vnode.h and IO_NDELAY (help!!) Message-ID: <Pine.BSF.3.96.971120080600.1289B-100000@trojanhorse.ml.org> In-Reply-To: <19971120090611.FW37911@uriah.heep.sax.de>
next in thread | previous in thread | raw e-mail | index | archive | help
global, does not even show there being an rtcread on my system (maybye
because it is -stable), there is an rtc.h though.
Are you saying I should support the FIONBIO ioctl()? Where do I find the
definition of that? Do you have an example?
I had some problems with returning an error (EWOULDBLOCK) if I broke out
because the I/O was going to block. Doesn't returing an error from your
read routine make the users call to read(2) return -1 and errno set to
your error? Anyway I thought that a non-blocking data source should just
simply return 0 when it was no data, not an error. Because thats how I've
seen read(2) used with select, basically select() catch a descriptor that
is ready and exhaust that data source until it reads 0. -1 is really an
error.
Also according to the tsleep manpage, why do you only catch ERESTART and
not EINTR, I found that that catching EINTR was important for me because
if the user threw a huge buffer at me and the acquisition rate was down at
64 bytes/sec, It might take a while after pressing ctrl-C for the program
to exit. So I catch anything non-zero and break out, without returning an
error (except for timeout). The thing is that the uio structure might
already contain some data, and I don't want to loose that normally.
Unless there is something really wrong (timeout). I am afraid if I return
an error than the user will not be able to get at whatever partial data
was there. For instance they might want to have a signal catcher that
catches SIGINT and shuts some things down. Once that exits I assume they
would end up at the instruction after the read call and they could still
get that final data from the interrupted read right?
Anyway can you take a look at this and tell me how it should be?
Also about how I implement (and why) the FIONBIO call?
Here is my code fragment:
--------------------------------------------------------
/* how to read from the board */
static int alog_read (dev_t dev, struct uio *uio, int ioflag)
{
int unit = UNIT(dev);
int chan = CHANNEL(dev);
talog_unit *info = alog_unit[unit];
int s, oldtrig, terr, toread, err = 0;
s = spltty();
oldtrig = info->chan[chan].fifotrig; /* save official trigger value */
while (uio->uio_resid >= sizeof(u_short)) /* while uio has space */
{
if (!info->chan[chan].fifosize) /* if we have an empty fifo */
{
if (ioflag & IO_NDELAY) break; /* exit if we are non-blocking */
/* Start filling fifo on first blocking read */
if (info->chan[chan].status == STATUS_INIT)
info->chan[chan].status = STATUS_INUSE;
/* temporarily adjust the fifo trigger to be optimal size */
info->chan[chan].fifotrig =
min (READMAXTRIG, uio->uio_resid / sizeof(u_short));
/* lets sleep until we have some io available or timeout */
terr = tsleep (&(info->chan[chan].fifo), READPRI | PCATCH, READMSG,
info->chan[chan].fifotrig*READTIMO);
if (terr == EWOULDBLOCK)
{ printf (DEVFORMAT ": read timeout\n", unit,
'a'+EMUX(chan), IMUX(chan));
err = ETIMEDOUT;
break; /* were outta here */
}
if (terr) break; /* if caught a signal then just break out */
}
/* ok, now if we got here there is something to read from the fifo */
/* calculate how many entries we can read out from the fifostart
* pointer */
toread = min (uio->uio_resid / sizeof(u_short),
min (info->chan[chan].fifosize,
FIFOSIZE - info->chan[chan].fifostart));
/* perform the move, if there is an error then exit */
if (err = uiomove((caddr_t)
&(info->chan[chan].fifo[info->chan[chan].fifostart]),
toread * sizeof(u_short), uio)) break;
info->chan[chan].fifosize -= toread; /* fifo this much smaller */
info->chan[chan].fifostart += toread; /* we got this many more */
if (info->chan[chan].fifostart == FIFOSIZE)
info->chan[chan].fifostart = 0; /* wrap around fifostart */
}
info->chan[chan].fifotrig = oldtrig; /* restore trigger changes */
splx(s);
return err;
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.96.971120080600.1289B-100000>
