1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef MOJO_CORE_SHARED_BUFFER_DISPATCHER_H_
6 #define MOJO_CORE_SHARED_BUFFER_DISPATCHER_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <utility>
12 
13 #include "base/macros.h"
14 #include "base/memory/platform_shared_memory_region.h"
15 #include "mojo/core/dispatcher.h"
16 #include "mojo/core/system_impl_export.h"
17 
18 namespace mojo {
19 
20 namespace core {
21 
22 class NodeController;
23 class PlatformSharedMemoryMapping;
24 
25 class MOJO_SYSTEM_IMPL_EXPORT SharedBufferDispatcher final : public Dispatcher {
26  public:
27   // The default options to use for |MojoCreateSharedBuffer()|. (Real uses
28   // should obtain this via |ValidateCreateOptions()| with a null |in_options|;
29   // this is exposed directly for testing convenience.)
30   static const MojoCreateSharedBufferOptions kDefaultCreateOptions;
31 
32   // Validates and/or sets default options for |MojoCreateSharedBufferOptions|.
33   // If non-null, |in_options| must point to a struct of at least
34   // |in_options->struct_size| bytes. |out_options| must point to a (current)
35   // |MojoCreateSharedBufferOptions| and will be entirely overwritten on success
36   // (it may be partly overwritten on failure).
37   static MojoResult ValidateCreateOptions(
38       const MojoCreateSharedBufferOptions* in_options,
39       MojoCreateSharedBufferOptions* out_options);
40 
41   // Static factory method: |validated_options| must be validated (obviously).
42   // On failure, |*result| will be left as-is.
43   // TODO(vtl): This should probably be made to return a scoped_refptr and have
44   // a MojoResult out parameter instead.
45   static MojoResult Create(
46       const MojoCreateSharedBufferOptions& validated_options,
47       NodeController* node_controller,
48       uint64_t num_bytes,
49       scoped_refptr<SharedBufferDispatcher>* result);
50 
51   // Create a |SharedBufferDispatcher| from |shared_buffer|.
52   static MojoResult CreateFromPlatformSharedMemoryRegion(
53       base::subtle::PlatformSharedMemoryRegion region,
54       scoped_refptr<SharedBufferDispatcher>* result);
55 
56   // The "opposite" of SerializeAndClose(). Called by Dispatcher::Deserialize().
57   static scoped_refptr<SharedBufferDispatcher> Deserialize(
58       const void* bytes,
59       size_t num_bytes,
60       const ports::PortName* ports,
61       size_t num_ports,
62       PlatformHandle* platform_handles,
63       size_t num_handles);
64 
65   // Passes the underlying PlatformSharedMemoryRegion. This dispatcher must be
66   // closed after calling this function.
67   base::subtle::PlatformSharedMemoryRegion PassPlatformSharedMemoryRegion();
68 
69   // NOTE: This is not thread-safe. Definitely never use it outside of tests.
GetRegionForTesting()70   base::subtle::PlatformSharedMemoryRegion& GetRegionForTesting() {
71     return region_;
72   }
73 
74   // Dispatcher:
75   Type GetType() const override;
76   MojoResult Close() override;
77   MojoResult DuplicateBufferHandle(
78       const MojoDuplicateBufferHandleOptions* options,
79       scoped_refptr<Dispatcher>* new_dispatcher) override;
80   MojoResult MapBuffer(
81       uint64_t offset,
82       uint64_t num_bytes,
83       std::unique_ptr<PlatformSharedMemoryMapping>* mapping) override;
84   MojoResult GetBufferInfo(MojoSharedBufferInfo* info) override;
85   void StartSerialize(uint32_t* num_bytes,
86                       uint32_t* num_ports,
87                       uint32_t* num_platform_handles) override;
88   bool EndSerialize(void* destination,
89                     ports::PortName* ports,
90                     PlatformHandle* handles) override;
91   bool BeginTransit() override;
92   void CompleteTransitAndClose() override;
93   void CancelTransit() override;
94 
95  private:
96   explicit SharedBufferDispatcher(
97       base::subtle::PlatformSharedMemoryRegion region);
98   ~SharedBufferDispatcher() override;
99 
100   static scoped_refptr<SharedBufferDispatcher> CreateInternal(
101       base::subtle::PlatformSharedMemoryRegion region);
102 
103   // Validates and/or sets default options for
104   // |MojoDuplicateBufferHandleOptions|. If non-null, |in_options| must point to
105   // a struct of at least |in_options->struct_size| bytes. |out_options| must
106   // point to a (current) |MojoDuplicateBufferHandleOptions| and will be
107   // entirely overwritten on success (it may be partly overwritten on failure).
108   static MojoResult ValidateDuplicateOptions(
109       const MojoDuplicateBufferHandleOptions* in_options,
110       MojoDuplicateBufferHandleOptions* out_options);
111 
112   // Guards access to the fields below.
113   base::Lock lock_;
114 
115   bool in_transit_ = false;
116   base::subtle::PlatformSharedMemoryRegion region_;
117 
118   DISALLOW_COPY_AND_ASSIGN(SharedBufferDispatcher);
119 };
120 
121 }  // namespace core
122 }  // namespace mojo
123 
124 #endif  // MOJO_CORE_SHARED_BUFFER_DISPATCHER_H_
125