Chromium Code Reviews| Index: remoting/protocol/jingle_session.cc |
| diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc |
| index 6e6457abe14fc14294f4d79c3085ea4a04b46cb9..f421b025e6716af41571af663bc24fefa1568f53 100644 |
| --- a/remoting/protocol/jingle_session.cc |
| +++ b/remoting/protocol/jingle_session.cc |
| @@ -106,25 +106,25 @@ class JingleSession::OrderedMessageQueue { |
| ~OrderedMessageQueue() {} |
| // Returns the list of messages ordered by their sequential IDs. |
| - std::vector<std::unique_ptr<PendingMessage>> OnIncomingMessage( |
| + std::vector<PendingMessage> OnIncomingMessage( |
| const std::string& id, |
| - std::unique_ptr<PendingMessage>); |
| + PendingMessage&& pending_message); |
| private: |
| // Implements an ordered list by using map with the |sequence_id| as the key, |
| // so that |queue_| is always sorted by |sequence_id|. |
| - std::map<int, std::unique_ptr<PendingMessage>> queue_; |
| + std::map<int, PendingMessage> queue_; |
| int next_incoming_ = kAny; |
| DISALLOW_COPY_AND_ASSIGN(OrderedMessageQueue); |
| }; |
| -std::vector<std::unique_ptr<JingleSession::PendingMessage>> |
| +std::vector<JingleSession::PendingMessage> |
| JingleSession::OrderedMessageQueue::OnIncomingMessage( |
| const std::string& id, |
| - std::unique_ptr<JingleSession::PendingMessage> message) { |
| - std::vector<std::unique_ptr<JingleSession::PendingMessage>> result; |
| + JingleSession::PendingMessage&& message) { |
| + std::vector<JingleSession::PendingMessage> result; |
| int current = GetSequentialId(id); |
| // If there is no sequencing order encoded in the id, just return the |
| // message. |
| @@ -157,12 +157,16 @@ JingleSession::OrderedMessageQueue::OnIncomingMessage( |
| return result; |
| }; |
| +JingleSession::PendingMessage::PendingMessage() = default; |
|
kelvinp
2016/10/31 18:23:14
Out of curiosity, why is a default empty construct
Sergey Ulanov
2016/10/31 18:25:02
std::vector<> needs it.
|
| +JingleSession::PendingMessage::PendingMessage(PendingMessage&& moved) = default; |
| JingleSession::PendingMessage::PendingMessage( |
| std::unique_ptr<JingleMessage> message, |
| const ReplyCallback& reply_callback) |
| : message(std::move(message)), reply_callback(reply_callback) {} |
| +JingleSession::PendingMessage::~PendingMessage() = default; |
| -JingleSession::PendingMessage::~PendingMessage() {} |
| +JingleSession::PendingMessage& JingleSession::PendingMessage::operator=( |
| + PendingMessage&& moved) = default; |
| JingleSession::JingleSession(JingleSessionManager* session_manager) |
| : session_manager_(session_manager), |
| @@ -399,7 +403,7 @@ void JingleSession::SendMessage(std::unique_ptr<JingleMessage> message) { |
| } |
| if (request) { |
| request->SetTimeout(base::TimeDelta::FromSeconds(timeout)); |
| - pending_requests_.insert(std::move(request)); |
| + pending_requests_.push_back(std::move(request)); |
| } else { |
| LOG(ERROR) << "Failed to send a " |
| << JingleMessage::GetActionName(message->action) << " message"; |
| @@ -451,14 +455,15 @@ void JingleSession::OnTransportInfoResponse(IqRequest* request, |
| DCHECK(!transport_info_requests_.empty()); |
| // Consider transport-info requests sent before this one lost and delete |
| - // corresponding IqRequest objects. |
| - while (transport_info_requests_.front().get() != request) { |
| - transport_info_requests_.pop_front(); |
| - } |
| - |
| - // Delete the |request| itself. |
| - DCHECK_EQ(request, transport_info_requests_.front().get()); |
| - transport_info_requests_.pop_front(); |
| + // all IqRequest objects in front of |request|. |
| + auto request_it = std::find_if( |
| + transport_info_requests_.begin(), transport_info_requests_.end(), |
| + [request](const std::unique_ptr<IqRequest>& ptr) { |
| + return ptr.get() == request; |
| + }); |
| + DCHECK(request_it != transport_info_requests_.end()); |
| + transport_info_requests_.erase(transport_info_requests_.begin(), |
| + request_it + 1); |
| // Ignore transport-info timeouts. |
| if (!response) { |
| @@ -477,13 +482,13 @@ void JingleSession::OnTransportInfoResponse(IqRequest* request, |
| void JingleSession::OnIncomingMessage(const std::string& id, |
| std::unique_ptr<JingleMessage> message, |
| const ReplyCallback& reply_callback) { |
| - std::unique_ptr<PendingMessage> item( |
| - new PendingMessage(std::move(message), reply_callback)); |
| - std::vector<std::unique_ptr<PendingMessage>> ordered = |
| - message_queue_->OnIncomingMessage(id, std::move(item)); |
| + std::vector<PendingMessage> ordered = message_queue_->OnIncomingMessage( |
| + id, PendingMessage{std::move(message), reply_callback}); |
| + base::WeakPtr<JingleSession> self = weak_factory_.GetWeakPtr(); |
| for (auto& message : ordered) { |
| - ProcessIncomingMessage(std::move(message->message), |
| - message->reply_callback); |
| + ProcessIncomingMessage(std::move(message.message), message.reply_callback); |
| + if (!self) |
| + return; |
| } |
| } |
| @@ -508,19 +513,7 @@ void JingleSession::ProcessIncomingMessage( |
| break; |
| case JingleMessage::TRANSPORT_INFO: |
| - if (!transport_) { |
| - LOG(ERROR) << "Received unexpected transport-info message->"; |
| - reply_callback.Run(JingleMessageReply::NONE); |
| - return; |
| - } |
| - |
| - if (!message->transport_info || |
| - !transport_->ProcessTransportInfo(message->transport_info.get())) { |
| - reply_callback.Run(JingleMessageReply::BAD_REQUEST); |
| - return; |
| - } |
| - |
| - reply_callback.Run(JingleMessageReply::NONE); |
| + OnTransportInfo(std::move(message), reply_callback); |
| break; |
| case JingleMessage::SESSION_TERMINATE: |
| @@ -557,8 +550,9 @@ void JingleSession::OnAccept(std::unique_ptr<JingleMessage> message, |
| SetState(ACCEPTED); |
| DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); |
| - authenticator_->ProcessMessage(auth_message, base::Bind( |
| - &JingleSession::ProcessAuthenticationStep,base::Unretained(this))); |
| + authenticator_->ProcessMessage( |
| + auth_message, base::Bind(&JingleSession::ProcessAuthenticationStep, |
| + base::Unretained(this))); |
| } |
| void JingleSession::OnSessionInfo(std::unique_ptr<JingleMessage> message, |
| @@ -580,8 +574,30 @@ void JingleSession::OnSessionInfo(std::unique_ptr<JingleMessage> message, |
| reply_callback.Run(JingleMessageReply::NONE); |
| - authenticator_->ProcessMessage(message->info.get(), base::Bind( |
| - &JingleSession::ProcessAuthenticationStep, base::Unretained(this))); |
| + authenticator_->ProcessMessage( |
| + message->info.get(), base::Bind(&JingleSession::ProcessAuthenticationStep, |
| + base::Unretained(this))); |
| +} |
| + |
| +void JingleSession::OnTransportInfo(std::unique_ptr<JingleMessage> message, |
| + const ReplyCallback& reply_callback) { |
| + if (!message->transport_info) { |
| + reply_callback.Run(JingleMessageReply::BAD_REQUEST); |
| + return; |
| + } |
| + |
| + if (state_ == AUTHENTICATING) { |
| + pending_transport_info_.push_back( |
| + PendingMessage{std::move(message), reply_callback}); |
| + } else if (state_ == AUTHENTICATED) { |
| + reply_callback.Run( |
| + transport_->ProcessTransportInfo(message->transport_info.get()) |
| + ? JingleMessageReply::NONE |
| + : JingleMessageReply::BAD_REQUEST); |
| + } else { |
| + LOG(ERROR) << "Received unexpected transport-info message."; |
| + reply_callback.Run(JingleMessageReply::UNEXPECTED_REQUEST); |
| + } |
| } |
| void JingleSession::OnTerminate(std::unique_ptr<JingleMessage> message, |
| @@ -678,21 +694,13 @@ void JingleSession::ProcessAuthenticationStep() { |
| } |
| DCHECK_NE(authenticator_->state(), Authenticator::MESSAGE_READY); |
| - // The current JingleSession object can be destroyed by event_handler of |
| - // SetState(AUTHENTICATING) and cause subsequent dereferencing of the this |
| - // pointer to crash. To protect against it, we run ContinueAuthenticationStep |
| - // asychronously using a weak pointer. |
| - base::ThreadTaskRunnerHandle::Get()->PostTask( |
| - FROM_HERE, |
| - base::Bind(&JingleSession::ContinueAuthenticationStep, |
| - weak_factory_.GetWeakPtr())); |
| - |
| if (authenticator_->started()) { |
| + base::WeakPtr<JingleSession> self = weak_factory_.GetWeakPtr(); |
| SetState(AUTHENTICATING); |
| + if (!self) |
| + return; |
| } |
| -} |
| -void JingleSession::ContinueAuthenticationStep() { |
| if (authenticator_->state() == Authenticator::ACCEPTED) { |
| OnAuthenticated(); |
| } else if (authenticator_->state() == Authenticator::REJECTED) { |
| @@ -706,6 +714,18 @@ void JingleSession::OnAuthenticated() { |
| base::Bind(&JingleSession::SendTransportInfo, |
| weak_factory_.GetWeakPtr())); |
| + base::WeakPtr<JingleSession> self = weak_factory_.GetWeakPtr(); |
| + std::vector<PendingMessage> messages_to_process; |
| + std::swap(messages_to_process, pending_transport_info_); |
| + for (auto& message : messages_to_process) { |
| + message.reply_callback.Run( |
| + transport_->ProcessTransportInfo(message.message->transport_info.get()) |
| + ? JingleMessageReply::NONE |
| + : JingleMessageReply::BAD_REQUEST); |
| + if (!self) |
| + return; |
| + } |
| + |
| SetState(AUTHENTICATED); |
| } |