f_offset

Ed Schouten ed at 80386.nl
Mon Apr 14 19:18:23 UTC 2008


Hello Poul-Henning,

Sorry, I forgot to reply to your message this afternoon.

* Poul-Henning Kamp <phk at phk.freebsd.dk> wrote:
> In message <20080414074710.GI5934 at hoeg.nl>, Ed Schouten writes:
> 
> >I'm experiencing similar problems with implementing read() and write()
> >inside my mpsafetty branch for TTY's. Just like the current TTY
> >implementation, my implementation will do strange things when two
> >threads call read() or write() at the same time. Data could end up mixed
> >together.
> 
> The write side of this will break quite a lot of stuff, starting
> with syslogd(8), write(1), wall(1) and similar, all which expect
> to be able to spam terminals coherently.
> 
> The read side will probably mostly cause trouble for programs that
> try to take input from /dev/tty, usually passwords.

I'll explain what I've done with the TTY layer somewhat more in depth. I
was a little brief in my last message.

It is true that the read()-side of the TTY layer doesn't really offer
much guarantees when multiple applications try to perform a read() on
both the TTY device or the PTY controller device. I've tried to prevent
as much copying as possible, so unlike the current code there isn't a
buffer in between. A compromise I had to make was that read()'s on TTY's
aren't serialized. I don't think this will cause a problem:

- PTY controller devices aren't really intended to be read()
  by multiple threads at the same time.

- It's not likely multiple read()'s on the TTY device will happen a lot.
  When a background process group tries to perform a read(), it will
  most likely receive a SIGTTIN (except when it ignores the signal,
  etc).

- I am sure this will not cause any problems in canonical mode, because
  there is already a guarantee that the VEOL/VEOF character will always
  be processed by the thread that first detected it. It is not possible
  that the character is interpreted by multiple readers.

Now about the write() case. I said write()'s were completely
unprotected, but I was a little brief about this. Because it's too
complex to implement an unbuffered mechanism that copies data from
userspace directly into the buffer queue (makes locking hard, input
could be processed to expand to a different amount of bytes, etc),
write() calls will be buffered.

There are only two cases where a write() may end up fragmented when
multiple write() calls would happen at the same time:

- The write() exceeds the write buffer size of 256 bytes (100 bytes with
  the current TTY layer). Maybe I should adjust this value, because 256
  bytes may be a lot when allocated on the stack.

- The write() call causes the calling thread to be blocked, because the
  TTY has reached its high watermark.

All in all I think the way I've implemented the TTY layer should be
quite safe. Its guarantees don't differ too much when compared to the
existing implementation, in my opinion.

-- 
 Ed Schouten <ed at 80386.nl>
 WWW: http://g-rave.nl/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-arch/attachments/20080414/ffef8cd9/attachment.pgp


More information about the freebsd-arch mailing list