Use single thread for usrsctp stack #2383
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Yesterday we noticed that the usrsctp stack always created, and bound to, two random UDP ports: one for IPv4 and one for IPv6. Digging in the code, we found out the cause was the
usrsctp_init(0, janus_sctp_data_to_dtls, NULL)
call: as part of the initialization process, the usrsctp stack creates a thread and binds to the provided port (random one, in our case, since we pass0
) in order to support SCTP over UDP encapsulation.Clearly we don't need that kind of encapsulation in Janus: actually, we don't want it at all! But apparently the only way to get rid of it is starting the usrsctp stack without its internal threads, which means driving it using an external loop. This is a feature that was added last year, thanks to the efforts by @jmillan and @ibc that revived an older contribution that had been discarded at the time. More specifically, when you initialize the usrsctp stack with
usrsctp_init_nothreads
instead ofusrsctp_init
, no threads are created in the stack, which means the UDP encapsulation stuff isn't created either. Of course, it also means as an application you're responsible for "running" the stack somehow, which in the context of usrsctp means running theusrsctp_handle_timers()
timer as part of your event loop.This patch tries to do exactly that, by adding support for this nothreads mode. By default we still behave as before (
usrsctp_init
called at startup), but if you setusrsctp_singlethread = true
in thegeneral
section ofjanus.jcfg
, we switch to the single thread mode instead: this means initializing the stack withusrsctp_init_nothreads
, and creating a dedicated thread insctp.c
to host a Glib context/loop that can then serve the regular source that will invokeusrsctp_handle_timers
(which we do every 10ms, at the moment, as José Luis and Iñaki did in mediasoup). I considered re-using one of the existing loops for that timer, like the main loop in the Janus core, but I don't have a clear understanding of the impact the usrsctp stack may have on loops yet, and so I thought it safer to have a dedicated thread instead.From a few simple tests this seems to be working, but this needs proper testing, especially with higher numbers and a higher datachannel traffic (which is why in this PR it's optional and disabled by default). Feedback welcome!