Re: Data available for reading in a GIOChannel

2007-05-30 Thread Tristan Van Berkom
On Tue, 2007-05-29 at 22:42 +0100, Robert Pearce wrote:
 On Tue, 29 May 2007, Jonathan Winterflood 
 [EMAIL PROTECTED] wrote :
 
 A question arises, though: is it possible that the channel will recieve 
 the last of the data between the 
 time  g_io_channel_read_chars  returns G_IO_STATUS_AGAIN and the callbac
 k exits, and that the callback will not be called again?
 
 I don't think so, but given that somebody posted from experience that 
 the callback is reentrant (which I didn't think was possible) perhaps 
 I'm wrong. On the other hand, I've written code that assumes both 
 non-reentrant and that any extra data arriving during the callback will 
 result in it being called again, and I've never hit a problem.

A GIOWatch function is definitly not reentrant, a mainloop runs in a
single thread, you could have set up a mainloop and GMainContext to
handle a mainloop in a second thread, even there your GIOWatch callback
will not be reentrant.

This document describes what the mainloop does:
http://developer.gnome.org/doc/API/2.0/glib/glib-The-Main-Event-Loop.html


Cheers,
  -Tristan


___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-30 Thread Chris Vine
On Tue, 2007-05-29 at 22:42 +0100, Robert Pearce wrote:

 My understanding was that the Glib idle task checks the IO channel 
 status and calls the callback if it's ready. Since Glib is non-threaded, 
 this cannot happen during a previous execution of the callback. And 
 since it uses the channel's state rather than any edge events, no data 
 will be lost or ignored simply because the callback was running at the 
 time it arrived. Indeed this must be true if Glib is non-threaded, 
 because the data may arrive at any time and some huge Gtk re-draw may be 
 in progress when it happens. But that's only my understanding as a user 
 so I'd advise you all to ask one of the authors.

I am not one of the authors, but that is how it works (although on Unix
not using an idle task).  The GIOWatch/GSource object for a GIOChannel
watch uses poll() (on Unix) and if a watch is set on a GIOChannel object
and data arrives while the main loop is executing, or indeed while a
read of the GIOChannel object in the watch callback is taking place,
then when the current main loop iteration has finished the main loop
will be fired again and the data will be picked up on the next iteration
through the loop.  It would be a huge bug if after setting a watch on a
GIOChannel object, the watch permanently misses data arriving while the
main loop is doing other things, or indeed is doing a read of the same
GIOChannel object.

The normal way of dealing with the OP's situation is to set a watch on
the GIOChannel object, and then for the watch callback to do
non-blocking reads which loop until EAGAIN is received (equating to
g_io_channel_read_*() returning G_IO_STATUS_AGAIN).

According to the OP's original posting he has in the past made blocking
reads on C++ streams which rely on std::streambuf::is_avail() or its
equivalent in Java.  That is fairly hopeless as it only tells you what
is in the buffers, not what the system has available for reading.  It
therefore represents very old news - it tells you the minimum that can
be read without blocking (which could be 0), but certainly not the
maximum which can be read without blocking (which could be lots more).
In fact in C++ streambufs (I don't know about Java buffers but I imagine
the same applies) a stalemate can be reached, whereby because is_avail()
returns 0 no read is made, and because no read is made the buffers never
fill up.

On your threading point, glib is threaded in the sense that it is thread
safe and that you can have different GMainContext objects in different
threads.  So you could have a special thread with its own main loop
which only, for example, deals with reading from particular pipes or
sockets.  However, that is not relevant to the OP's enquiry (if reading
via a watch attached to that thread's main loop, he would still need to
do non-blocking reads in the way described above).

Chris


___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-29 Thread Alexandre Moreira
On 5/28/07, Ana [EMAIL PROTECTED] wrote:
 On Mon, May 28, 2007 at 04:42:11PM -0300, Alexandre Moreira wrote:
  On 5/28/07, Robert Pearce [EMAIL PROTECTED] 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.

Perhaps I didn't express myself well enough. But I'll try to be clearer now.

 That was pretty much what I was talking about: I don't know about
Glib's IO Channels, but there are certain facilities (epoll on linux,
for example, IIRC) which let's the programmer choose which kind of
behavior it'll have: level based (if exists data to be read it will
return with the result) or edge based (whenever it goes from not
having data to be read to having data to be read it'll return with the
result).

What I mean was, depending on what stuff glib uses on certain
architectures, it could behave in a way that the problem I mentioned
would be relevant. As such, I find safer to read stuff until it tells
me it would block (Ok, there is the possibility of a starvation there,
but I don't write this kind of code often enough to worry about it...
I should really give the subject a bit more study/thought.)

Regards,
Alexandre Moreira.


 - Ana

 ___
 gtk-list mailing list
 gtk-list@gnome.org
 http://mail.gnome.org/mailman/listinfo/gtk-list

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-29 Thread Jonathan Winterflood

Hi,


you never know how much readable data is available until you read it, you

are only ever guaranteed to have one byte of data available for reading
anyway.

In my opinion, the channel should _always_ know how much data is available,
how can it tell that there is nothing there?... Plus, it can't not know the
amount of data it _has_ actually recieved and is buffered ready for me...

Java InputStreams for example have the available() method:
http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#available()
http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#available%28%29


[...] I read the data in 1024 byte chunks [...]

This sounds like a good workaround, which will work well in a watch
callback; I'll use that

Thanks,
Jonathan

On 5/28/07, Armin Burgmeier [EMAIL PROTECTED] wrote:


-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Tristan Van Berkom wrote:
 On Sun, 2007-05-27 at 16:57 +0200, Jonathan Winterflood 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?

 I dont know if gnet provides anything for this, what I typically
 do is:

while (select (fds, readable condition)) {
   read (a single byte of data);
}

I don't think this is very efficient because it calls select and read
for a every single byte you want to receive. I normally put the socket
in non-blocking mode and as soon as glib indicates readability I read
the data in 1024 byte chunks until I get EGAIN from recv() (or,
G_IO_STATUS_AGAIN from g_io_channel_read_chars(), respectively).

Greetings,
Armin
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.5 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGWtx9hOtxKlDYm6cRAg/mAKCFWyGdpMern/YeJ8TrDP1VtJ3j3QCfVEYY
eyd41u6r79MbkumRMGo/WOc=
=mZjC
-END PGP SIGNATURE-





--
Morpheus linux, c'est une question de VI ou de MORE
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-29 Thread Paul Davis
On Mon, 2007-05-28 at 17:26 +0200, Jonathan Winterflood wrote:
 Hi,
 
  you never know how much readable data is available until you read
 it, you are only ever guaranteed to have one byte of data available
 for reading anyway.
 
 In my opinion, the channel should _always_ know how much data is
 available, how can it tell that there is nothing there?... Plus, it
 can't not know the amount of data it _has_ actually recieved and is
 buffered ready for me... 

there is a very big difference between knowing the distinctions between:
 
   * something and nothing
   * specifically how much and nothing at all

the process that leads to the callback is called as soon as a single
byte of data arrives. there might be more data by the time it actually
executes. nothing else in the system (except perhaps a device driver) is
buffering data for you and then saying (post-facto) we have some
stuff. your callback can do that if it wants to offer that kind of
service to high level layers of your application/code.

 Java InputStreams for example have the available() method:
 http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#available()

thats because Java InputStreams are heavily buffered. glib/gtk
IOChannels are not, by default. in particular, when you use this
callback method, your code is being notified that there is data
available long before a Java InputStream would have told that it had
information ready.

  [...] I read the data in 1024 byte chunks [...]
 This sounds like a good workaround, which will work well in a watch
 callback; I'll use that

the important thing is just to use non-blocking I/O with the channel. t

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-29 Thread Travis Miller

Callbacks on a GIOChannel (as described) are re-entrant!.  I know since i
have hit this problem.  Essentially you must read what you can.  If its a
socket you would have soimething like

  bytes_read = recv( fd, ( void * ) ( buffer[
current_byte ] ), expected_size );
  current_byte += bytes_received;

and then you would exit the function.  If current_byte hasn't reached the
expected_size, then you just gotta wait till you
get called back again.  But under no circunstance should you loop in this
function.  You will not get what you want if you do that.

travis miller
[EMAIL PROTECTED]
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-29 Thread Jonathan Winterflood

Thanks for your precisions on where this difference comes from :)

I guess   g_io_channel_set_flags(_channel, G_IO_FLAG_NONBLOCK, NULL);  is
good for switching to non-blocking mode.

A question arises, though: is it possible that the channel will recieve the
last of the data between the
time  g_io_channel_read_chars  returns G_IO_STATUS_AGAIN and the
callback exits, and that the callback will not be called again?

This would be a really easy way to get stuck waiting for data which is
already there, so I'm thinking no, can you confirm this?

Thanks a lot,
Jonathan

On 5/29/07, Paul Davis [EMAIL PROTECTED] wrote:


On Mon, 2007-05-28 at 17:26 +0200, Jonathan Winterflood wrote:
 Hi,

  you never know how much readable data is available until you read
 it, you are only ever guaranteed to have one byte of data available
 for reading anyway.

 In my opinion, the channel should _always_ know how much data is
 available, how can it tell that there is nothing there?... Plus, it
 can't not know the amount of data it _has_ actually recieved and is
 buffered ready for me...

there is a very big difference between knowing the distinctions between:

   * something and nothing
   * specifically how much and nothing at all

the process that leads to the callback is called as soon as a single
byte of data arrives. there might be more data by the time it actually
executes. nothing else in the system (except perhaps a device driver) is
buffering data for you and then saying (post-facto) we have some
stuff. your callback can do that if it wants to offer that kind of
service to high level layers of your application/code.

 Java InputStreams for example have the available() method:

http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#available()

thats because Java InputStreams are heavily buffered. glib/gtk
IOChannels are not, by default. in particular, when you use this
callback method, your code is being notified that there is data
available long before a Java InputStream would have told that it had
information ready.

  [...] I read the data in 1024 byte chunks [...]
 This sounds like a good workaround, which will work well in a watch
 callback; I'll use that

the important thing is just to use non-blocking I/O with the channel. t





--
Morpheus linux, c'est une question de VI ou de MORE
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-29 Thread Robert Pearce
On Tue, 29 May 2007, Jonathan Winterflood 
[EMAIL PROTECTED] wrote :

A question arises, though: is it possible that the channel will recieve 
the last of the data between the 
time  g_io_channel_read_chars  returns G_IO_STATUS_AGAIN and the callbac
k exits, and that the callback will not be called again?

I don't think so, but given that somebody posted from experience that 
the callback is reentrant (which I didn't think was possible) perhaps 
I'm wrong. On the other hand, I've written code that assumes both 
non-reentrant and that any extra data arriving during the callback will 
result in it being called again, and I've never hit a problem.

My understanding was that the Glib idle task checks the IO channel 
status and calls the callback if it's ready. Since Glib is non-threaded, 
this cannot happen during a previous execution of the callback. And 
since it uses the channel's state rather than any edge events, no data 
will be lost or ignored simply because the callback was running at the 
time it arrived. Indeed this must be true if Glib is non-threaded, 
because the data may arrive at any time and some huge Gtk re-draw may be 
in progress when it happens. But that's only my understanding as a user 
so I'd advise you all to ask one of the authors.
-- 
Rob Pearce   http://www.bdt-home.demon.co.uk

The contents of this | Windows NT crashed.
message are purely   | I am the Blue Screen of Death.
my opinion. Don't| No one hears your screams.
believe a word.  |
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-29 Thread Ana
Looking at the glib source here:

glib/giochannel.c
glib/giochannel.h
glib/giounix.c

You can see that, at least on a *nix machine, g_io_channel_read_chars()
calls the c library read() on a file descriptor in the GIOChannel
struct.  The segment:


  result = read (unix_channel-fd, buf, count);

  if (result  0)
{
  *bytes_read = 0;

  switch (errno)
{
#ifdef EINTR
  case EINTR:
goto retry;
#endif
#ifdef EAGAIN
  case EAGAIN:
return G_IO_STATUS_AGAIN;
#endif


So, basically, on a Linux (or presumably any *nix like OS) the semantics
of g_io_channel_read_chars() will be roughly the same as POSIX read()*.
You can see that when read() returns -1 ( 0), and the global errno is
set to EAGAIN then G_IO_STATUS_AGAIN is returned.

read() is a system call.  Last I checked (a long, long time ago) EAGAIN
is set in the kernel side of the read() call when there is no data in
the buffer to read.  Unless I'm mistaken, the only way, in *nix land, to
hear from the kernel again about there being more data, is to call
select(), poll(), or read() again...  or to handle SIGIO while using
signal-driven IO (see O_ASYNC in the open(2) man page and*).

The g_io_channels appear to use poll() if a built-in system version is
available, and to emulate poll(), if it's not.  So, I believe the
semantics, on *nix at least, more or less amount to:

while( poll() )  /* glib main loop does this */
{
read();  /* your callback does this */
}


I don't see any magic happening that might make it more complicated.  If
you're using threads then it does get more complicated, but not in any
way that can't be managed by typical thread management.  Also, the
functions that are actually used to do the reading are set as callbacks
in the GIOChannel struct.  Default calls the standard unix read(), but
if you're working on someone else's code...  you may want to double
check that.

I have never done IO on a win32 or...  really on any non-*nix machine,
so my experience is a bit limited.  As I understand it though, glib/gtk+
work at making the differences as small as possible.  I would not expect
a significant difference in how the g_io_channel interface behaves.

- Ana



* if you haven't already read it: Advanced Programming in the UNIX
Environment, by W. Richard Stevens is a good book to keep around.

On Tue, May 29, 2007 at 10:20:20PM +0200, Jonathan Winterflood wrote:
Thanks for your precisions on where this difference comes from :)
 
I guess   g_io_channel_set_flags(_channel, G_IO_FLAG_NONBLOCK, NULL);  is
good for switching to non-blocking mode.
 
A question arises, though: is it possible that the channel will recieve
the last of the data between the
time  g_io_channel_read_chars  returns G_IO_STATUS_AGAIN and the callback 
 exits, and that the callback will not be called again?
 
This would be a really easy way to get stuck waiting for data which is
already there, so I'm thinking no, can you confirm this?
 
Thanks a lot,
Jonathan
 
On 5/29/07, Paul Davis [EMAIL PROTECTED] wrote:
 
  On Mon, 2007-05-28 at 17:26 +0200, Jonathan Winterflood wrote:
   Hi,
  
you never know how much readable data is available until you read
   it, you are only ever guaranteed to have one byte of data available
   for reading anyway.
  
   In my opinion, the channel should _always_ know how much data is
   available, how can it tell that there is nothing there?... Plus, it
   can't not know the amount of data it _has_ actually recieved and is
   buffered ready for me...
 
  there is a very big difference between knowing the distinctions between:
 
 * something and nothing
 * specifically how much and nothing at all
 
  the process that leads to the callback is called as soon as a single
  byte of data arrives. there might be more data by the time it actually
  executes. nothing else in the system (except perhaps a device driver) is
  buffering data for you and then saying (post-facto) we have some
  stuff. your callback can do that if it wants to offer that kind of
  service to high level layers of your application/code.
 
   Java InputStreams for example have the available() method:
  
  
 [2]http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#available()
 
  thats because Java InputStreams are heavily buffered. glib/gtk
  IOChannels are not, by default. in particular, when you use this
  callback method, your code is being notified that there is data
  available long before a Java InputStream would have told that it had
  information ready.
 
[...] I read the data in 1024 byte chunks [...]
   This sounds like a good workaround, which will work well in a watch
   callback; I'll use that
 
 

Re: Data available for reading in a GIOChannel

2007-05-28 Thread Tristan Van Berkom
On Sun, 2007-05-27 at 16:57 +0200, Jonathan Winterflood 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? 

I dont know if gnet provides anything for this, what I typically
do is:

   while (select (fds, readable condition)) {
  read (a single byte of data);
   }

Regardless of the method used, you never know how much readable
data is available until you read it, you are only ever gaurunteed
to have one byte of data available for reading anyway.

Cheers,
-Tristan



___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-28 Thread Armin Burgmeier
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Tristan Van Berkom wrote:
 On Sun, 2007-05-27 at 16:57 +0200, Jonathan Winterflood 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? 
 
 I dont know if gnet provides anything for this, what I typically
 do is:
 
while (select (fds, readable condition)) {
   read (a single byte of data);
}

I don't think this is very efficient because it calls select and read
for a every single byte you want to receive. I normally put the socket
in non-blocking mode and as soon as glib indicates readability I read
the data in 1024 byte chunks until I get EGAIN from recv() (or,
G_IO_STATUS_AGAIN from g_io_channel_read_chars(), respectively).

Greetings,
Armin
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.5 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGWtx9hOtxKlDYm6cRAg/mAKCFWyGdpMern/YeJ8TrDP1VtJ3j3QCfVEYY
eyd41u6r79MbkumRMGo/WOc=
=mZjC
-END PGP SIGNATURE-
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-28 Thread Robert Pearce
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.
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-28 Thread Alexandre Moreira
On 5/28/07, Robert Pearce [EMAIL PROTECTED] 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).

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.

Regards,
Alexandre Moreira.

 ___
 gtk-list mailing list
 gtk-list@gnome.org
 http://mail.gnome.org/mailman/listinfo/gtk-list

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Data available for reading in a GIOChannel

2007-05-28 Thread Ana
On Mon, May 28, 2007 at 04:42:11PM -0300, Alexandre Moreira wrote:
 On 5/28/07, Robert Pearce [EMAIL PROTECTED] 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

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list