1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// Copyright 2013 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_EDK_SYSTEM_MESSAGE_PIPE_H_
#define MOJO_EDK_SYSTEM_MESSAGE_PIPE_H_
#include <stddef.h>
#include <stdint.h>
#include <vector>
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "mojo/edk/embedder/platform_handle_vector.h"
#include "mojo/edk/system/channel_endpoint_client.h"
#include "mojo/edk/system/dispatcher.h"
#include "mojo/edk/system/handle_signals_state.h"
#include "mojo/edk/system/memory.h"
#include "mojo/edk/system/message_in_transit.h"
#include "mojo/edk/system/message_pipe_endpoint.h"
#include "mojo/edk/system/system_impl_export.h"
#include "mojo/public/c/system/message_pipe.h"
#include "mojo/public/c/system/types.h"
namespace mojo {
namespace system {
class Awakable;
class Channel;
class ChannelEndpoint;
class MessageInTransitQueue;
// |MessagePipe| is the secondary object implementing a message pipe (see the
// explanatory comment in core.cc). It is typically owned by the dispatcher(s)
// corresponding to the local endpoints. This class is thread-safe.
class MOJO_SYSTEM_IMPL_EXPORT MessagePipe : public ChannelEndpointClient {
public:
// Creates a |MessagePipe| with two new |LocalMessagePipeEndpoint|s.
static MessagePipe* CreateLocalLocal();
// Creates a |MessagePipe| with a |LocalMessagePipeEndpoint| on port 0 and a
// |ProxyMessagePipeEndpoint| on port 1. |*channel_endpoint| is set to the
// (newly-created) |ChannelEndpoint| for the latter.
static MessagePipe* CreateLocalProxy(
scoped_refptr<ChannelEndpoint>* channel_endpoint);
// Similar to |CreateLocalProxy()|, except that it'll do so from an existing
// |ChannelEndpoint| (whose |ReplaceClient()| it'll call) and take
// |message_queue|'s contents as already-received incoming messages. If
// |channel_endpoint| is null, this will create a "half-open" message pipe.
static MessagePipe* CreateLocalProxyFromExisting(
MessageInTransitQueue* message_queue,
ChannelEndpoint* channel_endpoint);
// Creates a |MessagePipe| with a |ProxyMessagePipeEndpoint| on port 0 and a
// |LocalMessagePipeEndpoint| on port 1. |*channel_endpoint| is set to the
// (newly-created) |ChannelEndpoint| for the former.
// Note: This is really only needed in tests (outside of tests, this
// configuration arises from a local message pipe having its port 0
// "converted" using |ConvertLocalToProxy()|).
static MessagePipe* CreateProxyLocal(
scoped_refptr<ChannelEndpoint>* channel_endpoint);
// Gets the other port number (i.e., 0 -> 1, 1 -> 0).
static unsigned GetPeerPort(unsigned port);
// Used by |MessagePipeDispatcher::Deserialize()|. Returns true on success (in
// which case, |*message_pipe|/|*port| are set appropriately) and false on
// failure (in which case |*message_pipe| may or may not be set to null).
static bool Deserialize(Channel* channel,
const void* source,
size_t size,
scoped_refptr<MessagePipe>* message_pipe,
unsigned* port);
// Gets the type of the endpoint (used for assertions, etc.).
MessagePipeEndpoint::Type GetType(unsigned port);
// These are called by the dispatcher to implement its methods of
// corresponding names. In all cases, the port |port| must be open.
void CancelAllAwakables(unsigned port);
void Close(unsigned port);
// Unlike |MessagePipeDispatcher::WriteMessage()|, this does not validate its
// arguments.
MojoResult WriteMessage(unsigned port,
UserPointer<const void> bytes,
uint32_t num_bytes,
std::vector<DispatcherTransport>* transports,
MojoWriteMessageFlags flags);
MojoResult ReadMessage(unsigned port,
UserPointer<void> bytes,
UserPointer<uint32_t> num_bytes,
DispatcherVector* dispatchers,
uint32_t* num_dispatchers,
MojoReadMessageFlags flags);
HandleSignalsState GetHandleSignalsState(unsigned port) const;
MojoResult AddAwakable(unsigned port,
Awakable* awakable,
MojoHandleSignals signals,
uint32_t context,
HandleSignalsState* signals_state);
void RemoveAwakable(unsigned port,
Awakable* awakable,
HandleSignalsState* signals_state);
void StartSerialize(unsigned port,
Channel* channel,
size_t* max_size,
size_t* max_platform_handles);
bool EndSerialize(unsigned port,
Channel* channel,
void* destination,
size_t* actual_size,
embedder::PlatformHandleVector* platform_handles);
// |ChannelEndpointClient| methods:
bool OnReadMessage(unsigned port, MessageInTransit* message) override;
void OnDetachFromChannel(unsigned port) override;
private:
MessagePipe();
~MessagePipe() override;
// This is used internally by |WriteMessage()| and by |OnReadMessage()|.
// |transports| may be non-null only if it's nonempty and |message| has no
// dispatchers attached. Must be called with |lock_| held.
MojoResult EnqueueMessageNoLock(unsigned port,
scoped_ptr<MessageInTransit> message,
std::vector<DispatcherTransport>* transports);
// Helper for |EnqueueMessageNoLock()|. Must be called with |lock_| held.
MojoResult AttachTransportsNoLock(
unsigned port,
MessageInTransit* message,
std::vector<DispatcherTransport>* transports);
base::Lock lock_; // Protects the following members.
scoped_ptr<MessagePipeEndpoint> endpoints_[2];
DISALLOW_COPY_AND_ASSIGN(MessagePipe);
};
} // namespace system
} // namespace mojo
#endif // MOJO_EDK_SYSTEM_MESSAGE_PIPE_H_
|