Re: How to use GIOChannel to read an Unix socket

2010-01-27 Thread Robert Pearce
Hi silverburgh,

On Tue, 26 Jan 2010 23:59:11 -0800 you wrote:
 
 I have updated my gio_read_socket per your advice.

No you haven't.


Chris explicitly said you need to free the GIOChannel objectand that using 
g_io_channel_shutdown of itself is not sufficient. I quote:

 Actually, you have attempted to fix your problem in a different way,
 by closing the socket when the read data length is 0, assuming that you
 are doing blocking reads.  However, you need to free the GIOChannel
 object. The easiest way to do that is to call g_io_channel_unref() on
 the GIOChannel object immediately after you have called
 g_io_add_watch() on it. g_io_channel_*_new() returns a GIOChannel
 object with a reference count of one.  g_io_add_watch() adds a further
 reference count - if you decrement it by 1, the callback will be
 disconnected and the relevant GSource object removed when the callback
 returns FALSE, which it should do when it detects end-of-file, or if
 you call g_source_remove() on the return value of g_io_add_watch().
 (Incidentally, you are also supposed to use g_io_channel_shutdown()
 rather than g_io_channel_close(), but that of itself is not sufficient
 to free the GIOCondition object and it is not necessary anyway in this
 usage.)  I agree that the documentation on this isn't very good.

So you need to change how you create the channel object (which you haven't 
posted so I have to assume you didn't change it) _AND_ you need to ensure that 
the callback returns FALSE when it detects end of file. Try doing what Chris 
said and see if that helps.

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


Re: How to use GIOChannel to read an Unix socket

2010-01-27 Thread Chris Vine
On Tue, 26 Jan 2010 23:59:11 -0800
silverburgh silverburgh.me...@gmail.com wrote:
 I have updated my gio_read_socket per your advice.
 But when the other end closes the socket (the GIOChannel* gio ties to
 that socket),
 I get a segmentation fault.  I think some how when I call
 gio_shutdown, it ends up calling gio_read_socket again, and it crashes
 with a Segmentation fault.
 
 My console output:
 gio shutdown:
  gio_read_socket
 
 (GtkLauncher:5402): GLib-CRITICAL **: g_io_channel_read_line:
 assertion `channel-is_readable' failed
 
 Program received signal SIGSEGV, Segmentation fault.
 0x08048aa4 in gio_read_socket (gio=0x8590f50, condition=G_IO_IN,
 data=0x0) at main.c:230
 230   g_error (Error reading: %s\n,
 err-message);
 
 
 static gboolean
 gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer
 data) {
 printf ( gio_read_socket \n);
 GIOStatus ret;
 GError *err = NULL;
 gchar *msg;
 gsize len;
 
   if (condition  G_IO_HUP){
 printf (Read end of pipe died!\n);
 return TRUE;
   }
 
 ret = g_io_channel_read_line (gio, msg, len, NULL, err);
 if (ret == G_IO_STATUS_ERROR)
 g_error (Error reading: %s\n, err-message);
 else if (ret == G_IO_STATUS_EOF) {
 printf (gio shutdown: \n);
   g_io_channel_shutdown(gio, true, err);
   } else {
 printf (Read %u bytes: %s\n, len, msg);
 g_free (msg);
   }
 
 return TRUE;
 }
 
 Thank you for any more help.

You need to return FALSE in the callback if G_IO_HUP or G_IO_STATUS_EOF
is detected, since that will cause disconnection of the callback from
the glib main loop.  If you have previously called g_io_channel_unref()
after the call to g_io_add_watch(), then this will also dispose of the
GIOChannel object, so don't try to access it again.

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


Re: How to use GIOChannel to read an Unix socket

2010-01-26 Thread silverburgh
Chris,

I have updated my gio_read_socket per your advice.
But when the other end closes the socket (the GIOChannel* gio ties to
that socket),
I get a segmentation fault.  I think some how when I call
gio_shutdown, it ends up calling gio_read_socket again, and it crashes
with a Segmentation fault.

My console output:
gio shutdown:
 gio_read_socket

(GtkLauncher:5402): GLib-CRITICAL **: g_io_channel_read_line:
assertion `channel-is_readable' failed

Program received signal SIGSEGV, Segmentation fault.
0x08048aa4 in gio_read_socket (gio=0x8590f50, condition=G_IO_IN, data=0x0)
at main.c:230
230 g_error (Error reading: %s\n, err-message);


static gboolean
gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer data)
{
printf ( gio_read_socket \n);
GIOStatus ret;
GError *err = NULL;
gchar *msg;
gsize len;

if (condition  G_IO_HUP){
  printf (Read end of pipe died!\n);
  return TRUE;
}

ret = g_io_channel_read_line (gio, msg, len, NULL, err);
if (ret == G_IO_STATUS_ERROR)
g_error (Error reading: %s\n, err-message);
else if (ret == G_IO_STATUS_EOF) {
printf (gio shutdown: \n);
g_io_channel_shutdown(gio, true, err);
} else {
printf (Read %u bytes: %s\n, len, msg);
g_free (msg);
}

return TRUE;
}

Thank you for any more help.


On Sun, Jan 24, 2010 at 2:47 AM, Chris Vine ch...@cvine.freeserve.co.uk wrote:
 On Sun, 24 Jan 2010 00:02:49 -0800
 silverburgh silverburgh.me...@gmail.com wrote:
 Hi,

 I create a GIOChannel which wraps around a socket on linux:

 GIOChannel* channel = g_io_channel_unix_new(sock);
 g_io_add_watch(channel, G_IO_IN,
                       gio_read_socket, NULL));
 g_io_add_watch(channel, G_IO_HUP,
                       gio_close_socket, NULL));

 And my function gio_read_socket() does get called whenever there is
 data available on the socket. And I am able to retrieve data using
 g_io_channel_read_line ().
 But when the other side of the socket get closed().  My function
 g_io_channel_read_line() get called infinite number of times with the
 number of data read = 0. Can you please tell me how can I fix my
 problem? And my function gio_close_socket() which registered for
 G_IO_HUP were never get called.

 static gboolean
 gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer
 data) {
        printf ( gio_read_socket \n);
         GIOStatus ret;
         GError *err = NULL;
         gchar *msg;
         gsize len;

         ret = g_io_channel_read_line (gio, msg, len, NULL, err);
         if (ret == G_IO_STATUS_ERROR)
                 g_error (Error reading: %s\n, err-message);

         printf (Read %u bytes: %s\n, len, msg);
         g_free (msg);
         // Try to close the socket when nothing is there.
         if (len == 0) {
               close(g_io_channel_unix_get_fd(gio));
             g_io_channel_close(gio);
         }

         return TRUE;
 }

 You need to check the return value of g_io_channel_read_line() for more
 than just an error - in particular for G_IO_STATUS_EOF.  You also should
 not normally have a separate callback for a G_IO_HUP condition because
 POLL_HUP is not of itself a reliable indicator of end of file.
 (Instead bitwise-or it with G_IO_IN for a single handler.)

 See this for further details:
 http://www.greenend.org.uk/rjk/2001/06/poll.html

 Actually, you have attempted to fix your problem in a different way,
 by closing the socket when the read data length is 0, assuming that you
 are doing blocking reads.  However, you need to free the GIOChannel
 object. The easiest way to do that is to call g_io_channel_unref() on
 the GIOChannel object immediately after you have called
 g_io_add_watch() on it. g_io_channel_*_new() returns a GIOChannel
 object with a reference count of one.  g_io_add_watch() adds a further
 reference count - if you decrement it by 1, the callback will be
 disconnected and the relevant GSource object removed when the callback
 returns FALSE, which it should do when it detects end-of-file, or if
 you call g_source_remove() on the return value of g_io_add_watch().
 (Incidentally, you are also supposed to use g_io_channel_shutdown()
 rather than g_io_channel_close(), but that of itself is not sufficient
 to free the GIOCondition object and it is not necessary anyway in this
 usage.)  I agree that the documentation on this isn't very good.

 Chris



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


How to use GIOChannel to read an Unix socket

2010-01-24 Thread silverburgh
Hi,

I create a GIOChannel which wraps around a socket on linux:

GIOChannel* channel = g_io_channel_unix_new(sock);
g_io_add_watch(channel, G_IO_IN,
gio_read_socket, NULL));
g_io_add_watch(channel, G_IO_HUP,
gio_close_socket, NULL));

And my function gio_read_socket() does get called whenever there is
data available on the socket. And I am able to retrieve data using
g_io_channel_read_line ().
But when the other side of the socket get closed().  My function
g_io_channel_read_line() get called infinite number of times with the
number of data read = 0. Can you please tell me how can I fix my
problem? And my function gio_close_socket() which registered for
G_IO_HUP were never get called.

static gboolean
gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer data)
{
   printf ( gio_read_socket \n);
GIOStatus ret;
GError *err = NULL;
gchar *msg;
gsize len;

ret = g_io_channel_read_line (gio, msg, len, NULL, err);
if (ret == G_IO_STATUS_ERROR)
g_error (Error reading: %s\n, err-message);

printf (Read %u bytes: %s\n, len, msg);
g_free (msg);
// Try to close the socket when nothing is there.
if (len == 0) {
  close(g_io_channel_unix_get_fd(gio));
  g_io_channel_close(gio);
}

return TRUE;
}

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


Re: How to use GIOChannel to read an Unix socket

2010-01-24 Thread Chris Vine
On Sun, 24 Jan 2010 00:02:49 -0800
silverburgh silverburgh.me...@gmail.com wrote:
 Hi,
 
 I create a GIOChannel which wraps around a socket on linux:
 
 GIOChannel* channel = g_io_channel_unix_new(sock);
 g_io_add_watch(channel, G_IO_IN,
   gio_read_socket, NULL));
 g_io_add_watch(channel, G_IO_HUP,
   gio_close_socket, NULL));
 
 And my function gio_read_socket() does get called whenever there is
 data available on the socket. And I am able to retrieve data using
 g_io_channel_read_line ().
 But when the other side of the socket get closed().  My function
 g_io_channel_read_line() get called infinite number of times with the
 number of data read = 0. Can you please tell me how can I fix my
 problem? And my function gio_close_socket() which registered for
 G_IO_HUP were never get called.
 
 static gboolean
 gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer
 data) {
printf ( gio_read_socket \n);
 GIOStatus ret;
 GError *err = NULL;
 gchar *msg;
 gsize len;
 
 ret = g_io_channel_read_line (gio, msg, len, NULL, err);
 if (ret == G_IO_STATUS_ERROR)
 g_error (Error reading: %s\n, err-message);
 
 printf (Read %u bytes: %s\n, len, msg);
 g_free (msg);
 // Try to close the socket when nothing is there.
 if (len == 0) {
   close(g_io_channel_unix_get_fd(gio));
 g_io_channel_close(gio);
 }
 
 return TRUE;
 }

You need to check the return value of g_io_channel_read_line() for more
than just an error - in particular for G_IO_STATUS_EOF.  You also should
not normally have a separate callback for a G_IO_HUP condition because
POLL_HUP is not of itself a reliable indicator of end of file.
(Instead bitwise-or it with G_IO_IN for a single handler.)

See this for further details:
http://www.greenend.org.uk/rjk/2001/06/poll.html

Actually, you have attempted to fix your problem in a different way,
by closing the socket when the read data length is 0, assuming that you
are doing blocking reads.  However, you need to free the GIOChannel
object. The easiest way to do that is to call g_io_channel_unref() on
the GIOChannel object immediately after you have called
g_io_add_watch() on it. g_io_channel_*_new() returns a GIOChannel
object with a reference count of one.  g_io_add_watch() adds a further
reference count - if you decrement it by 1, the callback will be
disconnected and the relevant GSource object removed when the callback
returns FALSE, which it should do when it detects end-of-file, or if
you call g_source_remove() on the return value of g_io_add_watch().
(Incidentally, you are also supposed to use g_io_channel_shutdown()
rather than g_io_channel_close(), but that of itself is not sufficient
to free the GIOCondition object and it is not necessary anyway in this
usage.)  I agree that the documentation on this isn't very good.

Chris


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