blob: 41024e7d54bc1900e0a0c6f23183a3a73e740f9f [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SERVICES_WEBNN_QUEUEABLE_RESOURCE_STATE_H_
#define SERVICES_WEBNN_QUEUEABLE_RESOURCE_STATE_H_
#include "base/memory/scoped_refptr.h"
#include "base/sequence_checker.h"
#include "base/thread_annotations.h"
#include "services/webnn/queueable_resource_state_base.h"
namespace webnn {
// Manages the state of a resource to be executed in a `ResourceTask`.
// This class enforces that the underlying resource may only be accessed while
// executing in a `ResourceTask`.
//
// Example use:
//
// auto task = base::MakeRefCounted<ResourceTask>(
// /*shared_resources=*/{my_resource_state},
// /*exclusive_resources=*/{},
// base::BindOnce(
// [](scoped_refptr<QueueableResourceState<MyResourceType>> state,
// base::OnceClosure completion_closure) {
// // We have a shared lock on the resource while until
// // `completion_closure` is run. We can safely get a reference to
// // the underlying resource.
// const MyResourceType& resource = state.GetSharedLockedResource();
// // Do something with `resource`...
// },
// my_resource_state));
// task->Enqueue();
//
// This class is reference counted so that operations that are in progress will
// keep the resources they are using alive until they complete. This class may
// not be passed between threads.
template <typename ResourceType>
class QueueableResourceState : public QueueableResourceStateBase {
public:
explicit QueueableResourceState(std::unique_ptr<ResourceType> resource)
: resource_content_(std::move(resource)) {}
// Get const access to the underlying resource. This method may only be
// called within a `ResourceTask` which took a shared lock on this state.
const ResourceType& GetSharedLockedResource() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
CHECK(IsLockedShared());
return *resource_content_.get();
}
// Get mutable access to the underlying resource. This method may only be
// called within a `ResourceTask` which took an exclusive lock on this state.
ResourceType* GetExclusivelyLockedResource() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
CHECK(IsLockedExclusive());
return resource_content_.get();
}
private:
~QueueableResourceState() override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
const std::unique_ptr<ResourceType> resource_content_
GUARDED_BY_CONTEXT(sequence_checker_);
};
} // namespace webnn
#endif // SERVICES_WEBNN_QUEUEABLE_RESOURCE_STATE_H_