Currently, there’s a nice race in component_close(), between pseudo_tcp_socket_close() (which sends the first packet in the TCP FIN handshake), and freeing all the agent’s candidates (and hence closing their underlying sockets).
The only way to reliably fix that is to make pseudo_tcp_socket_close() block on completing the handshake, or timing out. But blocking for that long would be terrible, so the solution also has to involve making component_close() and all of its callers, all the way up to nice_agent_remove_stream(), asynchronous, a la g_io_stream_close_async().
See the mailing list thread: http://lists.freedesktop.org/archives/nice/2014-October/000979.html
And the FIXME commit: http://cgit.freedesktop.org/libnice/libnice/commit/?id=88cd37a4ffbe4bc623eda2c0ac01565d467976f3
I guess this doesn't happen if one uses g_io_stream_close_async() ?
(In reply to Olivier Crête from comment #1)
> I guess this doesn't happen if one uses g_io_stream_close_async() ?
Nope, it will also happen then (well, the race is still technically present). I don’t know how easy it is to trigger on that code path.
This is all because pseudo_tcp_socket_[close|shutdown]() are non-blocking and sync.
Migrated to Phabricator: http://phabricator.freedesktop.org/T110