123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- // Copyright 2022 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.
- #ifndef MOJO_CORE_IPCZ_DRIVER_OBJECT_H_
- #define MOJO_CORE_IPCZ_DRIVER_OBJECT_H_
- #include <cstddef>
- #include <cstdint>
- #include <tuple>
- #include "base/containers/span.h"
- #include "base/memory/ref_counted.h"
- #include "base/memory/scoped_refptr.h"
- #include "build/build_config.h"
- #include "mojo/core/ipcz_api.h"
- #include "mojo/public/cpp/platform/platform_handle.h"
- #include "third_party/ipcz/include/ipcz/ipcz.h"
- namespace mojo::core::ipcz_driver {
- class Transport;
- // Common base class for objects managed by Mojo's ipcz driver.
- class ObjectBase : public base::RefCountedThreadSafe<ObjectBase> {
- public:
- REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
- enum Type : uint32_t {
- // An ipcz transport endpoint.
- kTransport,
- // A wrapped shared memory region.
- kSharedBuffer,
- // An active mapping for a shared memory region. These objects are not
- // serializable and cannot be transmitted over a Transport.
- kSharedBufferMapping,
- // A PlatformHandle which can be transmitted as-is by the platform's Channel
- // implementation, out-of-band from message data. This is the only type of
- // driver object which can be emitted by the driver's Serialize(), and it's
- // the only type accepted by its Transmit(). This type is unused on Windows,
- // where all platform handles are encoded as inline message data during
- // serialization.
- kTransmissiblePlatformHandle,
- // A PlatformHandle which may or may not be transmissible by the platform's
- // Channel implementation, but which can at least be transformed into
- // something transmissible during serialization.
- kWrappedPlatformHandle,
- // A MojoTrap instance used to emulate a Mojo trap. These objects are not
- // serializable and cannot be transmitted over a Transport.
- kMojoTrap,
- // An Invitation instance used to emulate Mojo process invitations. These
- // objects are not serializable and cannot be transmitted over a Transport.
- kInvitation,
- };
- explicit ObjectBase(Type type);
- Type type() const { return type_; }
- IpczDriverHandle handle() const {
- return reinterpret_cast<IpczDriverHandle>(this);
- }
- static ObjectBase* FromHandle(IpczDriverHandle handle) {
- return reinterpret_cast<ObjectBase*>(handle);
- }
- static IpczDriverHandle ReleaseAsHandle(scoped_refptr<ObjectBase> object) {
- return reinterpret_cast<IpczDriverHandle>(object.release());
- }
- static scoped_refptr<ObjectBase> TakeFromHandle(IpczDriverHandle handle) {
- scoped_refptr<ObjectBase> object(FromHandle(handle));
- if (object) {
- // We're inheriting a ref previously owned by `handle`, so drop the extra
- // ref we just added.
- object->Release();
- }
- return object;
- }
- // Closes this object.
- virtual void Close();
- // Indicates whether this object can be serialized at all.
- virtual bool IsSerializable() const;
- // Computes the number of bytes and platform handles required to serialize
- // this object for transmission through `transmitter`. Returns false if the
- // object cannot be serialized or transmitted as such.
- virtual bool GetSerializedDimensions(Transport& transmitter,
- size_t& num_bytes,
- size_t& num_handles);
- // Attempts to serialize this object into `data` and `handles` which are
- // already sufficiently sized according to GetSerializedDimensions(). Returns
- // false if serialization fails.
- virtual bool Serialize(Transport& transmitter,
- base::span<uint8_t> data,
- base::span<PlatformHandle> handles);
- protected:
- virtual ~ObjectBase();
- // Boxes a reference to `object` and returns an IpczHandle for the box.
- static IpczHandle Box(scoped_refptr<ObjectBase> object);
- // Peeks at `box` and returns its underlying driver handle.
- static IpczDriverHandle PeekBox(IpczHandle box);
- // Unboxes `box` and returns a reference to the object it contained.
- static scoped_refptr<ObjectBase> Unbox(IpczHandle box);
- private:
- friend class base::RefCountedThreadSafe<ObjectBase>;
- const Type type_;
- };
- // Type-specific base class which builds on ObjectBase but which infers its Type
- // from a static object_type() method defined by T.
- template <typename T>
- class Object : public ObjectBase {
- public:
- Object() : ObjectBase(T::object_type()) {}
- // Constructs a new T instance with the forwarded Args, and immediately boxes
- // a reference to it. Returns a handle to the new box.
- template <typename... Args>
- static IpczHandle MakeBoxed(Args&&... args) {
- return Box(base::MakeRefCounted<T>(std::forward<Args>(args)...));
- }
- static T* FromHandle(IpczDriverHandle handle) {
- ObjectBase* object = ObjectBase::FromHandle(handle);
- if (!object || object->type() != T::object_type()) {
- return nullptr;
- }
- return static_cast<T*>(object);
- }
- static scoped_refptr<T> TakeFromHandle(IpczDriverHandle handle) {
- scoped_refptr<T> object(FromHandle(handle));
- if (object) {
- // We're inheriting a ref previously owned by `handle`, so drop the extra
- // ref we just added.
- object->Release();
- }
- return object;
- }
- // Peeks at `box` and returns a pointer to its underlying T, if the underlying
- // driver object is in fact a T. Does not invalidate `box`.
- static T* FromBox(IpczHandle box) { return FromHandle(PeekBox(box)); }
- // Unboxes `box` and returns a reference to its underlying T. If `box` is not
- // a box that contains a T, this returns null.
- static scoped_refptr<T> Unbox(IpczHandle box) {
- scoped_refptr<T> object = base::WrapRefCounted(T::FromBox(box));
- if (object) {
- std::ignore = ObjectBase::Unbox(box);
- }
- return object;
- }
- protected:
- ~Object() override = default;
- };
- } // namespace mojo::core::ipcz_driver
- #endif // MOJO_CORE_IPCZ_DRIVER_OBJECT_H_
|