This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch] Fix libstdc++/9533


On Tue, Mar 04, 2003 at 10:13:52AM +0100, Paolo Carlini wrote:
> Nathan Myers wrote:
> 
> >>The current showmanyc() is really simple:
> >>... 
> >>Dunno what can be put in it according to the standard.
> >>
> >Almost anything.  This is good, because now we don't need the 
> >block() and no_block() functions; it all goes in showmanyc().
> >showmanyc() is supposed to tell all it can find out about how
> >many bytes are really there, not just how many it has buffered
> >or will buffer, but it shouldn't take too long about it.
>
> Yes.
> I agree that it would be great to avoid the block/no_block
> functions and putting everything inside showmanyc(). On the other
> hand, what I find a little disturbing is that, instead of doing
> this very-low-level work once, during open(), we end up doing it
> repeatedly every time showmanyc() is called. And in general,
> as a general design issue, this kind of code is really special:
> you are not going to find any low-level system call inside the
> other member functions.
> Don't you share with me the feeling that perhaps the problem can
> be fixed (or better avoided completely) by using a new higher
> level strategy, perhaps even involving, a largish redesign of some
> components, I don't know?

IMHO, we should do the least amount of work possible in open(),
and particularly not try to fill a buffer.  I know what you mean
about putting lots of low-level operations in a single virtual;
it will get messy with #ifs for stuff that might not be present
on the platform.  Still, that is precisely what the virtuals are 
for: a place to put detailed semantics.  The general stuff is in 
basic_streambuf<> members.  I expect to see ::write() in overflow() 
(only!) and ::read() in underflow() (only!).

> Anyway...
> 
> >Ideally showmanyc() should try to do an fstat64() on the file 
> >descriptor and report the result, if any.   If it's not a file,
> >then the IFREG or S_ISREG flag won't be set, and the st_size 
> >isn't meaningful.  (If fstat64() reports more bytes than a 
> >streamsize could represent, it ought to return 
> >numeric_limits<streamsize>::max().  (Of course there might not
> >be an fstat64(), so that would have to be #ifdef'ed, and use
> >fstat() then.))
> >
> >It also ought to try 
> >
> > ::recv(this->fd(), 0, 0, (MSG_DONTWAIT|MSG_PEEK|MSG_NOSIGNAL))
> >
> >in case it's a socket or pipe.  In fact, it should prefer that 
> >over setting and clearing flags on the file descriptor and calling 
> >underflow.  It would be rude for showmanyc to actually read the bytes 
> >when it doesn't have to.  (If it returns -1, then errno is set to 
> >EAGAIN if it meant to return zero.)
> 
> Thanks Nathan for this invaluable information. If we all agree to
> actually put this kinf of code inside showmanyc (or better inside a
> __basic_file function called from there, of course)  your explanations
> should be largely sufficient for me to prepare something which (almost)
> works.
> 
> Two questions, as a check of my understanding:
> 1- You suggest first calling fstat, then, if IFREG or S_IREG are not set,
> calling recv, in order to acquire the similar information for pipes?

I was thinking about this.  I now think it would be better to call 
::recv() first, and if that fails, call ::fstat.  The rationale is 
that it is much more likely for it to be called in a loop on a socket, 
and ::recv() is a lot cheaper.  If the fd is really a file, they 
probably only call it once to get the total size and be done.  

> 2- After that, we do _not_ actually read the data into the buffer, just
> return from showmanyc a sensible value, a next underflow will do,
> sure to obtain at least that amount of data.

Right.  

Nathan Myers
ncm-nospam at cantrip dot org


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]