123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- /**
- * Copyright (c) 2020 Paul-Louis Ageneau
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #include "init.hpp"
- #include "globals.hpp"
- #include "impl/certificate.hpp"
- #include "impl/dtlstransport.hpp"
- #include "impl/sctptransport.hpp"
- #include "impl/threadpool.hpp"
- #include "impl/tls.hpp"
- #if RTC_ENABLE_WEBSOCKET
- #include "impl/tlstransport.hpp"
- #endif
- #if RTC_ENABLE_MEDIA
- #include "impl/dtlssrtptransport.hpp"
- #endif
- #ifdef _WIN32
- #include <winsock2.h>
- #endif
- namespace rtc {
- namespace {
- void doInit() {
- PLOG_DEBUG << "Global initialization";
- #ifdef _WIN32
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2, 2), &wsaData))
- throw std::runtime_error("WSAStartup failed, error=" + std::to_string(WSAGetLastError()));
- #endif
- impl::ThreadPool::Instance().spawn(THREADPOOL_SIZE);
- #if USE_GNUTLS
- // Nothing to do
- #else
- openssl::init();
- #endif
- impl::SctpTransport::Init();
- impl::DtlsTransport::Init();
- #if RTC_ENABLE_WEBSOCKET
- impl::TlsTransport::Init();
- #endif
- #if RTC_ENABLE_MEDIA
- impl::DtlsSrtpTransport::Init();
- #endif
- }
- void doCleanup() {
- PLOG_DEBUG << "Global cleanup";
- impl::ThreadPool::Instance().join();
- impl::CleanupCertificateCache();
- impl::SctpTransport::Cleanup();
- impl::DtlsTransport::Cleanup();
- #if RTC_ENABLE_WEBSOCKET
- impl::TlsTransport::Cleanup();
- #endif
- #if RTC_ENABLE_MEDIA
- impl::DtlsSrtpTransport::Cleanup();
- #endif
- #ifdef _WIN32
- WSACleanup();
- #endif
- }
- } // namespace
- weak_ptr<void> Init::Weak;
- shared_ptr<void> *Init::Global = nullptr;
- bool Init::Initialized = false;
- std::recursive_mutex Init::Mutex;
- init_token Init::Token() {
- std::unique_lock lock(Mutex);
- if (auto token = Weak.lock())
- return token;
- delete Global;
- Global = new shared_ptr<void>(new Init());
- Weak = *Global;
- return *Global;
- }
- void Init::Preload() {
- std::unique_lock lock(Mutex);
- auto token = Token();
- if (!Global)
- Global = new shared_ptr<void>(token);
- PLOG_DEBUG << "Preloading certificate";
- impl::make_certificate().wait();
- }
- void Init::Cleanup() {
- std::unique_lock lock(Mutex);
- delete Global;
- Global = nullptr;
- }
- Init::Init() {
- // Mutex is locked by Token() here
- if (!std::exchange(Initialized, true))
- doInit();
- }
- Init::~Init() {
- std::thread t([]() {
- // We need to lock Mutex ourselves
- std::unique_lock lock(Mutex);
- if (Global)
- return;
- if (std::exchange(Initialized, false))
- doCleanup();
- });
- t.detach();
- }
- } // namespace rtc
|