1. 15 Apr, 2014 1 commit
    • Philip Withnall's avatar
      agent: Fix GSource dispatches for UDP NiceOutputStreams · 479c2ee3
      Philip Withnall authored
      The GSource created by g_pollable_output_stream_create_source() on a
      NiceOutputStream would never have been dispatched, due to not having any
      poll events (or anything else); it only works for TCP streams because of
      a GCancellable child source which is triggered by the TCP code.
      Fix that by making ComponentSource suitable for G_IO_IN and G_IO_OUT
      again, and adding that as a child source for UDP output stream GSources.
  2. 25 Feb, 2014 2 commits
  3. 31 Jan, 2014 14 commits
    • Olivier Crête's avatar
      agent: Replace nice_agent_build_io_stream() with nice_agent_get_io_stream() · 430e8db5
      Olivier Crête authored
      Also made the GIOStream into a singleton, it always returns the same one.
      Also make it impossible to create a GIOStream for a non-existing stream/component
    • Philip Withnall's avatar
      agent: Add support for vectored I/O for receives · 253be348
      Philip Withnall authored
      Add two new public functions:
       • nice_agent_recv_messages()
       • nice_agent_recv_messages_nonblocking()
      which allow receiving multiple messages in a single call, and support
      vectors of buffers to receive the messages into.
      The existing nice_agent_recv[_nonblocking]() APIs have been left
      This tidies up a lot of the message handling code internally, and
      eliminates a couple of memcpy()s. There are still a few more memcpy()s
      on the critical path, which could be eliminated with further work.
      In the reliable agent case, every message is memcpy()ed twice: once into
      the pseudo-TCP receive buffer, and once out of it. The copy on input
      could be eliminated (in the case of in-order delivery of packets) by
      receiving directly into the receive buffer. The copy on output can’t be
      eliminated except in the I/O callback case (when
      nice_agent_attach_recv() has been used), in which case the callback
      could be invoked with a pointer directly into the pseudo-TCP receive
      In the non-reliable agent case, zero memcpy()s are used.
      A couple of the more complex socket implementations (TURN and HTTP) have
      slow paths during setup, and partially also during normal use. These
      could be optimised further, and FIXME comments have been added.
    • Olivier Crête's avatar
      inputstream: Make the GSource hold a weak ref on the agent · ebb787e2
      Olivier Crête authored
      This also means that it can't have the component ref. Also make the
      cancellable a child source of this GPollableInputStream one
    • Olivier Crête's avatar
      outputstream: Don't wake up on every input buffer · b5f79391
      Olivier Crête authored
      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.
    • Olivier Crête's avatar
      agent: Only change pseudotcp clock if the new timeout is sooner · 83bcf954
      Olivier Crête authored
      Destroying and creating GSources is expensive, so also don't destroy and
      re-create if possible, instead lets use the new g_source_set_ready_time()
    • Philip Withnall's avatar
      agent: Queue incoming pseudo-TCP messages until ACKs can be sent · 18e2e3a2
      Philip Withnall authored
      If pseudo-TCP messages are received before a socket has been selected
      from all the STUN candidates, they would previously be immediately
      passed to the pseudo-TCP state machine, which would attempt to send ACKs
      for them. This would fail (due to a lack of an outbound UDP socket), and
      would incur a retransmit timeout in the TCP state machine. This slowed
      down the tests enormously if one agent in a test completed candidate
      selection before the other (which is an entirely reasonable scenario).
      This never occurred before because the existing tests artificially run
      both agents in lock-step, and never send data packets from one to the
      other until both have completed candidate selection. This is basically
      Fix the problem by queuing incoming pseudo-TCP messages until an
      outbound UDP socket is available to send the ACKs or SYNACKs on.
    • Philip Withnall's avatar
      agent: Add a ComponentSource to Component · 3724af1a
      Philip Withnall authored
      This is a type of GSource which proxies all poll events from the sockets
      in a Component. It’s necessary for the implementation of
      GPollableInputStream and GPollableOutputStream.
      This adds no new external API, but does add ComponentSource and
      component_source_new() as new internal API.
    • Philip Withnall's avatar
      agent: Add nice_agent_recv() allowing blocking receives on sockets · 243c47ec
      Philip Withnall authored
      This is a blocking receive function, designed to be called from a worker
      thread. It cannot be used in conjunction with the existing
      nice_agent_attach_recv() API, as the blocking receive and the GSource
      would compete over access to the single copy of the data in the kernel’s
      receive buffer.
    • Philip Withnall's avatar
      agent: Move GSource handling into Component · c5672702
      Philip Withnall authored
      Rather than handle GSource creation, attachment and removal in
      NiceAgent, handle it inside Component. This brings it closer to the
      networking code, and improves encapsulation of the state of each
    • Philip Withnall's avatar
      agent: Support invoking I/O callbacks in non-default contexts · 2b6370a8
      Philip Withnall authored
      If the Component’s I/O receiver machinery is invoked from a thread which
      can’t acquire the main context specified for the I/O callbacks, the
      callbacks need to be queued as idle handlers in that main context.
      This is needed for the case where blocking reads are being performed in
      one thread, with their callbacks needing to be delivered in another
      This introduces a new fine-grained lock to Component: io_mutex. This
      protects accesses to Component->io_callback, Component->io_user_data and
      Component->pending_io_callbacks. If being locked at the same time as the
      main agent lock, it must always be locked afterwards, but the agent lock
      does not *have* to be held in order to lock io_mutex.
    • Philip Withnall's avatar
    • Philip Withnall's avatar
      agent: Integrate TcpUserData into Component · 68a9632e
      Philip Withnall authored
      It was allocated separately and always set, which is a wasted
      allocation. Instead, pull the NiceAgent and Stream pointers into the
      Component directly, and eliminate the redundant allocation.
      This also means the NiceAgent and Stream are available for use elsewhere
      in the Component code (not just with TCP stuff).
    • Philip Withnall's avatar
      agent: Move I/O callback handling from NiceAgent into Component · 6fe29601
      Philip Withnall authored
      Compartmentalise the handling of setting and clearing the user-provided
      per-Component I/O callbacks.
      Data flows from the socket, through nice_agent_g_source_cb(), to
      component_emit_io_callback() which calls the callback provided by the
      user when originally attaching to the stream/component.
    • Philip Withnall's avatar
      agent: Move socket/source handling from NiceAgent into Component · 790974e0
      Philip Withnall authored
      This compartmentalises it a little more, reducing the spread of
      state-changing code from three files down to one.
      The key change is the switch from using two GSLists of NiceSockets and
      GSources in Component, to using a single GSList of a struct {
      NiceSocket, GSource }. This is possible because there is at most one
      GSource per NiceSocket. This change reduces memory overhead (from the
      GSList structures) slightly, and makes the relationship between sockets
      and sources much clearer.
  4. 19 Jan, 2011 1 commit
  5. 16 Feb, 2010 4 commits
  6. 30 Jun, 2009 1 commit
  7. 09 Mar, 2009 1 commit
  8. 04 Mar, 2009 2 commits
  9. 04 Nov, 2008 1 commit
  10. 28 Oct, 2008 1 commit
  11. 22 Oct, 2008 1 commit
  12. 07 Oct, 2008 2 commits
  13. 24 Sep, 2008 1 commit
  14. 10 Sep, 2008 1 commit
  15. 07 Aug, 2008 1 commit
  16. 30 Jul, 2008 1 commit
  17. 26 Apr, 2008 2 commits
  18. 22 Apr, 2008 1 commit
  19. 11 Mar, 2008 1 commit
  20. 26 Nov, 2007 1 commit