Reland "[PeerConnection] Use an OperationsChain in PeerConnection for async ops."
This is a reland of 1dddaa1a84330091ca083c950ef2e24a85a48fc8
The regression that caused the original CL to be reverted was the fact that
invoking SetLocalDescription() inside of the CreateOffer() callback was no
longer executing synchronously and immediately.
In this CL, the original CL is patched so that the CreateOffer() operation
is marked as completed just before invoking the CreateOffer() callback
(versus doing it just afterwards). This ensures that the OperationsChain is
popped before the callback runs. The same applies for CreateAnswer().
See diff between Patch Set 1 (Original CL) and the latest Patch Set.
Original change's description:
> [PeerConnection] Use an OperationsChain in PeerConnection for async ops.
>
> For background, motivation, requirements and implementation notes, see
> https://docs.google.com/document/d/1XLwNN2kUIGGTwz9LQ0NwJNkcybi9oKnynUEZB1jGA14/edit?usp=sharing
>
> Using the OperationsChain will unblock future CLs from chaining multiple
> operations together such as implementing parameterless
> setLocalDescription().
>
> In this CL, the OperationsChain is used in existing signaling operations
> with little intended side-effects. An operation that is chained onto an
> empty OperationsChain will for instance execute immediately, and
> SetLocalDescription() and SetRemoteDescription() are implemented as
> "synchronous operations".
>
> The lifetime of the PeerConnection is not indended to change as a result
> of this CL: All chained operations use a WeakPtr to the PC to ensure
> use-after-free does not happen.
>
> There is one notable change though: CreateOffer() and CreateAnswer() will
> asynchronously delay other signaling methods from executing until they
> have completed.
>
> Drive-by fix: This CL also ensures that early failing
> CreateOffer/CreateAnswer operation's observers are invoked if the
> PeerConnection is destroyed while a PostCreateSessionDescriptionFailure
> is pending.
>
> Bug: webrtc:11019
> Change-Id: I521333e41d20d9bbfb1e721609f2c9db2a5f93a9
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/157305
> Reviewed-by: Steve Anton <steveanton@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#29605}
TBR=steveanton@webrtc.org
Bug: webrtc:11019
Change-Id: I57b4496e63378c91c24679ee496e21f5cb6a0e59
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/158524
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29630}
diff --git a/pc/peer_connection.h b/pc/peer_connection.h
index baaa14d..7a576f3 100644
--- a/pc/peer_connection.h
+++ b/pc/peer_connection.h
@@ -34,8 +34,10 @@
#include "pc/stream_collection.h"
#include "pc/webrtc_session_description_factory.h"
#include "rtc_base/experiments/field_trial_parser.h"
+#include "rtc_base/operations_chain.h"
#include "rtc_base/race_checker.h"
#include "rtc_base/unique_id_generator.h"
+#include "rtc_base/weak_ptr.h"
namespace webrtc {
@@ -443,6 +445,22 @@
rtc::scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
GetFirstAudioTransceiver() const RTC_RUN_ON(signaling_thread());
+ // Implementation of the offer/answer exchange operations. These are chained
+ // onto the |operations_chain_| when the public CreateOffer(), CreateAnswer(),
+ // SetLocalDescription() and SetRemoteDescription() methods are invoked.
+ void DoCreateOffer(
+ const RTCOfferAnswerOptions& options,
+ rtc::scoped_refptr<CreateSessionDescriptionObserver> observer);
+ void DoCreateAnswer(
+ const RTCOfferAnswerOptions& options,
+ rtc::scoped_refptr<CreateSessionDescriptionObserver> observer);
+ void DoSetLocalDescription(
+ std::unique_ptr<SessionDescriptionInterface> desc,
+ rtc::scoped_refptr<SetSessionDescriptionObserver> observer);
+ void DoSetRemoteDescription(
+ std::unique_ptr<SessionDescriptionInterface> desc,
+ rtc::scoped_refptr<SetRemoteDescriptionObserverInterface> observer);
+
void CreateAudioReceiver(MediaStreamInterface* stream,
const RtpSenderInfo& remote_sender_info)
RTC_RUN_ON(signaling_thread());
@@ -1217,6 +1235,14 @@
// pointer (but not touch the object) from any thread.
RtcEventLog* const event_log_ptr_ RTC_PT_GUARDED_BY(worker_thread());
+ // The operations chain is used by the offer/answer exchange methods to ensure
+ // they are executed in the right order. For example, if
+ // SetRemoteDescription() is invoked while CreateOffer() is still pending, the
+ // SRD operation will not start until CreateOffer() has completed. See
+ // https://w3c.github.io/webrtc-pc/#dfn-operations-chain.
+ rtc::scoped_refptr<rtc::OperationsChain> operations_chain_
+ RTC_GUARDED_BY(signaling_thread());
+
SignalingState signaling_state_ RTC_GUARDED_BY(signaling_thread()) = kStable;
IceConnectionState ice_connection_state_ RTC_GUARDED_BY(signaling_thread()) =
kIceConnectionNew;
@@ -1446,6 +1472,9 @@
std::unique_ptr<LocalIceCredentialsToReplace>
local_ice_credentials_to_replace_ RTC_GUARDED_BY(signaling_thread());
bool is_negotiation_needed_ RTC_GUARDED_BY(signaling_thread()) = false;
+
+ rtc::WeakPtrFactory<PeerConnection> weak_ptr_factory_
+ RTC_GUARDED_BY(signaling_thread());
};
} // namespace webrtc