Move global libsrtp usage count into a singleton class
Avoids using webrtc::GlobalMutex. Since state is allocated on first
use and never destroyed, we avoid an exit-time destructor when
building with absl::Mutex.
Bug: webrtc:11567
Change-Id: Ib9c6480ab0474e37a853460115b35d961b93009c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/258080
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36455}
diff --git a/pc/BUILD.gn b/pc/BUILD.gn
index cb9d297..fc6950a 100644
--- a/pc/BUILD.gn
+++ b/pc/BUILD.gn
@@ -581,6 +581,7 @@
"../rtc_base",
"../rtc_base:checks",
"../rtc_base:logging",
+ "../rtc_base:macromagic",
"../rtc_base:rtc_base_approved",
"../rtc_base:stringutils",
"../rtc_base/synchronization:mutex",
diff --git a/pc/srtp_session.cc b/pc/srtp_session.cc
index d01bc38..7d1aaf2 100644
--- a/pc/srtp_session.cc
+++ b/pc/srtp_session.cc
@@ -27,6 +27,7 @@
#include "rtc_base/logging.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/string_encode.h"
+#include "rtc_base/thread_annotations.h"
#include "rtc_base/time_utils.h"
#include "system_wrappers/include/metrics.h"
#include "third_party/libsrtp/include/srtp.h"
@@ -34,6 +35,81 @@
namespace cricket {
+namespace {
+class LibSrtpInitializer {
+ public:
+ // Returns singleton instance of this class. Instance created on first use,
+ // and never destroyed.
+ static LibSrtpInitializer& Get() {
+ static LibSrtpInitializer* const instance = new LibSrtpInitializer();
+ return *instance;
+ }
+ void ProhibitLibsrtpInitialization();
+
+ // These methods are responsible for initializing libsrtp (if the usage count
+ // is incremented from 0 to 1) or deinitializing it (when decremented from 1
+ // to 0).
+ //
+ // Returns true if successful (will always be successful if already inited).
+ bool IncrementLibsrtpUsageCountAndMaybeInit(
+ srtp_event_handler_func_t* handler);
+ void DecrementLibsrtpUsageCountAndMaybeDeinit();
+
+ private:
+ LibSrtpInitializer() = default;
+
+ webrtc::Mutex mutex_;
+ int usage_count_ RTC_GUARDED_BY(mutex_) = 0;
+};
+
+void LibSrtpInitializer::ProhibitLibsrtpInitialization() {
+ webrtc::MutexLock lock(&mutex_);
+ ++usage_count_;
+}
+
+bool LibSrtpInitializer::IncrementLibsrtpUsageCountAndMaybeInit(
+ srtp_event_handler_func_t* handler) {
+ webrtc::MutexLock lock(&mutex_);
+
+ RTC_DCHECK_GE(usage_count_, 0);
+ if (usage_count_ == 0) {
+ int err;
+ err = srtp_init();
+ if (err != srtp_err_status_ok) {
+ RTC_LOG(LS_ERROR) << "Failed to init SRTP, err=" << err;
+ return false;
+ }
+
+ err = srtp_install_event_handler(handler);
+ if (err != srtp_err_status_ok) {
+ RTC_LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err;
+ return false;
+ }
+
+ err = external_crypto_init();
+ if (err != srtp_err_status_ok) {
+ RTC_LOG(LS_ERROR) << "Failed to initialize fake auth, err=" << err;
+ return false;
+ }
+ }
+ ++usage_count_;
+ return true;
+}
+
+void LibSrtpInitializer::DecrementLibsrtpUsageCountAndMaybeDeinit() {
+ webrtc::MutexLock lock(&mutex_);
+
+ RTC_DCHECK_GE(usage_count_, 1);
+ if (--usage_count_ == 0) {
+ int err = srtp_shutdown();
+ if (err) {
+ RTC_LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err;
+ }
+ }
+}
+
+} // namespace
+
using ::webrtc::ParseRtpSequenceNumber;
// One more than the maximum libsrtp error code. Required by
@@ -53,7 +129,7 @@
srtp_dealloc(session_);
}
if (inited_) {
- DecrementLibsrtpUsageCountAndMaybeDeinit();
+ LibSrtpInitializer::Get().DecrementLibsrtpUsageCountAndMaybeDeinit();
}
}
@@ -354,7 +430,8 @@
// This is the first time we need to actually interact with libsrtp, so
// initialize it if needed.
- if (IncrementLibsrtpUsageCountAndMaybeInit()) {
+ if (LibSrtpInitializer::Get().IncrementLibsrtpUsageCountAndMaybeInit(
+ &SrtpSession::HandleEventThunk)) {
inited_ = true;
} else {
return false;
@@ -377,54 +454,8 @@
return DoSetKey(type, cs, key, len, extension_ids);
}
-ABSL_CONST_INIT int g_libsrtp_usage_count = 0;
-ABSL_CONST_INIT webrtc::GlobalMutex g_libsrtp_lock(absl::kConstInit);
-
void ProhibitLibsrtpInitialization() {
- webrtc::GlobalMutexLock ls(&g_libsrtp_lock);
- ++g_libsrtp_usage_count;
-}
-
-// static
-bool SrtpSession::IncrementLibsrtpUsageCountAndMaybeInit() {
- webrtc::GlobalMutexLock ls(&g_libsrtp_lock);
-
- RTC_DCHECK_GE(g_libsrtp_usage_count, 0);
- if (g_libsrtp_usage_count == 0) {
- int err;
- err = srtp_init();
- if (err != srtp_err_status_ok) {
- RTC_LOG(LS_ERROR) << "Failed to init SRTP, err=" << err;
- return false;
- }
-
- err = srtp_install_event_handler(&SrtpSession::HandleEventThunk);
- if (err != srtp_err_status_ok) {
- RTC_LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err;
- return false;
- }
-
- err = external_crypto_init();
- if (err != srtp_err_status_ok) {
- RTC_LOG(LS_ERROR) << "Failed to initialize fake auth, err=" << err;
- return false;
- }
- }
- ++g_libsrtp_usage_count;
- return true;
-}
-
-// static
-void SrtpSession::DecrementLibsrtpUsageCountAndMaybeDeinit() {
- webrtc::GlobalMutexLock ls(&g_libsrtp_lock);
-
- RTC_DCHECK_GE(g_libsrtp_usage_count, 1);
- if (--g_libsrtp_usage_count == 0) {
- int err = srtp_shutdown();
- if (err) {
- RTC_LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err;
- }
- }
+ LibSrtpInitializer::Get().ProhibitLibsrtpInitialization();
}
void SrtpSession::HandleEvent(const srtp_event_data_t* ev) {
diff --git a/pc/srtp_session.h b/pc/srtp_session.h
index 1c61156..048e665 100644
--- a/pc/srtp_session.h
+++ b/pc/srtp_session.h
@@ -120,14 +120,6 @@
// for debugging.
void DumpPacket(const void* buf, int len, bool outbound);
- // These methods are responsible for initializing libsrtp (if the usage count
- // is incremented from 0 to 1) or deinitializing it (when decremented from 1
- // to 0).
- //
- // Returns true if successful (will always be successful if already inited).
- static bool IncrementLibsrtpUsageCountAndMaybeInit();
- static void DecrementLibsrtpUsageCountAndMaybeDeinit();
-
void HandleEvent(const srtp_event_data_t* ev);
static void HandleEventThunk(srtp_event_data_t* ev);
@@ -142,7 +134,6 @@
int rtcp_auth_tag_len_ = 0;
bool inited_ = false;
- static webrtc::GlobalMutex lock_;
int last_send_seq_num_ = -1;
bool external_auth_active_ = false;
bool external_auth_enabled_ = false;