diff --git a/CMakeLists.txt b/CMakeLists.txt index 25ed3a7..0b199ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.7) project(libdatachannel - VERSION 0.13.1 + VERSION 0.13.2 LANGUAGES CXX) set(PROJECT_DESCRIPTION "WebRTC Data Channels Library") diff --git a/src/candidate.cpp b/src/candidate.cpp index c856aa4..3236375 100644 --- a/src/candidate.cpp +++ b/src/candidate.cpp @@ -93,7 +93,7 @@ void Candidate::parse(string candidate) { {"so", TransportType::TcpSo}}; const std::array prefixes{"a=", "candidate:"}; - for (const string &prefix : prefixes) + for (string prefix : prefixes) if (match_prefix(candidate, prefix)) candidate.erase(0, prefix.size()); diff --git a/src/impl/sctptransport.cpp b/src/impl/sctptransport.cpp index ddcaedf..7ee318d 100644 --- a/src/impl/sctptransport.cpp +++ b/src/impl/sctptransport.cpp @@ -85,8 +85,30 @@ static LogCounter static LogCounter COUNTER_BAD_SCTP_STATUS(plog::warning, "Number of SCTP packets received with a bad status"); -std::unordered_set SctpTransport::Instances; -std::shared_mutex SctpTransport::InstancesMutex; +class SctpTransport::InstancesSet { +public: + void insert(SctpTransport *instance) { + std::unique_lock lock(mMutex); + mSet.insert(instance); + } + + void erase(SctpTransport *instance) { + std::unique_lock lock(mMutex); + mSet.erase(instance); + } + + using shared_lock = std::shared_lock; + optional lock(SctpTransport *instance) { + shared_lock lock(mMutex); + return mSet.find(instance) != mSet.end() ? std::make_optional(std::move(lock)) : nullopt; + } + +private: + std::unordered_set mSet; + std::shared_mutex mMutex; +}; + +SctpTransport::InstancesSet *SctpTransport::Instances = new InstancesSet; void SctpTransport::Init() { usrsctp_init(0, &SctpTransport::WriteCallback, nullptr); @@ -159,10 +181,7 @@ SctpTransport::SctpTransport(shared_ptr lower, const Configuration &c PLOG_DEBUG << "Initializing SCTP transport"; usrsctp_register_address(this); - { - std::unique_lock lock(InstancesMutex); - Instances.insert(this); - } + Instances->insert(this); mSock = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, nullptr, nullptr, 0, nullptr); if (!mSock) @@ -301,10 +320,7 @@ SctpTransport::~SctpTransport() { close(); usrsctp_deregister_address(this); - { - std::unique_lock lock(InstancesMutex); - Instances.erase(this); - } + Instances->erase(this); } void SctpTransport::start() { @@ -864,11 +880,8 @@ optional SctpTransport::rtt() { void SctpTransport::UpcallCallback(struct socket *, void *arg, int /* flags */) { auto *transport = static_cast(arg); - std::shared_lock lock(InstancesMutex); - if (Instances.find(transport) == Instances.end()) - return; - - transport->handleUpcall(); + if(auto lock = Instances->lock(transport)) + transport->handleUpcall(); } int SctpTransport::WriteCallback(void *ptr, void *data, size_t len, uint8_t tos, uint8_t set_df) { @@ -876,11 +889,10 @@ int SctpTransport::WriteCallback(void *ptr, void *data, size_t len, uint8_t tos, // Workaround for sctplab/usrsctp#405: Send callback is invoked on already closed socket // https://github.com/sctplab/usrsctp/issues/405 - std::shared_lock lock(InstancesMutex); - if (Instances.find(transport) == Instances.end()) + if(auto lock = Instances->lock(transport)) + return transport->handleWrite(static_cast(data), len, tos, set_df); + else return -1; - - return transport->handleWrite(static_cast(data), len, tos, set_df); } } // namespace rtc::impl diff --git a/src/impl/sctptransport.hpp b/src/impl/sctptransport.hpp index a7cf7b2..654099b 100644 --- a/src/impl/sctptransport.hpp +++ b/src/impl/sctptransport.hpp @@ -120,8 +120,8 @@ private: static void UpcallCallback(struct socket *sock, void *arg, int flags); static int WriteCallback(void *sctp_ptr, void *data, size_t len, uint8_t tos, uint8_t set_df); - static std::unordered_set Instances; - static std::shared_mutex InstancesMutex; + class InstancesSet; + static InstancesSet *Instances; }; } // namespace rtc::impl