910e62b5创建于 1月15日历史提交
// 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_