[Pkg-telepathy-commits] [libnice] 104/265: outputstream: Don't wake up on every input buffer

Simon McVittie smcv at debian.org
Wed May 14 12:04:57 UTC 2014


This is an automated email from the git hooks/post-receive script.

smcv pushed a commit to branch debian
in repository libnice.

commit b5f79391b7ed90e99bb38d667b06b87cfd623f74
Author: Olivier Crête <olivier.crete at collabora.com>
Date:   Fri Jan 24 00:52:01 2014 -0500

    outputstream: Don't wake up on every input buffer
    
    So instead of actually blocking on the FD, block on a GCancellable
    which is triggered when the writable callback is called. Also set the
    application's GCancellable as a child of this source.
---
 agent/agent.c        | 14 ++++++++++++--
 agent/component.c    |  4 ++--
 agent/component.h    |  1 +
 agent/outputstream.c | 30 ++++++++++++++++++++----------
 4 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/agent/agent.c b/agent/agent.c
index 0325a6b..b925505 100644
--- a/agent/agent.c
+++ b/agent/agent.c
@@ -987,13 +987,17 @@ nice_agent_set_property (
 static void priv_pseudo_tcp_error (NiceAgent *agent, Stream *stream,
     Component *component)
 {
+  if (component->tcp_writable_cancellable) {
+    g_cancellable_reset (component->tcp_writable_cancellable);
+    g_clear_object (&component->tcp_writable_cancellable);
+  }
+
   if (component->tcp) {
     agent_signal_component_state_change (agent, stream->id,
         component->id, NICE_COMPONENT_STATE_FAILED);
     component_detach_all_sockets (component);
     pseudo_tcp_socket_close (component->tcp, TRUE);
-    g_object_unref (component->tcp);
-    component->tcp = NULL;
+    g_clear_object (&component->tcp);
   }
 
   if (component->tcp_clock) {
@@ -1016,6 +1020,7 @@ pseudo_tcp_socket_opened (PseudoTcpSocket *sock, gpointer user_data)
 
   nice_debug ("Agent %p: s%d:%d pseudo Tcp socket Opened", agent,
       stream->id, component->id);
+  g_cancellable_cancel (component->tcp_writable_cancellable);
   g_signal_emit (agent, signals[SIGNAL_RELIABLE_TRANSPORT_WRITABLE], 0,
       stream->id, component->id);
 }
@@ -1113,6 +1118,7 @@ pseudo_tcp_socket_writable (PseudoTcpSocket *sock, gpointer user_data)
 
   nice_debug ("Agent %p: s%d:%d pseudo Tcp socket writable", agent,
       stream->id, component->id);
+  g_cancellable_cancel (component->tcp_writable_cancellable);
   g_signal_emit (agent, signals[SIGNAL_RELIABLE_TRANSPORT_WRITABLE], 0,
       stream->id, component->id);
 }
@@ -1627,6 +1633,7 @@ nice_agent_add_stream (
                                             pseudo_tcp_socket_closed,
                                             pseudo_tcp_socket_write_packet};
         component->tcp = pseudo_tcp_socket_new (0, &tcp_callbacks);
+        component->tcp_writable_cancellable = g_cancellable_new ();
         adjust_tcp_clock (agent, stream, component);
         nice_debug ("Agent %p: Create Pseudo Tcp Socket for component %d",
             agent, i+1);
@@ -2904,6 +2911,9 @@ nice_agent_send_full (
     ret = pseudo_tcp_socket_send (component->tcp, (const gchar *) buf, buf_len);
     adjust_tcp_clock (agent, stream, component);
 
+    if (!pseudo_tcp_socket_can_send (component->tcp))
+      g_cancellable_reset (component->tcp_writable_cancellable);
+
     /* In case of -1, the error is either EWOULDBLOCK or ENOTCONN, which both
        need the user to wait for the reliable-transport-writable signal */
     if (ret < 0 &&
diff --git a/agent/component.c b/agent/component.c
index 63a029e..c923a6a 100644
--- a/agent/component.c
+++ b/agent/component.c
@@ -188,10 +188,10 @@ component_free (Component *cmp)
     g_source_unref (cmp->tcp_clock);
     cmp->tcp_clock = NULL;
   }
+  g_clear_object (&cmp->tcp_writable_cancellable);
   if (cmp->tcp) {
     pseudo_tcp_socket_close (cmp->tcp, TRUE);
-    g_object_unref (cmp->tcp);
-    cmp->tcp = NULL;
+    g_clear_object(&cmp->tcp);
   }
 
   while ((data = g_queue_pop_head (&cmp->pending_io_messages)) != NULL)
diff --git a/agent/component.h b/agent/component.h
index fedb23c..6873eeb 100644
--- a/agent/component.h
+++ b/agent/component.h
@@ -186,6 +186,7 @@ struct _Component
   GSource* tcp_clock;
   long last_clock_timeout;
   gboolean tcp_readable;
+  GCancellable *tcp_writable_cancellable;
 
   guint min_port;
   guint max_port;
diff --git a/agent/outputstream.c b/agent/outputstream.c
index 9994b66..558cc64 100644
--- a/agent/outputstream.c
+++ b/agent/outputstream.c
@@ -558,14 +558,24 @@ nice_output_stream_create_source (GPollableOutputStream *stream,
   Stream *_stream = NULL;
   NiceAgent *agent;  /* owned */
 
+  component_source = g_pollable_source_new (G_OBJECT (stream));
+
+  if (cancellable) {
+    GSource *cancellable_source = g_cancellable_source_new (cancellable);
+
+    g_source_set_dummy_callback (cancellable_source);
+    g_source_add_child_source (component_source, cancellable_source);
+    g_source_unref (cancellable_source);
+  }
+
   /* Closed streams cannot have sources. */
   if (g_output_stream_is_closed (G_OUTPUT_STREAM (stream)))
-    return g_pollable_source_new (G_OBJECT (stream));  /* dummy */
+    return component_source;
 
   /* Has the agent disappeared? */
   agent = g_weak_ref_get (&priv->agent_ref);
   if (agent == NULL)
-    return g_pollable_source_new (G_OBJECT (stream));  /* dummy */
+    return component_source;
 
   agent_lock ();
 
@@ -574,17 +584,17 @@ nice_output_stream_create_source (GPollableOutputStream *stream,
           &_stream, &component)) {
     g_warning ("Could not find component %u in stream %u", priv->component_id,
         priv->stream_id);
-    component_source = g_pollable_source_new (G_OBJECT (stream));  /* dummy */
     goto done;
   }
 
-  /* Note: We need G_IO_IN here to handle pseudo-TCP streams. If our TCP
-   * transmit buffer is full, but the kernel's receive buffer has pending ACKs
-   * sitting in it, we need to receive those ACKs so we can transmit the head
-   * bytes in the transmit buffer, and hence free up space in the tail of the
-   * buffer so the stream is writeable again. */
-  component_source = component_source_new (component, G_OBJECT (stream),
-      G_IO_IN | G_IO_OUT, cancellable);
+   if (component->tcp_writable_cancellable) {
+    GSource *cancellable_source =
+        g_cancellable_source_new (component->tcp_writable_cancellable);
+
+    g_source_set_dummy_callback (cancellable_source);
+    g_source_add_child_source (component_source, cancellable_source);
+    g_source_unref (cancellable_source);
+  }
 
 done:
   agent_unlock ();

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-telepathy/libnice.git



More information about the Pkg-telepathy-commits mailing list