1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2015 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_MESSAGE_PIPE_DISPATCHER_H_ 6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MOJO_EDK_SYSTEM_MESSAGE_PIPE_DISPATCHER_H_ 7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stdint.h> 9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <memory> 11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <queue> 12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/macros.h" 14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/atomic_flag.h" 15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/awakable_list.h" 16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/dispatcher.h" 17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/message_for_transit.h" 18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/ports/port_ref.h" 19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo { 21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace edk { 22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass NodeController; 24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass PortsMessage; 25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MessagePipeDispatcher : public Dispatcher { 27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public: 28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Constructs a MessagePipeDispatcher permanently tied to a specific port. 29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // |connected| must indicate the state of the port at construction time; if 30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // the port is initialized with a peer, |connected| must be true. Otherwise it 31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // must be false. 32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // 33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // A MessagePipeDispatcher may not be transferred while in a disconnected 34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // state, and one can never return to a disconnected once connected. 35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // 36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // |pipe_id| is a unique identifier which can be used to track pipe endpoints 37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // as they're passed around. |endpoint| is either 0 or 1 and again is only 38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // used for tracking pipes (one side is always 0, the other is always 1.) 39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MessagePipeDispatcher(NodeController* node_controller, 40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const ports::PortRef& port, 41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uint64_t pipe_id, 42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez int endpoint); 43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Fuses this pipe with |other|. Returns |true| on success or |false| on 45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // failure. Regardless of the return value, both dispatchers are closed by 46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // this call. 47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool Fuse(MessagePipeDispatcher* other); 48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Dispatcher: 50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez Type GetType() const override; 51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult Close() override; 52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult Watch(MojoHandleSignals signals, 53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const Watcher::WatchCallback& callback, 54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uintptr_t context) override; 55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult CancelWatch(uintptr_t context) override; 56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult WriteMessage(std::unique_ptr<MessageForTransit> message, 57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoWriteMessageFlags flags) override; 58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult ReadMessage(std::unique_ptr<MessageForTransit>* message, 59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uint32_t* num_bytes, 60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoHandle* handles, 61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uint32_t* num_handles, 62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoReadMessageFlags flags, 63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool read_any_size) override; 64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez HandleSignalsState GetHandleSignalsState() const override; 65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult AddAwakable(Awakable* awakable, 66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoHandleSignals signals, 67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uintptr_t context, 68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez HandleSignalsState* signals_state) override; 69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void RemoveAwakable(Awakable* awakable, 70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez HandleSignalsState* signals_state) override; 71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void StartSerialize(uint32_t* num_bytes, 72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uint32_t* num_ports, 73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uint32_t* num_handles) override; 74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool EndSerialize(void* destination, 75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ports::PortName* ports, 76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez PlatformHandle* handles) override; 77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool BeginTransit() override; 78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void CompleteTransitAndClose() override; 79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void CancelTransit() override; 80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez static scoped_refptr<Dispatcher> Deserialize( 82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const void* data, 83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t num_bytes, 84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const ports::PortName* ports, 85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t num_ports, 86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez PlatformHandle* handles, 87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez size_t num_handles); 88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private: 90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez class PortObserverThunk; 91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez friend class PortObserverThunk; 92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ~MessagePipeDispatcher() override; 94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult CloseNoLock(); 96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez HandleSignalsState GetHandleSignalsStateNoLock() const; 97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void OnPortStatusChanged(); 98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // These are safe to access from any thread without locking. 100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez NodeController* const node_controller_; 101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const ports::PortRef port_; 102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const uint64_t pipe_id_; 103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const int endpoint_; 104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Guards access to all the fields below. 106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez mutable base::Lock signal_lock_; 107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // This is not the same is |port_transferred_|. It's only held true between 109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // BeginTransit() and Complete/CancelTransit(). 110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez AtomicFlag in_transit_; 111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool port_transferred_ = false; 113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez AtomicFlag port_closed_; 114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez AwakableList awakables_; 115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DISALLOW_COPY_AND_ASSIGN(MessagePipeDispatcher); 117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}; 118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} // namespace edk 120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} // namespace mojo 121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif // MOJO_EDK_SYSTEM_MESSAGE_PIPE_DISPATCHER_H_ 123