Re: New GIOChannel patch
- From: Owen Taylor <otaylor redhat com>
- To: Ron Steinke <rsteinke w-link net>
- Cc: gtk-devel-list gnome org
- Subject: Re: New GIOChannel patch
- Date: 17 Jul 2001 22:33:38 -0400
Ron Steinke <rsteinke w-link net> writes:
> > > > * Need to make a read-only-returns-whole-characters guarantee
> > > > for reading for UTF-8, and validate incoming data.
> > >
> > > Did this, excluding the encodings NULL (guaranteed to be binary safe)
> > > and GIOChannelEncodeRaw.
> >
> > So, we have for special encodings:
> >
> > - "UTF-8" works just like it wasn't a special case, but doesn't
> > involve opening a converter from UTF-8 to UTF-8.
> >
> > - NULL. No conversion, byte-by-byte.
> >
> > - GIOChannelEncodeRaw. Like NULL but no buffering?
> >
> > The NULL / GIOChannelEncodeRaw distinction strikes me as something
> > that shouldn't be controlled by the encoding - since there
> > is no difference in encoding. Rather, there should be a
> > separate g_io_channel_set_unbuffered(), or something.
>
> Mabye we should just rename g_io_channel_set_encoding() to
> something more general.
Well, assuming we could come up with a decent name.
Argument for:
* Buffering and encoding conversion do interact. You can't
have encoding conversion without buffering.
So mixing them together as a single setting does
follow the good rule of preventing mistakes by
simply not having the potential for them in the interface.
Argument against:
* I don't think people will really see the connection
and will be confused if we mix the two together.
It is easier, I think to present them as separate and
then be told: if you call g_io_channel_set_unbuffered,
you must use G_IO_CHANNEL_ENCODE_RAW as your encoding.
> > Well, that's handled right by:
> >
> > /* Only return TRUE here if _all_ bits in watch->condition will be set
> > */
> > return ((watch->condition & buffer_condition) == watch->condition);
> >
> > Right? Actually, I don't think we should set the G_IO_OUT bit
> > unless we have space in the buffer ... if I'm trying to write
> > a 30 meg file to a socket, and am using G_IO_OUT, and I don't
> > want to create a 30 meg local bugger.
>
> So the current approach seems to be correct. The only question I
> have left is if we need some sort of automatic flush watch.
I don't think an automatic flush watch is feasible ... we
generally have no idea whether the user is using a main
context, what main context it is using, or what the thread
contraints are.
However, you are right that there is a problem .... to flush output
through a buffer to a non-blocking location involves pushing data
along at two locations, not just one. If we have space at the first
location, we should call g_io_channel_write_chars(), if we have space
at the second location, we should call g_io_channel_flush().
One idea is a special type of source: g_io_channel_add_flush_watch()
that gets called when the underlying file descriptor needs
flushing,
But this seems rather over-complex. An alternative would be to expose
the amount of data in the write buffer via an API function, and report
G_IO_OUT only when a write is allowed on the output stream. Then
people could write for their callback :
if (g_io_channel_get_pending_write_bytes (channel) > HIGH_WATER_MARK)
g_io_channel_flush (channel);
while (g_io_channel_get_pending_write_bytes (channel) < LOW_WATER_MARK)
{
/* Write some more data into the buffer */
}
> > > > * There is no reason (IMO) to expand the write buffer arbitrarily
> > > > when writing characters - just flush out each chunk as
> > > > it converted.
> > >
> > > Writing before conversion is complete would cause problems in dealing
> > > with error conditions. Currently, if an error is detected in
> > > writing, the write buffer is returned to its previous condition
> > > and bytes_written is set to zero. If we start writing before we're
> > > sure there aren't any conversion errors, we can't do this.
> >
> > I think this is fine. We see the same behavior with out of space
> > errors - we write the part that fits, we get a short write,
> > we try again, we get a ENOSPACE error for the remainder,
> > and return that as a GError.
> >
> > If we wanted to preserve the "error returned only if nothing
> > written" aspect of write(), we'd have to make sure we only
> > ever did one write() per call of g_io_channel_write_chars()
> > which is neither easy to do nor desirable.
>
> So, should I then return the number of characters actually written
> in *bytes_written even on error?
I don't think it would hurt to do this, though I'm not sure
when it would be useful either.
> > * If it's a file, it's most likely a programming error
> > and/or a misencoded internal stream,
> >
> > I don't see any disaster in not reporting this error, and
> > it seems to me that making this an error could occasionally
> > be quite annoying.
>
> Okay. I'll change it to a g_warning(), and clear the
> contents of the partial character buffer on flush.
>
> This is now bug #57694.
The behavior that I would tend expect is:
- Silently retain partial characters on g_io_channel_flush()
- g_warning() in g_io_channel_read() if we, for a seekable
channel have partial characters remaining after a flush.
I'm not sure if this is the behavior you are planning to
implement or not.
Regards,
Owen
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]