Skip to content
  • David Zeuthen's avatar
    Bug 626748 – Use async methods for writing and handle EAGAIN · 8a3a4596
    David Zeuthen authored
    If sending a lot of data and/or the other peer is not reading it, then
    socket buffers can overflow. This is communicated from the kernel by
    returning EAGAIN. In GIO, it is modelled by g_output_stream_write()
    and g_socket_send_message() returning G_IO_ERROR_WOULD_BLOCK.
    
    It is also problematic that that we're using synchronous IO in the
    shared GDBus IO thread. It means that one GDBusConnection can lock up
    others.
    
    It turns out that by porting from g_output_stream_write() to
    g_output_stream_write_async() we fix the EAGAIN issue. For GSocket, we
    still need to handle things manually (by creating a GSource) as
    g_socket_send_message() is used.
    
    We check the new behavior in Michael's producer/consumer test case (at
    /gdbus/overflow in gdbus-peer.c) added in the last commit.
    
    Also add a test case that sends and receives a 20 MiB message.
    
    Also add a new `transport' G_DBUS_DEBUG option so it is easy to
    inspect partial writes:
    
     $ G_DBUS_DEBUG=transport ./gdbus-connection -p /gdbus/connection/large_message
     [...]
     ========================================================================
     GDBus-debug:Transport:
       >>>> WROTE 128000 bytes of message with serial 4 and
            size 20971669 from offset 0 on a GSocketOutputStream
     ========================================================================
     GDBus-debug:Transport:
       >>>> WROTE 128000 bytes of message with serial 4 and
            size 20971669 from offset 128000 on a GSocketOutputStream
     ========================================================================
     GDBus-debug:Transport:
       >>>> WROTE 128000 bytes of message with serial 4 and
            size 20971669 from offset 256000 on a GSocketOutputStream
     [...]
     ========================================================================
     GDBus-debug:Transport:
       >>>> WROTE 43669 bytes of message with serial 4 and
            size 20971669 from offset 20928000 on a GSocketOutputStream
     [...]
     ========================================================================
     GDBus-debug:Transport:
       <<<< READ 16 bytes of message with serial 3 and
            size 20971620 to offset 0 from a GSocketInputStream
     ========================================================================
     GDBus-debug:Transport:
       <<<< READ 15984 bytes of message with serial 3 and
            size 20971620 to offset 16 from a GSocketInputStream
     ========================================================================
     GDBus-debug:Transport:
       <<<< READ 16000 bytes of message with serial 3 and
            size 20971620 to offset 16000 from a GSocketInputStream
     [...]
     ========================================================================
     GDBus-debug:Transport:
       <<<< READ 144000 bytes of message with serial 3 and
            size 20971620 to offset 20720000 from a GSocketInputStream
     ========================================================================
     GDBus-debug:Transport:
       <<<< READ 107620 bytes of message with serial 3 and
            size 20971620 to offset 20864000 from a GSocketInputStream
     OK
    
    https://bugzilla.gnome.org/show_bug.cgi?id=626748
    
    
    
    Signed-off-by: default avatarDavid Zeuthen <davidz@redhat.com>
    8a3a4596