Re: Data available for reading in a GIOChannel

On Mon, May 28, 2007 at 04:42:11PM -0300, Alexandre Moreira wrote:
> On 5/28/07, Robert Pearce <rob bdt-home demon co uk> wrote:
> > On Sun, 27 May 2007 16:57:03 +0200 Jonathan wrote:
> > > Hi,
> > >
> > > I need to read a large amount of data from a GIOChannel (200K, over
> > > the internet).
> > >
> > > So far, I use the gnet library to create the
> > > socket, and then I use the GIOChannel to integrate the read/writing
> > > into the program's loop (a
> > > GTK application)
> > >
> > > I use g_io_add_watch(_channel, G_IO_IN, &(_imageDataReadyForReading), this);
> > > to register the callback for data reading.
> > >
> > > How can I determine the number of bytes available for reading, so as not to
> > > block on reading the data?
> > >
> >
> > On the applications where I've used g_io_add_watch it's on a serial port that I've opened non-blocking. Then my callback I just does:
> >     stat = g_io_channel_read_chars ( source,
> >                                      tmpbuf, sizeof(tmpbuf), &len, &err );
> >
> > If there are less than tmpbuf characters waiting, it fills what it can and sets len to the actual number. Then I process len bytes. Normally my tmpbuf is bigger than the longest message I expect, but it seems to work even if it isn't.
> Please anyone correct me if I'm wrong, but...
> I guess you should loop until EAGAIN,  because you can get some nasty
> things if your program is being run on a system where the select (or
> poll, or whatever it uses to watch the channels) call returns when the
> file descriptor CHANGES its state (ready to read // not ready to
> read).

That's what I typically do.  something like this:

/* make sure 'source' is non-blocking before entering loop
 * below is simplified */
do {
  len = 0;
  stat = g_io_channel_read_chars ( source,
                                   tmpbuf, sizeof(tmpbuf), &len, &err );
  if( len > 0 )
    process_data(tmpbuf, len);
 } while(stat == G_IO_STATUS_NORMAL && len == sizeof(tmpbuf));

Whether it's necessary or advisable to read in a loop like that, I'm not
sure.  Depending on certain things, such how long the process_data()
function takes, you may wish to let the main loop run after every time
process_data() is called...  in which case you wouldn't use a loop like
the above.

> In that case you could create a situation where a client is expecting
> for some response from you, but you didn't actually read the request
> (because it is lost in the buffer) and therefore each process is
> waiting for the other to act.

I think the question here is: if we don't read all available data before
returning to poll/select, will our callback be triggered again so that
we can process the remaining data?  Without doing any research, I
believe the answer would have to be 'yes'.  To make sure, look at some
source or create a test.

- Ana

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]