Browse Source

Merge pull request #808 from paullouisageneau/nice-global-mainloop

libnice: Use a single global thread for ICE transport
Paul-Louis Ageneau 2 years ago
parent
commit
f5af5aa4f5
3 changed files with 46 additions and 20 deletions
  1. 37 17
      src/impl/icetransport.cpp
  2. 7 3
      src/impl/icetransport.hpp
  3. 2 0
      src/impl/init.cpp

+ 37 - 17
src/impl/icetransport.cpp

@@ -37,6 +37,14 @@ namespace rtc::impl {
 
 
 const int MAX_TURN_SERVERS_COUNT = 2;
 const int MAX_TURN_SERVERS_COUNT = 2;
 
 
+void IceTransport::Init() {
+	// Dummy
+}
+
+void IceTransport::Cleanup() {
+	// Dummy
+}
+
 IceTransport::IceTransport(const Configuration &config, candidate_callback candidateCallback,
 IceTransport::IceTransport(const Configuration &config, candidate_callback candidateCallback,
                            state_callback stateChangeCallback,
                            state_callback stateChangeCallback,
                            gathering_state_callback gatheringStateChangeCallback)
                            gathering_state_callback gatheringStateChangeCallback)
@@ -356,6 +364,29 @@ void IceTransport::LogCallback(juice_log_level_t level, const char *message) {
 
 
 #else // USE_NICE == 1
 #else // USE_NICE == 1
 
 
+unique_ptr<GMainLoop, void (*)(GMainLoop *)> IceTransport::MainLoop(nullptr, nullptr);
+std::thread IceTransport::MainLoopThread;
+
+void IceTransport::Init() {
+	g_log_set_handler("libnice", G_LOG_LEVEL_MASK, LogCallback, nullptr);
+
+	IF_PLOG(plog::verbose) {
+		nice_debug_enable(false); // do not output STUN debug messages
+	}
+
+	MainLoop = decltype(MainLoop)(g_main_loop_new(nullptr, FALSE), g_main_loop_unref);
+	if (!MainLoop)
+		throw std::runtime_error("Failed to create the main loop");
+
+	MainLoopThread = std::thread(g_main_loop_run, MainLoop.get());
+}
+
+void IceTransport::Cleanup() {
+	g_main_loop_quit(MainLoop.get());
+	MainLoopThread.join();
+	MainLoop.reset();
+}
+
 static void closeNiceAgentCallback(GObject *niceAgent, GAsyncResult *, gpointer) {
 static void closeNiceAgentCallback(GObject *niceAgent, GAsyncResult *, gpointer) {
 	g_object_unref(niceAgent);
 	g_object_unref(niceAgent);
 }
 }
@@ -372,19 +403,12 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
       mMid("0"), mGatheringState(GatheringState::New),
       mMid("0"), mGatheringState(GatheringState::New),
       mCandidateCallback(std::move(candidateCallback)),
       mCandidateCallback(std::move(candidateCallback)),
       mGatheringStateChangeCallback(std::move(gatheringStateChangeCallback)),
       mGatheringStateChangeCallback(std::move(gatheringStateChangeCallback)),
-      mNiceAgent(nullptr, nullptr), mMainLoop(nullptr, nullptr), mOutgoingDscp(0) {
+      mNiceAgent(nullptr, nullptr), mOutgoingDscp(0) {
 
 
 	PLOG_DEBUG << "Initializing ICE transport (libnice)";
 	PLOG_DEBUG << "Initializing ICE transport (libnice)";
 
 
-	g_log_set_handler("libnice", G_LOG_LEVEL_MASK, LogCallback, this);
-
-	IF_PLOG(plog::verbose) {
-		nice_debug_enable(false); // do not output STUN debug messages
-	}
-
-	mMainLoop = decltype(mMainLoop)(g_main_loop_new(nullptr, FALSE), g_main_loop_unref);
-	if (!mMainLoop)
-		std::runtime_error("Failed to create the main loop");
+	if(!MainLoop)
+		throw std::logic_error("Main loop for nice agent is not created");
 
 
 	// RFC 8445: The nomination process that was referred to as "aggressive nomination" in RFC 5245
 	// RFC 8445: The nomination process that was referred to as "aggressive nomination" in RFC 5245
 	// has been deprecated in this specification.
 	// has been deprecated in this specification.
@@ -395,7 +419,7 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
 	// Create agent
 	// Create agent
 	mNiceAgent = decltype(mNiceAgent)(
 	mNiceAgent = decltype(mNiceAgent)(
 	    nice_agent_new_full(
 	    nice_agent_new_full(
-	        g_main_loop_get_context(mMainLoop.get()),
+	        g_main_loop_get_context(MainLoop.get()),
 	        NICE_COMPATIBILITY_RFC5245, // RFC 5245 was obsoleted by RFC 8445 but this should be OK
 	        NICE_COMPATIBILITY_RFC5245, // RFC 5245 was obsoleted by RFC 8445 but this should be OK
 	        flags),
 	        flags),
 	    closeNiceAgent);
 	    closeNiceAgent);
@@ -403,8 +427,6 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
 	if (!mNiceAgent)
 	if (!mNiceAgent)
 		throw std::runtime_error("Failed to create the nice agent");
 		throw std::runtime_error("Failed to create the nice agent");
 
 
-	mMainLoopThread = std::thread(g_main_loop_run, mMainLoop.get());
-
 	mStreamId = nice_agent_add_stream(mNiceAgent.get(), 1);
 	mStreamId = nice_agent_add_stream(mNiceAgent.get(), 1);
 	if (!mStreamId)
 	if (!mStreamId)
 		throw std::runtime_error("Failed to add a stream");
 		throw std::runtime_error("Failed to add a stream");
@@ -576,7 +598,7 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
 	nice_agent_set_port_range(mNiceAgent.get(), mStreamId, 1, config.portRangeBegin,
 	nice_agent_set_port_range(mNiceAgent.get(), mStreamId, 1, config.portRangeBegin,
 	                          config.portRangeEnd);
 	                          config.portRangeEnd);
 
 
-	nice_agent_attach_recv(mNiceAgent.get(), mStreamId, 1, g_main_loop_get_context(mMainLoop.get()),
+	nice_agent_attach_recv(mNiceAgent.get(), mStreamId, 1, g_main_loop_get_context(MainLoop.get()),
 	                       RecvCallback, this);
 	                       RecvCallback, this);
 }
 }
 
 
@@ -587,11 +609,9 @@ IceTransport::~IceTransport() {
 	}
 	}
 
 
 	PLOG_DEBUG << "Destroying ICE transport";
 	PLOG_DEBUG << "Destroying ICE transport";
-	nice_agent_attach_recv(mNiceAgent.get(), mStreamId, 1, g_main_loop_get_context(mMainLoop.get()),
+	nice_agent_attach_recv(mNiceAgent.get(), mStreamId, 1, g_main_loop_get_context(MainLoop.get()),
 	                       NULL, NULL);
 	                       NULL, NULL);
 	nice_agent_remove_stream(mNiceAgent.get(), mStreamId);
 	nice_agent_remove_stream(mNiceAgent.get(), mStreamId);
-	g_main_loop_quit(mMainLoop.get());
-	mMainLoopThread.join();
 	mNiceAgent.reset();
 	mNiceAgent.reset();
 }
 }
 
 

+ 7 - 3
src/impl/icetransport.hpp

@@ -32,6 +32,9 @@ namespace rtc::impl {
 
 
 class IceTransport : public Transport {
 class IceTransport : public Transport {
 public:
 public:
+	static void Init();
+	static void Cleanup();
+
 	enum class GatheringState { New = 0, InProgress = 1, Complete = 2 };
 	enum class GatheringState { New = 0, InProgress = 1, Complete = 2 };
 
 
 	using candidate_callback = std::function<void(const Candidate &candidate)>;
 	using candidate_callback = std::function<void(const Candidate &candidate)>;
@@ -83,10 +86,11 @@ private:
 	static void RecvCallback(juice_agent_t *agent, const char *data, size_t size, void *user_ptr);
 	static void RecvCallback(juice_agent_t *agent, const char *data, size_t size, void *user_ptr);
 	static void LogCallback(juice_log_level_t level, const char *message);
 	static void LogCallback(juice_log_level_t level, const char *message);
 #else
 #else
-	uint32_t mStreamId = 0;
+	static unique_ptr<GMainLoop, void (*)(GMainLoop *)> MainLoop;
+	static std::thread MainLoopThread;
+
 	unique_ptr<NiceAgent, void (*)(NiceAgent *)> mNiceAgent;
 	unique_ptr<NiceAgent, void (*)(NiceAgent *)> mNiceAgent;
-	unique_ptr<GMainLoop, void (*)(GMainLoop *)> mMainLoop;
-	std::thread mMainLoopThread;
+	uint32_t mStreamId = 0;
 	guint mTimeoutId = 0;
 	guint mTimeoutId = 0;
 	std::mutex mOutgoingMutex;
 	std::mutex mOutgoingMutex;
 	unsigned int mOutgoingDscp;
 	unsigned int mOutgoingDscp;

+ 2 - 0
src/impl/init.cpp

@@ -141,6 +141,7 @@ void Init::doInit() {
 #if RTC_ENABLE_MEDIA
 #if RTC_ENABLE_MEDIA
 	DtlsSrtpTransport::Init();
 	DtlsSrtpTransport::Init();
 #endif
 #endif
+	IceTransport::Init();
 }
 }
 
 
 void Init::doCleanup() {
 void Init::doCleanup() {
@@ -167,6 +168,7 @@ void Init::doCleanup() {
 #if RTC_ENABLE_MEDIA
 #if RTC_ENABLE_MEDIA
 	DtlsSrtpTransport::Cleanup();
 	DtlsSrtpTransport::Cleanup();
 #endif
 #endif
+	IceTransport::Cleanup();
 
 
 #ifdef _WIN32
 #ifdef _WIN32
 	WSACleanup();
 	WSACleanup();