| Index: webrtc/api/peerconnection.cc | 
| diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc | 
| index 5f8acca5669c0c1aabb8a568e9d8a4d46a5c22f9..7acdee6925333608d8e798043dd1d2bd0ae2347a 100644 | 
| --- a/webrtc/api/peerconnection.cc | 
| +++ b/webrtc/api/peerconnection.cc | 
| @@ -590,6 +590,9 @@ bool PeerConnection::Initialize( | 
| new WebRtcSession(media_controller_.get(), factory_->network_thread(), | 
| factory_->worker_thread(), factory_->signaling_thread(), | 
| port_allocator_.get())); | 
| + | 
| +  session_->SetTransportController( | 
| +      factory_->CreateTransportController(port_allocator_.get())); | 
| stats_.reset(new StatsCollector(this)); | 
|  | 
| // Initialize the WebRtcSession. It creates transport channels etc. | 
| @@ -760,6 +763,9 @@ bool PeerConnection::RemoveTrack(RtpSenderInterface* sender) { | 
| rtc::scoped_refptr<DtmfSenderInterface> PeerConnection::CreateDtmfSender( | 
| AudioTrackInterface* track) { | 
| TRACE_EVENT0("webrtc", "PeerConnection::CreateDtmfSender"); | 
| +  if (IsClosed()) { | 
| +    return nullptr; | 
| +  } | 
| if (!track) { | 
| LOG(LS_ERROR) << "CreateDtmfSender - track is NULL."; | 
| return NULL; | 
| @@ -782,6 +788,9 @@ rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender( | 
| const std::string& kind, | 
| const std::string& stream_id) { | 
| TRACE_EVENT0("webrtc", "PeerConnection::CreateSender"); | 
| +  if (IsClosed()) { | 
| +    return nullptr; | 
| +  } | 
| rtc::scoped_refptr<RtpSenderInterface> new_sender; | 
| if (kind == MediaStreamTrackInterface::kAudioKind) { | 
| new_sender = RtpSenderProxy::Create( | 
| @@ -984,6 +993,9 @@ void PeerConnection::SetLocalDescription( | 
| SetSessionDescriptionObserver* observer, | 
| SessionDescriptionInterface* desc) { | 
| TRACE_EVENT0("webrtc", "PeerConnection::SetLocalDescription"); | 
| +  if (IsClosed()) { | 
| +    return; | 
| +  } | 
| if (!VERIFY(observer != nullptr)) { | 
| LOG(LS_ERROR) << "SetLocalDescription - observer is NULL."; | 
| return; | 
| @@ -1062,6 +1074,9 @@ void PeerConnection::SetRemoteDescription( | 
| SetSessionDescriptionObserver* observer, | 
| SessionDescriptionInterface* desc) { | 
| TRACE_EVENT0("webrtc", "PeerConnection::SetRemoteDescription"); | 
| +  if (IsClosed()) { | 
| +    return; | 
| +  } | 
| if (!VERIFY(observer != nullptr)) { | 
| LOG(LS_ERROR) << "SetRemoteDescription - observer is NULL."; | 
| return; | 
| @@ -1182,6 +1197,9 @@ bool PeerConnection::SetConfiguration(const RTCConfiguration& configuration) { | 
| bool PeerConnection::AddIceCandidate( | 
| const IceCandidateInterface* ice_candidate) { | 
| TRACE_EVENT0("webrtc", "PeerConnection::AddIceCandidate"); | 
| +  if (IsClosed()) { | 
| +    return false; | 
| +  } | 
| return session_->ProcessIceMessage(ice_candidate); | 
| } | 
|  | 
| @@ -1226,7 +1244,6 @@ void PeerConnection::Close() { | 
| // Update stats here so that we have the most recent stats for tracks and | 
| // streams before the channels are closed. | 
| stats_->UpdateStats(kStatsOutputLevelStandard); | 
| - | 
| session_->Close(); | 
| } | 
|  | 
| @@ -1367,17 +1384,26 @@ void PeerConnection::OnIceGatheringChange( | 
|  | 
| void PeerConnection::OnIceCandidate(const IceCandidateInterface* candidate) { | 
| RTC_DCHECK(signaling_thread()->IsCurrent()); | 
| +  if (IsClosed()) { | 
| +    return; | 
| +  } | 
| observer_->OnIceCandidate(candidate); | 
| } | 
|  | 
| void PeerConnection::OnIceCandidatesRemoved( | 
| const std::vector<cricket::Candidate>& candidates) { | 
| RTC_DCHECK(signaling_thread()->IsCurrent()); | 
| +  if (IsClosed()) { | 
| +    return; | 
| +  } | 
| observer_->OnIceCandidatesRemoved(candidates); | 
| } | 
|  | 
| void PeerConnection::OnIceConnectionReceivingChange(bool receiving) { | 
| RTC_DCHECK(signaling_thread()->IsCurrent()); | 
| +  if (IsClosed()) { | 
| +    return; | 
| +  } | 
| observer_->OnIceConnectionReceivingChange(receiving); | 
| } | 
|  | 
| @@ -1397,6 +1423,9 @@ void PeerConnection::ChangeSignalingState( | 
|  | 
| void PeerConnection::OnAudioTrackAdded(AudioTrackInterface* track, | 
| MediaStreamInterface* stream) { | 
| +  if (IsClosed()) { | 
| +    return; | 
| +  } | 
| auto sender = FindSenderForTrack(track); | 
| if (sender != senders_.end()) { | 
| // We already have a sender for this track, so just change the stream_id | 
| @@ -1427,6 +1456,9 @@ void PeerConnection::OnAudioTrackAdded(AudioTrackInterface* track, | 
| // indefinitely, when we have unified plan SDP. | 
| void PeerConnection::OnAudioTrackRemoved(AudioTrackInterface* track, | 
| MediaStreamInterface* stream) { | 
| +  if (IsClosed()) { | 
| +    return; | 
| +  } | 
| auto sender = FindSenderForTrack(track); | 
| if (sender == senders_.end()) { | 
| LOG(LS_WARNING) << "RtpSender for track with id " << track->id() | 
| @@ -1439,6 +1471,9 @@ void PeerConnection::OnAudioTrackRemoved(AudioTrackInterface* track, | 
|  | 
| void PeerConnection::OnVideoTrackAdded(VideoTrackInterface* track, | 
| MediaStreamInterface* stream) { | 
| +  if (IsClosed()) { | 
| +    return; | 
| +  } | 
| auto sender = FindSenderForTrack(track); | 
| if (sender != senders_.end()) { | 
| // We already have a sender for this track, so just change the stream_id | 
| @@ -1461,6 +1496,9 @@ void PeerConnection::OnVideoTrackAdded(VideoTrackInterface* track, | 
|  | 
| void PeerConnection::OnVideoTrackRemoved(VideoTrackInterface* track, | 
| MediaStreamInterface* stream) { | 
| +  if (IsClosed()) { | 
| +    return; | 
| +  } | 
| auto sender = FindSenderForTrack(track); | 
| if (sender == senders_.end()) { | 
| LOG(LS_WARNING) << "RtpSender for track with id " << track->id() | 
|  |