1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2013 The Chromium Authors. All rights reserved.
2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be
3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file.
4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#ifndef MOJO_EDK_SYSTEM_DATA_PIPE_CONSUMER_DISPATCHER_H_
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MOJO_EDK_SYSTEM_DATA_PIPE_CONSUMER_DISPATCHER_H_
7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stddef.h>
9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stdint.h>
10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <memory>
12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/macros.h"
14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/memory/ref_counted.h"
15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/synchronization/lock.h"
16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/embedder/platform_handle_vector.h"
17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/embedder/platform_shared_buffer.h"
18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/embedder/scoped_platform_handle.h"
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/awakable_list.h"
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/dispatcher.h"
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/ports/port_ref.h"
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/system_impl_export.h"
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo {
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace edk {
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezstruct DataPipeControlMessage;
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass NodeController;
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// This is the Dispatcher implementation for the consumer handle for data
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// pipes created by the Mojo primitive MojoCreateDataPipe(). This class is
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// thread-safe.
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MOJO_SYSTEM_IMPL_EXPORT DataPipeConsumerDispatcher final
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    : public Dispatcher {
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DataPipeConsumerDispatcher(
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      NodeController* node_controller,
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      const ports::PortRef& control_port,
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      scoped_refptr<PlatformSharedBuffer> shared_ring_buffer,
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      const MojoCreateDataPipeOptions& options,
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      bool initialized,
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      uint64_t pipe_id);
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Dispatcher:
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  Type GetType() const override;
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult Close() override;
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult Watch(MojoHandleSignals signals,
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                   const Watcher::WatchCallback& callback,
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                   uintptr_t context) override;
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult CancelWatch(uintptr_t context) override;
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult ReadData(void* elements,
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                      uint32_t* num_bytes,
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                      MojoReadDataFlags flags) override;
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult BeginReadData(const void** buffer,
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                           uint32_t* buffer_num_bytes,
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                           MojoReadDataFlags flags) override;
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult EndReadData(uint32_t num_bytes_read) override;
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HandleSignalsState GetHandleSignalsState() const override;
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult AddAwakable(Awakable* awakable,
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         MojoHandleSignals signals,
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         uintptr_t context,
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         HandleSignalsState* signals_state) override;
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void RemoveAwakable(Awakable* awakable,
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                      HandleSignalsState* signals_state) override;
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void StartSerialize(uint32_t* num_bytes,
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                      uint32_t* num_ports,
67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                      uint32_t* num_handles) override;
68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool EndSerialize(void* destination,
69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                    ports::PortName* ports,
70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                    PlatformHandle* handles) override;
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool BeginTransit() override;
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void CompleteTransitAndClose() override;
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void CancelTransit() override;
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  static scoped_refptr<DataPipeConsumerDispatcher>
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  Deserialize(const void* data,
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              size_t num_bytes,
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              const ports::PortName* ports,
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              size_t num_ports,
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              PlatformHandle* handles,
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              size_t num_handles);
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private:
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  class PortObserverThunk;
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  friend class PortObserverThunk;
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ~DataPipeConsumerDispatcher() override;
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void InitializeNoLock();
90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult CloseNoLock();
91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HandleSignalsState GetHandleSignalsStateNoLock() const;
92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void NotifyRead(uint32_t num_bytes);
93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void OnPortStatusChanged();
94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void UpdateSignalsStateNoLock();
95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const MojoCreateDataPipeOptions options_;
97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  NodeController* const node_controller_;
98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const ports::PortRef control_port_;
99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const uint64_t pipe_id_;
100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Guards access to the fields below.
102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  mutable base::Lock lock_;
103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  AwakableList awakable_list_;
105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  scoped_refptr<PlatformSharedBuffer> shared_ring_buffer_;
107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::unique_ptr<PlatformSharedBufferMapping> ring_buffer_mapping_;
108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ScopedPlatformHandle buffer_handle_for_transit_;
109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool in_two_phase_read_ = false;
111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t two_phase_max_bytes_read_ = 0;
112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool in_transit_ = false;
114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool is_closed_ = false;
115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool peer_closed_ = false;
116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool transferred_ = false;
117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t read_offset_ = 0;
119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t bytes_available_ = 0;
120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DISALLOW_COPY_AND_ASSIGN(DataPipeConsumerDispatcher);
122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace edk
125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace mojo
126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif  // MOJO_EDK_SYSTEM_DATA_PIPE_CONSUMER_DISPATCHER_H_
128