|
@@ -79,15 +79,23 @@ PeerConnection::~PeerConnection() {
|
|
}
|
|
}
|
|
|
|
|
|
void PeerConnection::close() {
|
|
void PeerConnection::close() {
|
|
- PLOG_VERBOSE << "Closing PeerConnection";
|
|
|
|
-
|
|
|
|
negotiationNeeded = false;
|
|
negotiationNeeded = false;
|
|
|
|
+ if (!closing.exchange(true)) {
|
|
|
|
+ PLOG_VERBOSE << "Closing PeerConnection";
|
|
|
|
+ if (auto transport = std::atomic_load(&mSctpTransport))
|
|
|
|
+ transport->stop();
|
|
|
|
+ else
|
|
|
|
+ remoteClose();
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
|
|
- // Close data channels and tracks asynchronously
|
|
|
|
- mProcessor.enqueue(&PeerConnection::closeDataChannels, shared_from_this());
|
|
|
|
- mProcessor.enqueue(&PeerConnection::closeTracks, shared_from_this());
|
|
|
|
-
|
|
|
|
- closeTransports();
|
|
|
|
|
|
+void PeerConnection::remoteClose() {
|
|
|
|
+ close();
|
|
|
|
+ if (state.load() != State::Closed) {
|
|
|
|
+ closeDataChannels();
|
|
|
|
+ closeTracks();
|
|
|
|
+ closeTransports();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
optional<Description> PeerConnection::localDescription() const {
|
|
optional<Description> PeerConnection::localDescription() const {
|
|
@@ -125,11 +133,10 @@ shared_ptr<T> emplaceTransport(PeerConnection *pc, shared_ptr<T> *member, shared
|
|
transport->start();
|
|
transport->start();
|
|
} catch (...) {
|
|
} catch (...) {
|
|
std::atomic_store(member, decltype(transport)(nullptr));
|
|
std::atomic_store(member, decltype(transport)(nullptr));
|
|
- transport->stop();
|
|
|
|
throw;
|
|
throw;
|
|
}
|
|
}
|
|
|
|
|
|
- if (pc->state.load() == PeerConnection::State::Closed) {
|
|
|
|
|
|
+ if (pc->closing.load() || pc->state.load() == PeerConnection::State::Closed) {
|
|
std::atomic_store(member, decltype(transport)(nullptr));
|
|
std::atomic_store(member, decltype(transport)(nullptr));
|
|
transport->stop();
|
|
transport->stop();
|
|
return nullptr;
|
|
return nullptr;
|
|
@@ -155,14 +162,16 @@ shared_ptr<IceTransport> PeerConnection::initIceTransport() {
|
|
case IceTransport::State::Connecting:
|
|
case IceTransport::State::Connecting:
|
|
changeState(State::Connecting);
|
|
changeState(State::Connecting);
|
|
break;
|
|
break;
|
|
- case IceTransport::State::Failed:
|
|
|
|
- changeState(State::Failed);
|
|
|
|
- break;
|
|
|
|
case IceTransport::State::Connected:
|
|
case IceTransport::State::Connected:
|
|
initDtlsTransport();
|
|
initDtlsTransport();
|
|
break;
|
|
break;
|
|
|
|
+ case IceTransport::State::Failed:
|
|
|
|
+ changeState(State::Failed);
|
|
|
|
+ mProcessor.enqueue(&PeerConnection::remoteClose, shared_from_this());
|
|
|
|
+ break;
|
|
case IceTransport::State::Disconnected:
|
|
case IceTransport::State::Disconnected:
|
|
changeState(State::Disconnected);
|
|
changeState(State::Disconnected);
|
|
|
|
+ mProcessor.enqueue(&PeerConnection::remoteClose, shared_from_this());
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
// Ignore
|
|
// Ignore
|
|
@@ -226,11 +235,11 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
|
|
break;
|
|
break;
|
|
case DtlsTransport::State::Failed:
|
|
case DtlsTransport::State::Failed:
|
|
changeState(State::Failed);
|
|
changeState(State::Failed);
|
|
- mProcessor.enqueue(&PeerConnection::closeTracks, shared_from_this());
|
|
|
|
|
|
+ mProcessor.enqueue(&PeerConnection::remoteClose, shared_from_this());
|
|
break;
|
|
break;
|
|
case DtlsTransport::State::Disconnected:
|
|
case DtlsTransport::State::Disconnected:
|
|
changeState(State::Disconnected);
|
|
changeState(State::Disconnected);
|
|
- mProcessor.enqueue(&PeerConnection::closeTracks, shared_from_this());
|
|
|
|
|
|
+ mProcessor.enqueue(&PeerConnection::remoteClose, shared_from_this());
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
// Ignore
|
|
// Ignore
|
|
@@ -299,6 +308,7 @@ shared_ptr<SctpTransport> PeerConnection::initSctpTransport() {
|
|
auto shared_this = weak_this.lock();
|
|
auto shared_this = weak_this.lock();
|
|
if (!shared_this)
|
|
if (!shared_this)
|
|
return;
|
|
return;
|
|
|
|
+
|
|
switch (transportState) {
|
|
switch (transportState) {
|
|
case SctpTransport::State::Connected:
|
|
case SctpTransport::State::Connected:
|
|
changeState(State::Connected);
|
|
changeState(State::Connected);
|
|
@@ -308,13 +318,12 @@ shared_ptr<SctpTransport> PeerConnection::initSctpTransport() {
|
|
case SctpTransport::State::Failed:
|
|
case SctpTransport::State::Failed:
|
|
LOG_WARNING << "SCTP transport failed";
|
|
LOG_WARNING << "SCTP transport failed";
|
|
changeState(State::Failed);
|
|
changeState(State::Failed);
|
|
- mProcessor.enqueue(&PeerConnection::remoteCloseDataChannels,
|
|
|
|
- shared_from_this());
|
|
|
|
|
|
+ mProcessor.enqueue(&PeerConnection::remoteClose, shared_from_this());
|
|
break;
|
|
break;
|
|
case SctpTransport::State::Disconnected:
|
|
case SctpTransport::State::Disconnected:
|
|
|
|
+ LOG_INFO << "SCTP transport disconnected";
|
|
changeState(State::Disconnected);
|
|
changeState(State::Disconnected);
|
|
- mProcessor.enqueue(&PeerConnection::remoteCloseDataChannels,
|
|
|
|
- shared_from_this());
|
|
|
|
|
|
+ mProcessor.enqueue(&PeerConnection::remoteClose, shared_from_this());
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
// Ignore
|
|
// Ignore
|
|
@@ -370,18 +379,18 @@ void PeerConnection::closeTransports() {
|
|
if (t)
|
|
if (t)
|
|
t->onStateChange(nullptr);
|
|
t->onStateChange(nullptr);
|
|
|
|
|
|
- // Initiate transport stop on the processor after closing the data channels
|
|
|
|
- mProcessor.enqueue([self = shared_from_this(), transports = std::move(transports)]() {
|
|
|
|
- TearDownProcessor::Instance().enqueue(
|
|
|
|
- [transports = std::move(transports), token = Init::Instance().token()]() mutable {
|
|
|
|
- for (const auto &t : transports)
|
|
|
|
- if (t)
|
|
|
|
- t->stop();
|
|
|
|
|
|
+ TearDownProcessor::Instance().enqueue(
|
|
|
|
+ [transports = std::move(transports), token = Init::Instance().token()]() mutable {
|
|
|
|
+ for (const auto &t : transports) {
|
|
|
|
+ if (t) {
|
|
|
|
+ t->stop();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- for (auto &t : transports)
|
|
|
|
- t.reset();
|
|
|
|
- });
|
|
|
|
- });
|
|
|
|
|
|
+ for (auto &t : transports)
|
|
|
|
+ t.reset();
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
void PeerConnection::endLocalCandidates() {
|
|
void PeerConnection::endLocalCandidates() {
|