Re: IO Channel Flush - Assertion Failure



Thanks for hint.

In my case io_write() is the function g_io_unix_write() from giounix.c:

----- snip -----

static GIOStatus
g_io_unix_write (GIOChannel  *channel, 
		 const gchar *buf, 
		 gsize       count,
		 gsize      *bytes_written,
		 GError    **err)
{
  GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
  gssize result;

 retry:
  result = write (unix_channel->fd, buf, count);

  if (result < 0)
    {
      *bytes_written = 0;

      switch (errno)
        {
#ifdef EINTR
          case EINTR:
            goto retry;
#endif
#ifdef EAGAIN
          case EAGAIN:
            return G_IO_STATUS_AGAIN;
#endif
          default:
            g_set_error (err, G_IO_CHANNEL_ERROR,
                         g_io_channel_error_from_errno (errno),
                         g_strerror (errno));
            return G_IO_STATUS_ERROR;
        }
    }

  *bytes_written = result;

  return G_IO_STATUS_NORMAL;
}

--------- snip ----------
(this code is from svn-trunk)

The function above has no special handling for the case that write()
returns 0. It regards this situation as G_IO_STATUS_NORMAL. However,
g_io_channel_flush() has a different opinion about that - see
g_assert(this_time > 0).
So one of these functions should change its philosophy!

The write()-manpage does not clearly mention what it means if write()
returns 0. In my understanding, if writing data is not possible, it
returns -1 and sets errno to EINTR or EAGAIN .. but maybe this is wrong
and write() returns 0 when there is a EINTR or EAGAIN situation.

I guess this problem should be filed as a bug. Please confirm ..

Christian

On Tue, 2007-12-18 at 09:56 -0800, Peter Long wrote:
> The assert only happens if io_write returns a successful status code AND the total bytes_written are less that the bytes in the buffer. So io_write() wrote nothing while there was data to write but did not report an error. That does sound like a bug to me. I bet the bug is in io_write(). It should return an error status if it could not write any more data.
> 
> Peter Long
> 
> ----- Original Message ----
> From: Christian Bünnig <masala web de>
> To: "gtk-list gnome org" <gtk-list gnome org>
> Sent: Tuesday, December 18, 2007 11:52:57 AM
> Subject: IO Channel Flush - Assertion Failure
> 
> 
> Hi,
> 
> for data communication between 2 Bluetooth devices I have created IO
> channels on the corresponding sockets. This works well the most time.
> However, sometimes (I could not determine the exact occurrence yet)
> flushing the channel with g_io_channel_flush() fails in that it raises
> an assertion error. The failure happens in the line
>   g_assert (this_time > 0);
> in the function below (from giochannel.c)
> 
> ------ snip -------
> 
> GIOStatus
> g_io_channel_flush (GIOChannel *channel, GError **error)
> {
>   GIOStatus status;
>   gsize this_time = 1, bytes_written = 0;
> 
>   g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
>   g_return_val_if_fail ((error == NULL) || (*error == NULL),  
>                         G_IO_STATUS_ERROR);
> 
>   if (channel->write_buf == NULL || channel->write_buf->len == 0)
>     return G_IO_STATUS_NORMAL;
> 
>   do
>     {
>       g_assert (this_time > 0); /// THIS ASSERTION FAILS ///
> 
>       status = channel->funcs->io_write(channel,
>                                 channel->write_buf->str +
>  bytes_written,
>                                 channel->write_buf->len -
>  bytes_written,
>                                 &this_time, error);
>       bytes_written += this_time;
>     }
>   while ((bytes_written < channel->write_buf->len)
>          && (status == G_IO_STATUS_NORMAL));
> 
>   g_string_erase (channel->write_buf, 0, bytes_written);
> 
>   return status;
> }
> 
> ------- snip --------
> 
> Afaik. assertions are used to detect bugs .. why is it considered as a
> bug if channel->funcs->io_write() writes no data (this_time == 0)? And
> who is responsible for that assertion failure?
> 
> Thanks for some advice,
> 
> Christian
> 
> _______________________________________________
> gtk-list mailing list
> gtk-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtk-list
> 
> 
> 



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