From owner-freebsd-hackers Thu Nov 20 08:31:07 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.7/8.8.7) id IAA15785 for hackers-outgoing; Thu, 20 Nov 1997 08:31:07 -0800 (PST) (envelope-from owner-freebsd-hackers) Received: from trojanhorse.ml.org (mdean.vip.best.com [206.86.94.101]) by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id IAA15776 for ; Thu, 20 Nov 1997 08:31:00 -0800 (PST) (envelope-from jamil@trojanhorse.ml.org) Received: from localhost (jamil@localhost) by trojanhorse.ml.org (8.8.8/8.8.5) with SMTP id IAA01413; Thu, 20 Nov 1997 08:25:49 -0800 (PST) Date: Thu, 20 Nov 1997 08:25:48 -0800 (PST) From: "Jamil J. Weatherbee" To: Joerg Wunsch cc: hackers@freebsd.org Subject: Re: vnode.h and IO_NDELAY (help!!) In-Reply-To: <19971120090611.FW37911@uriah.heep.sax.de> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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; }