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_PRODUCER_DISPATCHER_H_
6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MOJO_EDK_SYSTEM_DATA_PIPE_PRODUCER_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/system/awakable_list.h"
19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/dispatcher.h"
20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/ports/port_ref.h"
21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/system_impl_export.h"
22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo {
24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace edk {
25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezstruct DataPipeControlMessage;
27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass NodeController;
28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// This is the Dispatcher implementation for the producer handle for data
30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// pipes created by the Mojo primitive MojoCreateDataPipe(). This class is
31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// thread-safe.
32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MOJO_SYSTEM_IMPL_EXPORT DataPipeProducerDispatcher final
33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez    : public Dispatcher {
34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public:
35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DataPipeProducerDispatcher(
36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      NodeController* node_controller,
37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      const ports::PortRef& port,
38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      scoped_refptr<PlatformSharedBuffer> shared_ring_buffer,
39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      const MojoCreateDataPipeOptions& options,
40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      bool initialized,
41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez      uint64_t pipe_id);
42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Dispatcher:
44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  Type GetType() const override;
45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult Close() override;
46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult Watch(MojoHandleSignals signals,
47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                   const Watcher::WatchCallback& callback,
48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                   uintptr_t context) override;
49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult CancelWatch(uintptr_t context) override;
50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult WriteData(const void* elements,
51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                       uint32_t* num_bytes,
52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                       MojoReadDataFlags flags) override;
53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult BeginWriteData(void** buffer,
54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                            uint32_t* buffer_num_bytes,
55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                            MojoWriteDataFlags flags) override;
56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult EndWriteData(uint32_t num_bytes_written) override;
57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HandleSignalsState GetHandleSignalsState() const override;
58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult AddAwakable(Awakable* awakable,
59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         MojoHandleSignals signals,
60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         uintptr_t context,
61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                         HandleSignalsState* signals_state) override;
62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void RemoveAwakable(Awakable* awakable,
63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                      HandleSignalsState* signals_state) override;
64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void StartSerialize(uint32_t* num_bytes,
65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                      uint32_t* num_ports,
66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                      uint32_t* num_handles) override;
67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool EndSerialize(void* destination,
68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                    ports::PortName* ports,
69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                    PlatformHandle* handles) override;
70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool BeginTransit() override;
71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void CompleteTransitAndClose() override;
72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void CancelTransit() override;
73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  static scoped_refptr<DataPipeProducerDispatcher>
75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  Deserialize(const void* data,
76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              size_t num_bytes,
77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              const ports::PortName* ports,
78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              size_t num_ports,
79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              PlatformHandle* handles,
80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez              size_t num_handles);
81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private:
83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  class PortObserverThunk;
84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  friend class PortObserverThunk;
85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ~DataPipeProducerDispatcher() override;
87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void OnSharedBufferCreated(const scoped_refptr<PlatformSharedBuffer>& buffer);
89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void InitializeNoLock();
90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  MojoResult CloseNoLock();
91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  HandleSignalsState GetHandleSignalsStateNoLock() const;
92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void NotifyWrite(uint32_t num_bytes);
93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void OnPortStatusChanged();
94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  void UpdateSignalsStateNoLock();
95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool ProcessMessageNoLock(const DataPipeControlMessage& message,
96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez                            ScopedPlatformHandleVectorPtr handles);
97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const MojoCreateDataPipeOptions options_;
99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  NodeController* const node_controller_;
100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const ports::PortRef control_port_;
101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  const uint64_t pipe_id_;
102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  // Guards access to the fields below.
104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  mutable base::Lock lock_;
105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  AwakableList awakable_list_;
107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool buffer_requested_ = false;
109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  scoped_refptr<PlatformSharedBuffer> shared_ring_buffer_;
111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  std::unique_ptr<PlatformSharedBufferMapping> ring_buffer_mapping_;
112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  ScopedPlatformHandle buffer_handle_for_transit_;
113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool in_transit_ = false;
115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool is_closed_ = false;
116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool peer_closed_ = false;
117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool transferred_ = false;
118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  bool in_two_phase_write_ = false;
119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t write_offset_ = 0;
121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  uint32_t available_capacity_;
122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez  DISALLOW_COPY_AND_ASSIGN(DataPipeProducerDispatcher);
124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez};
125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace edk
127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}  // namespace mojo
128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez
129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif  // MOJO_EDK_SYSTEM_DATA_PIPE_PRODUCER_DISPATCHER_H_
130