blob: a0a280ff67b36f93b4e623057de6134e0860e4a6 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/socket/connect_job.h"
#include "base/trace_event/trace_event.h"
#include "net/base/net_errors.h"
#include "net/base/trace_constants.h"
#include "net/log/net_log.h"
#include "net/log/net_log_event_type.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/stream_socket.h"
namespace net {
CommonConnectJobParams::CommonConnectJobParams(
const std::string& group_name,
const SocketTag& socket_tag,
bool respect_limits,
ClientSocketFactory* client_socket_factory,
SocketPerformanceWatcherFactory* socket_performance_watcher_factory,
HostResolver* host_resolver,
NetLog* net_log,
WebSocketEndpointLockManager* websocket_endpoint_lock_manager)
: group_name(group_name),
socket_tag(socket_tag),
respect_limits(respect_limits),
client_socket_factory(client_socket_factory),
socket_performance_watcher_factory(socket_performance_watcher_factory),
host_resolver(host_resolver),
net_log(net_log),
websocket_endpoint_lock_manager(websocket_endpoint_lock_manager) {
DCHECK(!group_name.empty());
}
CommonConnectJobParams::CommonConnectJobParams(
const CommonConnectJobParams& other) = default;
CommonConnectJobParams::~CommonConnectJobParams() = default;
CommonConnectJobParams& CommonConnectJobParams::operator=(
const CommonConnectJobParams& other) = default;
ConnectJob::ConnectJob(RequestPriority priority,
base::TimeDelta timeout_duration,
const CommonConnectJobParams& common_connect_job_params,
Delegate* delegate,
const NetLogWithSource& net_log)
: timeout_duration_(timeout_duration),
priority_(priority),
common_connect_job_params_(common_connect_job_params),
delegate_(delegate),
net_log_(net_log) {
DCHECK(delegate);
net_log.BeginEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB,
NetLog::StringCallback(
"group_name", &common_connect_job_params.group_name));
}
ConnectJob::ConnectJob(const std::string& group_name,
base::TimeDelta timeout_duration,
RequestPriority priority,
const SocketTag& socket_tag,
bool respect_limits,
Delegate* delegate,
const NetLogWithSource& net_log)
: ConnectJob(priority,
timeout_duration,
CommonConnectJobParams(
group_name,
socket_tag,
respect_limits,
nullptr /* client_socket_factory */,
nullptr /* socket_performance_watcher_factory */,
nullptr /* host_resolver */,
nullptr /* net_log */,
nullptr /* websocket_endpoint_lock_manager */),
delegate,
net_log) {}
ConnectJob::~ConnectJob() {
net_log().EndEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB);
}
std::unique_ptr<StreamSocket> ConnectJob::PassSocket() {
return std::move(socket_);
}
void ConnectJob::ChangePriority(RequestPriority priority) {
// Priority of a job that ignores limits should not be changed because it
// should always be MAXIMUM_PRIORITY.
DCHECK(respect_limits());
priority_ = priority;
ChangePriorityInternal(priority);
}
int ConnectJob::Connect() {
if (!timeout_duration_.is_zero())
timer_.Start(FROM_HERE, timeout_duration_, this, &ConnectJob::OnTimeout);
LogConnectStart();
int rv = ConnectInternal();
if (rv != ERR_IO_PENDING) {
LogConnectCompletion(rv);
delegate_ = nullptr;
}
return rv;
}
void ConnectJob::SetSocket(std::unique_ptr<StreamSocket> socket) {
if (socket) {
net_log().AddEvent(NetLogEventType::CONNECT_JOB_SET_SOCKET,
socket->NetLog().source().ToEventParametersCallback());
}
socket_ = std::move(socket);
}
void ConnectJob::NotifyDelegateOfCompletion(int rv) {
TRACE_EVENT0(NetTracingCategory(), "ConnectJob::NotifyDelegateOfCompletion");
// The delegate will own |this|.
Delegate* delegate = delegate_;
delegate_ = nullptr;
LogConnectCompletion(rv);
delegate->OnConnectJobComplete(rv, this);
}
void ConnectJob::ResetTimer(base::TimeDelta remaining_time) {
timer_.Stop();
timer_.Start(FROM_HERE, remaining_time, this, &ConnectJob::OnTimeout);
}
void ConnectJob::LogConnectStart() {
connect_timing_.connect_start = base::TimeTicks::Now();
net_log().BeginEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT);
}
void ConnectJob::LogConnectCompletion(int net_error) {
connect_timing_.connect_end = base::TimeTicks::Now();
net_log().EndEventWithNetErrorCode(
NetLogEventType::SOCKET_POOL_CONNECT_JOB_CONNECT, net_error);
}
void ConnectJob::OnTimeout() {
// Make sure the socket is NULL before calling into |delegate|.
SetSocket(nullptr);
net_log_.AddEvent(NetLogEventType::SOCKET_POOL_CONNECT_JOB_TIMED_OUT);
NotifyDelegateOfCompletion(ERR_TIMED_OUT);
}
} // namespace net