Commit 9b082c6b authored by Francois Doray's avatar Francois Doray Committed by Commit Bot

[PM] Track the frame for each LockManager::Lock.

With this CL, we store the render_process_id and render_frame_id
(if any) associated with each LockManager::Lock in LockManager.

This is a prerequisite to build a Web Lock observer interface, through
which code outside of //content can know which frames hold lock and
avoid freezing them.

Bug: 980533
Change-Id: Ifb298f8739cf5d2ab5b982088403328fd7376a7a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1757288
Commit-Queue: François Doray <fdoray@chromium.org>
Reviewed-by: default avatarJoshua Bell <jsbell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#700883}
parent 2259a6a2
......@@ -74,12 +74,13 @@ class LockManager::Lock {
Lock(const std::string& name,
LockMode mode,
int64_t lock_id,
const std::string& client_id,
const ReceiverState& receiver_state,
mojo::AssociatedRemote<blink::mojom::LockRequest> request)
: name_(name),
mode_(mode),
client_id_(client_id),
lock_id_(lock_id),
client_id_(receiver_state.client_id),
execution_context_(receiver_state.execution_context),
request_(std::move(request)) {}
~Lock() = default;
......@@ -125,13 +126,17 @@ class LockManager::Lock {
LockMode mode() const { return mode_; }
int64_t lock_id() const { return lock_id_; }
const std::string& client_id() const { return client_id_; }
const ExecutionContext& execution_context() const {
return execution_context_;
}
bool is_granted() const { return !!handle_; }
private:
const std::string name_;
const LockMode mode_;
const std::string client_id_;
const int64_t lock_id_;
const std::string client_id_;
const ExecutionContext execution_context_;
// Exactly one of the following is non-null at any given time.
......@@ -170,28 +175,27 @@ class LockManager::OriginState {
void PreemptLock(int64_t lock_id,
const std::string& name,
LockMode mode,
const std::string& client_id,
mojo::AssociatedRemote<blink::mojom::LockRequest> request,
const url::Origin origin) {
const ReceiverState& receiver_state) {
// Preempting shared locks is not supported.
DCHECK_EQ(mode, LockMode::EXCLUSIVE);
std::list<Lock>& request_queue = resource_names_to_requests_[name];
while (!request_queue.empty() && request_queue.front().is_granted())
BreakFront(request_queue);
request_queue.emplace_front(name, mode, lock_id, client_id,
request_queue.emplace_front(name, mode, lock_id, receiver_state,
std::move(request));
auto it = request_queue.begin();
lock_id_to_iterator_.emplace(it->lock_id(), it);
it->Grant(lock_manager_->weak_ptr_factory_.GetWeakPtr(), origin);
it->Grant(lock_manager_->weak_ptr_factory_.GetWeakPtr(),
receiver_state.origin);
}
void AddRequest(int64_t lock_id,
const std::string& name,
LockMode mode,
const std::string& client_id,
mojo::AssociatedRemote<blink::mojom::LockRequest> request,
WaitMode wait,
const url::Origin origin) {
const ReceiverState& receiver_state) {
DCHECK(wait != WaitMode::PREEMPT);
std::list<Lock>& request_queue = resource_names_to_requests_[name];
bool can_grant = request_queue.empty() ||
......@@ -204,12 +208,14 @@ class LockManager::OriginState {
return;
}
request_queue.emplace_back(name, mode, lock_id, client_id,
request_queue.emplace_back(name, mode, lock_id, receiver_state,
std::move(request));
auto it = --(request_queue.end());
lock_id_to_iterator_.emplace(it->lock_id(), it);
if (can_grant)
it->Grant(lock_manager_->weak_ptr_factory_.GetWeakPtr(), origin);
if (can_grant) {
it->Grant(lock_manager_->weak_ptr_factory_.GetWeakPtr(),
receiver_state.origin);
}
}
void EraseLock(int64_t lock_id, const url::Origin& origin) {
......@@ -319,7 +325,7 @@ void LockManager::BindReceiver(
const std::string client_id = base::GenerateGUID();
receivers_.Add(this, std::move(receiver),
{client_id, render_process_id, render_frame_id, origin});
{client_id, {render_process_id, render_frame_id}, origin});
}
void LockManager::RequestLock(
......@@ -354,11 +360,10 @@ void LockManager::RequestLock(
OriginState& origin_state = origins_.find(context.origin)->second;
if (wait == WaitMode::PREEMPT) {
origin_state.PreemptLock(lock_id, name, mode, context.client_id,
std::move(request), context.origin);
origin_state.PreemptLock(lock_id, name, mode, std::move(request), context);
} else
origin_state.AddRequest(lock_id, name, mode, context.client_id,
std::move(request), wait, context.origin);
origin_state.AddRequest(lock_id, name, mode, std::move(request), wait,
context);
}
void LockManager::ReleaseLock(const url::Origin& origin, int64_t lock_id) {
......
......@@ -59,16 +59,22 @@ class LockManager : public base::RefCountedThreadSafe<LockManager>,
// State for a particular origin.
class OriginState;
// Describes a frame or a worker.
struct ExecutionContext {
// The identifier of the process hosting this frame or worker.
int render_process_id;
// The frame identifier, or MSG_ROUTING_NONE if this describes a worker
// (this means that dedicated/shared/service workers are not distinguished).
int render_frame_id;
};
// State for each client held in |receivers_|.
struct ReceiverState {
std::string client_id;
// Process owning this receiver.
int render_process_id;
// Frame owning this receiver. MSG_ROUTING_NONE if the receiver is owned by
// a worker.
int render_frame_id;
// ExecutionContext owning this receiver.
ExecutionContext execution_context;
// Origin of the frame or worker owning this receiver.
url::Origin origin;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment