Modified: trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp (250581 => 250582)
--- trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp 2019-10-01 21:26:06 UTC (rev 250581)
+++ trunk/Source/WebCore/Modules/mediastream/PeerConnectionBackend.cpp 2019-10-01 21:35:38 UTC (rev 250582)
@@ -100,8 +100,9 @@
return;
ASSERT(m_offerAnswerPromise);
- m_offerAnswerPromise->resolve(RTCSessionDescription::Init { RTCSdpType::Offer, filterSDP(WTFMove(sdp)) });
- m_offerAnswerPromise = WTF::nullopt;
+ m_peerConnection.doTask([promise = WTFMove(m_offerAnswerPromise), sdp = filterSDP(WTFMove(sdp))]() mutable {
+ promise->resolve(RTCSessionDescription::Init { RTCSdpType::Offer, sdp });
+ });
}
void PeerConnectionBackend::createOfferFailed(Exception&& exception)
@@ -113,8 +114,9 @@
return;
ASSERT(m_offerAnswerPromise);
- m_offerAnswerPromise->reject(WTFMove(exception));
- m_offerAnswerPromise = WTF::nullopt;
+ m_peerConnection.doTask([promise = WTFMove(m_offerAnswerPromise), exception = WTFMove(exception)]() mutable {
+ promise->reject(WTFMove(exception));
+ });
}
void PeerConnectionBackend::createAnswer(RTCAnswerOptions&& options, PeerConnection::SessionDescriptionPromise&& promise)
@@ -135,8 +137,9 @@
return;
ASSERT(m_offerAnswerPromise);
- m_offerAnswerPromise->resolve(RTCSessionDescription::Init { RTCSdpType::Answer, WTFMove(sdp) });
- m_offerAnswerPromise = WTF::nullopt;
+ m_peerConnection.doTask([promise = WTFMove(m_offerAnswerPromise), sdp = WTFMove(sdp)]() mutable {
+ promise->resolve(RTCSessionDescription::Init { RTCSdpType::Answer, sdp });
+ });
}
void PeerConnectionBackend::createAnswerFailed(Exception&& exception)
@@ -148,8 +151,9 @@
return;
ASSERT(m_offerAnswerPromise);
- m_offerAnswerPromise->reject(WTFMove(exception));
- m_offerAnswerPromise = WTF::nullopt;
+ m_peerConnection.doTask([promise = WTFMove(m_offerAnswerPromise), exception = WTFMove(exception)]() mutable {
+ promise->reject(WTFMove(exception));
+ });
}
static inline bool isLocalDescriptionTypeValidForState(RTCSdpType type, RTCSignalingState state)
@@ -192,10 +196,11 @@
if (m_peerConnection.isClosed())
return;
+
ASSERT(m_setDescriptionPromise);
-
- m_setDescriptionPromise->resolve();
- m_setDescriptionPromise = WTF::nullopt;
+ m_peerConnection.doTask([promise = WTFMove(m_setDescriptionPromise)]() mutable {
+ promise->resolve();
+ });
}
void PeerConnectionBackend::setLocalDescriptionFailed(Exception&& exception)
@@ -207,9 +212,9 @@
return;
ASSERT(m_setDescriptionPromise);
-
- m_setDescriptionPromise->reject(WTFMove(exception));
- m_setDescriptionPromise = WTF::nullopt;
+ m_peerConnection.doTask([promise = WTFMove(m_setDescriptionPromise), exception = WTFMove(exception)]() mutable {
+ promise->reject(WTFMove(exception));
+ });
}
static inline bool isRemoteDescriptionTypeValidForState(RTCSdpType type, RTCSignalingState state)
@@ -255,7 +260,7 @@
for (auto& event : events) {
auto& track = event.track.get();
- m_peerConnection.fireEvent(RTCTrackEvent::create(eventNames().trackEvent, Event::CanBubble::No, Event::IsCancelable::No, WTFMove(event.receiver), WTFMove(event.track), WTFMove(event.streams), WTFMove(event.transceiver)));
+ m_peerConnection.dispatchEventWhenFeasible(RTCTrackEvent::create(eventNames().trackEvent, Event::CanBubble::No, Event::IsCancelable::No, WTFMove(event.receiver), WTFMove(event.track), WTFMove(event.streams), WTFMove(event.transceiver)));
if (m_peerConnection.isClosed())
return;
@@ -267,10 +272,11 @@
if (m_peerConnection.isClosed())
return;
+
ASSERT(m_setDescriptionPromise);
-
- m_setDescriptionPromise->resolve();
- m_setDescriptionPromise = WTF::nullopt;
+ m_peerConnection.doTask([promise = WTFMove(m_setDescriptionPromise)]() mutable {
+ promise->resolve();
+ });
}
void PeerConnectionBackend::setRemoteDescriptionFailed(Exception&& exception)
@@ -283,9 +289,9 @@
ASSERT(!m_peerConnection.isClosed());
ASSERT(m_setDescriptionPromise);
-
- m_setDescriptionPromise->reject(WTFMove(exception));
- m_setDescriptionPromise = WTF::nullopt;
+ m_peerConnection.doTask([promise = WTFMove(m_setDescriptionPromise), exception = WTFMove(exception)]() mutable {
+ promise->reject(WTFMove(exception));
+ });
}
void PeerConnectionBackend::addPendingTrackEvent(PendingTrackEvent&& event)
@@ -332,9 +338,9 @@
return;
ASSERT(m_addIceCandidatePromise);
-
- m_addIceCandidatePromise->resolve();
- m_addIceCandidatePromise = WTF::nullopt;
+ m_peerConnection.doTask([promise = WTFMove(m_addIceCandidatePromise)]() mutable {
+ promise->resolve();
+ });
}
void PeerConnectionBackend::addIceCandidateFailed(Exception&& exception)
@@ -346,9 +352,9 @@
return;
ASSERT(m_addIceCandidatePromise);
-
- m_addIceCandidatePromise->reject(WTFMove(exception));
- m_addIceCandidatePromise = WTF::nullopt;
+ m_peerConnection.doTask([promise = WTFMove(m_addIceCandidatePromise), exception = WTFMove(exception)]() mutable {
+ promise->reject(WTFMove(exception));
+ });
}
void PeerConnectionBackend::fireICECandidateEvent(RefPtr<RTCIceCandidate>&& candidate, String&& serverURL)
@@ -355,7 +361,7 @@
{
ASSERT(isMainThread());
- m_peerConnection.fireEvent(RTCPeerConnectionIceEvent::create(Event::CanBubble::No, Event::IsCancelable::No, WTFMove(candidate), WTFMove(serverURL)));
+ m_peerConnection.dispatchEventWhenFeasible(RTCPeerConnectionIceEvent::create(Event::CanBubble::No, Event::IsCancelable::No, WTFMove(candidate), WTFMove(serverURL)));
}
void PeerConnectionBackend::enableICECandidateFiltering()
@@ -459,7 +465,7 @@
if (m_waitingForMDNSRegistration)
return;
- m_peerConnection.fireEvent(RTCPeerConnectionIceEvent::create(Event::CanBubble::No, Event::IsCancelable::No, nullptr, { }));
+ m_peerConnection.dispatchEventWhenFeasible(RTCPeerConnectionIceEvent::create(Event::CanBubble::No, Event::IsCancelable::No, nullptr, { }));
m_peerConnection.updateIceGatheringState(RTCIceGatheringState::Complete);
m_pendingICECandidates.clear();
}
@@ -508,7 +514,7 @@
if (newSignalingState != m_peerConnection.signalingState()) {
m_peerConnection.setSignalingState(newSignalingState);
- m_peerConnection.fireEvent(Event::create(eventNames().signalingstatechangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
+ m_peerConnection.dispatchEventWhenFeasible(Event::create(eventNames().signalingstatechangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
}
}
Modified: trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp (250581 => 250582)
--- trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp 2019-10-01 21:26:06 UTC (rev 250581)
+++ trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp 2019-10-01 21:35:38 UTC (rev 250582)
@@ -433,6 +433,7 @@
if (isClosed())
return false;
+ m_shouldDelayTasks = false;
m_connectionState = RTCPeerConnectionState::Closed;
m_iceConnectionState = RTCIceConnectionState::Closed;
m_signalingState = RTCSignalingState::Closed;
@@ -496,12 +497,36 @@
return "RTCPeerConnection";
}
- // FIXME: We should do better here, it is way too easy to prevent PageCache.
+// FIXME: We should do better here, it is way too easy to prevent PageCache.
bool RTCPeerConnection::canSuspendForDocumentSuspension() const
{
return !hasPendingActivity();
}
+void RTCPeerConnection::suspend(ReasonForSuspension reason)
+{
+ if (reason != ReasonForSuspension::PageCache)
+ return;
+
+ m_shouldDelayTasks = true;
+}
+
+void RTCPeerConnection::resume()
+{
+ if (!m_shouldDelayTasks)
+ return;
+
+ m_shouldDelayTasks = false;
+ scriptExecutionContext()->postTask([this, protectedThis = makeRef(*this)](auto&) {
+ if (m_isStopped || m_shouldDelayTasks)
+ return;
+
+ auto tasks = WTFMove(m_pendingTasks);
+ for (auto& task : tasks)
+ task();
+ });
+}
+
bool RTCPeerConnection::hasPendingActivity() const
{
if (m_isStopped)
@@ -536,7 +561,7 @@
return;
protectedThis->m_iceGatheringState = newState;
- protectedThis->dispatchEvent(Event::create(eventNames().icegatheringstatechangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
+ protectedThis->dispatchEventWhenFeasible(Event::create(eventNames().icegatheringstatechangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
protectedThis->updateConnectionState();
});
}
@@ -550,7 +575,7 @@
return;
protectedThis->m_iceConnectionState = newState;
- protectedThis->dispatchEvent(Event::create(eventNames().iceconnectionstatechangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
+ protectedThis->dispatchEventWhenFeasible(Event::create(eventNames().iceconnectionstatechangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
protectedThis->updateConnectionState();
});
}
@@ -580,7 +605,7 @@
INFO_LOG(LOGIDENTIFIER, "state changed from: " , m_connectionState, " to ", state);
m_connectionState = state;
- dispatchEvent(Event::create(eventNames().connectionstatechangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
+ dispatchEventWhenFeasible(Event::create(eventNames().connectionstatechangeEvent, Event::CanBubble::No, Event::IsCancelable::No));
}
void RTCPeerConnection::scheduleNegotiationNeededEvent()
@@ -591,15 +616,26 @@
if (!protectedThis->m_backend->isNegotiationNeeded())
return;
protectedThis->m_backend->clearNegotiationNeededState();
- protectedThis->dispatchEvent(Event::create(eventNames().negotiationneededEvent, Event::CanBubble::No, Event::IsCancelable::No));
+ protectedThis->dispatchEventWhenFeasible(Event::create(eventNames().negotiationneededEvent, Event::CanBubble::No, Event::IsCancelable::No));
});
}
-void RTCPeerConnection::fireEvent(Event& event)
+void RTCPeerConnection::doTask(Function<void()>&& task)
{
- dispatchEvent(event);
+ if (m_shouldDelayTasks || !m_pendingTasks.isEmpty()) {
+ m_pendingTasks.append(WTFMove(task));
+ return;
+ }
+ task();
}
+void RTCPeerConnection::dispatchEventWhenFeasible(Ref<Event>&& event)
+{
+ doTask([this, event = WTFMove(event)] {
+ dispatchEvent(event);
+ });
+}
+
void RTCPeerConnection::dispatchEvent(Event& event)
{
INFO_LOG(LOGIDENTIFIER, "dispatching '", event.type(), "'");
Modified: trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h (250581 => 250582)
--- trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h 2019-10-01 21:26:06 UTC (rev 250581)
+++ trunk/Source/WebCore/Modules/mediastream/RTCPeerConnection.h 2019-10-01 21:35:38 UTC (rev 250582)
@@ -165,7 +165,7 @@
void scheduleNegotiationNeededEvent();
- void fireEvent(Event&);
+ void dispatchEventWhenFeasible(Ref<Event>&&);
void disableICECandidateFiltering() { m_backend->disableICECandidateFiltering(); }
void enableICECandidateFiltering() { m_backend->enableICECandidateFiltering(); }
@@ -177,6 +177,8 @@
Document* document();
+ void doTask(Function<void()>&&);
+
#if !RELEASE_LOG_DISABLED
const Logger& logger() const final { return m_logger.get(); }
const void* logIdentifier() const final { return m_logIdentifier; }
@@ -210,6 +212,8 @@
WEBCORE_EXPORT void stop() final;
const char* activeDOMObjectName() const final;
bool canSuspendForDocumentSuspension() const final;
+ void suspend(ReasonForSuspension) final;
+ void resume() final;
void updateConnectionState();
bool doClose();
@@ -235,6 +239,8 @@
RTCConfiguration m_configuration;
RTCController* m_controller { nullptr };
Vector<RefPtr<RTCCertificate>> m_certificates;
+ bool m_shouldDelayTasks { false };
+ Vector<Function<void()>> m_pendingTasks;
};
} // namespace WebCore