Browse Source

Merge pull request #598 from paullouisageneau/close-tracks-from-pc

Close tracks on Peer Connection close or failure
Paul-Louis Ageneau 3 years ago
parent
commit
ee2000a975
3 changed files with 25 additions and 5 deletions
  1. 13 3
      src/impl/peerconnection.cpp
  2. 1 0
      src/impl/peerconnection.hpp
  3. 11 2
      test/track.cpp

+ 13 - 3
src/impl/peerconnection.cpp

@@ -83,8 +83,9 @@ void PeerConnection::close() {
 
 	negotiationNeeded = false;
 
-	// Close data channels asynchronously
+	// Close data channels and tracks asynchronously
 	mProcessor->enqueue(&PeerConnection::closeDataChannels, this);
+	mProcessor->enqueue(&PeerConnection::closeTracks, this);
 
 	closeTransports();
 }
@@ -225,9 +226,11 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
 				    break;
 			    case DtlsTransport::State::Failed:
 				    changeState(State::Failed);
+				    mProcessor->enqueue(&PeerConnection::closeTracks, this);
 				    break;
 			    case DtlsTransport::State::Disconnected:
 				    changeState(State::Disconnected);
+				    mProcessor->enqueue(&PeerConnection::closeTracks, this);
 				    break;
 			    default:
 				    // Ignore
@@ -752,14 +755,21 @@ void PeerConnection::openTracks() {
 	if (auto transport = std::atomic_load(&mDtlsTransport)) {
 		auto srtpTransport = std::dynamic_pointer_cast<DtlsSrtpTransport>(transport);
 		std::shared_lock lock(mTracksMutex); // read-only
-		for (auto it = mTracks.begin(); it != mTracks.end(); ++it)
-			if (auto track = it->second.lock())
+		for (auto it = mTrackLines.begin(); it != mTrackLines.end(); ++it)
+			if (auto track = it->lock())
 				if (!track->isOpen())
 					track->open(srtpTransport);
 	}
 #endif
 }
 
+void PeerConnection::closeTracks() {
+	std::shared_lock lock(mTracksMutex); // read-only
+	for (auto it = mTrackLines.begin(); it != mTrackLines.end(); ++it)
+		if (auto track = it->lock())
+			track->close();
+}
+
 void PeerConnection::validateRemoteDescription(const Description &description) {
 	if (!description.iceUfrag())
 		throw std::invalid_argument("Remote description has no ICE user fragment");

+ 1 - 0
src/impl/peerconnection.hpp

@@ -77,6 +77,7 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
 	shared_ptr<Track> emplaceTrack(Description::Media description);
 	void incomingTrack(Description::Media description);
 	void openTracks();
+	void closeTracks();
 
 	void validateRemoteDescription(const Description &description);
 	void processLocalDescription(Description description);

+ 11 - 2
test/track.cpp

@@ -82,12 +82,18 @@ void test_track() {
 	shared_ptr<Track> t2;
 	string newTrackMid;
 	pc2.onTrack([&t2, &newTrackMid](shared_ptr<Track> t) {
-		cout << "Track 2: Received with mid \"" << t->mid() << "\"" << endl;
-		if (t->mid() != newTrackMid) {
+		string mid = t->mid();
+		cout << "Track 2: Received track with mid \"" << mid << "\"" << endl;
+		if (mid != newTrackMid) {
 			cerr << "Wrong track mid" << endl;
 			return;
 		}
 
+		t->onOpen([mid]() { cout << "Track 2: Track with mid \"" << mid << "\" is open" << endl; });
+
+		t->onClosed(
+		    [mid]() { cout << "Track 2: Track with mid \"" << mid << "\" is closed" << endl; });
+
 		std::atomic_store(&t2, t);
 	});
 
@@ -131,5 +137,8 @@ void test_track() {
 	pc2.close();
 	this_thread::sleep_for(1s);
 
+	if (!t1->isClosed() || !t2->isClosed())
+		throw runtime_error("Track is not closed");
+
 	cout << "Success" << endl;
 }