EDK: Plumb Handle/HandleVector yet one more layer down: MessageInTransit.
The "remaining" layer is TransportData and things that deal with it
(e.g., serialization code).
R=azani@chromium.org
Review URL: https://codereview.chromium.org/1957553003 .
diff --git a/mojo/edk/system/channel_endpoint.cc b/mojo/edk/system/channel_endpoint.cc
index 6de03d3..204914d 100644
--- a/mojo/edk/system/channel_endpoint.cc
+++ b/mojo/edk/system/channel_endpoint.cc
@@ -165,7 +165,7 @@
DCHECK(local_id_.is_valid());
DCHECK(remote_id_.is_valid());
- message->SerializeAndCloseDispatchers(channel_);
+ message->SerializeAndCloseHandles(channel_);
message->set_source_id(local_id_);
message->set_destination_id(remote_id_);
return channel_->WriteMessage(std::move(message));
diff --git a/mojo/edk/system/local_message_pipe_endpoint.cc b/mojo/edk/system/local_message_pipe_endpoint.cc
index b8a75ac..dd0c953 100644
--- a/mojo/edk/system/local_message_pipe_endpoint.cc
+++ b/mojo/edk/system/local_message_pipe_endpoint.cc
@@ -9,7 +9,6 @@
#include <utility>
#include "base/logging.h"
-#include "mojo/edk/system/dispatcher.h"
#include "mojo/edk/system/message_in_transit.h"
namespace mojo {
@@ -95,24 +94,15 @@
else
enough_space = false;
- if (DispatcherVector* queued_dispatchers = message->dispatchers()) {
+ if (HandleVector* queued_handles = message->handles()) {
if (num_handles)
- *num_handles = static_cast<uint32_t>(queued_dispatchers->size());
+ *num_handles = static_cast<uint32_t>(queued_handles->size());
if (enough_space) {
- if (queued_dispatchers->empty()) {
+ if (queued_handles->empty()) {
// Nothing to do.
- } else if (queued_dispatchers->size() <= max_num_handles) {
+ } else if (queued_handles->size() <= max_num_handles) {
DCHECK(handles);
- // TODO(vtl): The rest of this code in this block is temporary, until I
- // plumb |Handle|s into |MessageInTransit|. This should really just be
- // something like:
- // handles->swap(*queued_handles);
- handles->reserve(queued_dispatchers->size());
- for (size_t i = 0; i < queued_dispatchers->size(); i++) {
- // We're not enforcing handle rights yet, so "none" is OK.
- handles->push_back(Handle(std::move(queued_dispatchers->at(i)),
- MOJO_HANDLE_RIGHT_NONE));
- }
+ handles->swap(*queued_handles);
} else {
enough_space = false;
}
diff --git a/mojo/edk/system/message_in_transit.cc b/mojo/edk/system/message_in_transit.cc
index 26e9252..4dbcf7d 100644
--- a/mojo/edk/system/message_in_transit.cc
+++ b/mojo/edk/system/message_in_transit.cc
@@ -109,13 +109,13 @@
}
MessageInTransit::~MessageInTransit() {
- if (dispatchers_) {
- for (size_t i = 0; i < dispatchers_->size(); i++) {
- if (!(*dispatchers_)[i])
+ if (handles_) {
+ for (size_t i = 0; i < handles_->size(); i++) {
+ if (!handles_->at(i))
continue;
- (*dispatchers_)[i]->AssertHasOneRef();
- (*dispatchers_)[i]->Close();
+ handles_->at(i).dispatcher->AssertHasOneRef();
+ handles_->at(i).dispatcher->Close();
}
}
}
@@ -141,39 +141,51 @@
return true;
}
+void MessageInTransit::SetHandles(std::unique_ptr<HandleVector> handles) {
+ DCHECK(handles);
+ DCHECK(!handles_);
+ DCHECK(!transport_data_);
+
+ handles_ = std::move(handles);
+#ifndef NDEBUG
+ for (size_t i = 0; i < handles_->size(); i++) {
+ if (handles_->at(i))
+ handles_->at(i).dispatcher->AssertHasOneRef();
+ }
+#endif
+}
+
void MessageInTransit::SetDispatchers(
std::unique_ptr<DispatcherVector> dispatchers) {
DCHECK(dispatchers);
- DCHECK(!dispatchers_);
- DCHECK(!transport_data_);
- dispatchers_ = std::move(dispatchers);
-#ifndef NDEBUG
- for (size_t i = 0; i < dispatchers_->size(); i++) {
- if ((*dispatchers_)[i])
- (*dispatchers_)[i]->AssertHasOneRef();
+ std::unique_ptr<HandleVector> handles(new HandleVector());
+ handles->reserve(dispatchers->size());
+ for (size_t i = 0; i < dispatchers->size(); i++) {
+ handles->push_back(
+ Handle(std::move(dispatchers->at(i)), MOJO_HANDLE_RIGHT_NONE));
}
-#endif
+ SetHandles(std::move(handles));
}
void MessageInTransit::SetTransportData(
std::unique_ptr<TransportData> transport_data) {
DCHECK(transport_data);
DCHECK(!transport_data_);
- DCHECK(!dispatchers_);
+ DCHECK(!handles_);
transport_data_ = std::move(transport_data);
UpdateTotalSize();
}
-void MessageInTransit::SerializeAndCloseDispatchers(Channel* channel) {
+void MessageInTransit::SerializeAndCloseHandles(Channel* channel) {
DCHECK(channel);
DCHECK(!transport_data_);
- if (!dispatchers_ || !dispatchers_->size())
+ if (!handles_ || !handles_->size())
return;
- transport_data_.reset(new TransportData(std::move(dispatchers_), channel));
+ transport_data_.reset(new TransportData(std::move(handles_), channel));
// Update the sizes in the message header.
UpdateTotalSize();
@@ -191,8 +203,8 @@
header()->destination_id = ChannelEndpointId();
header()->num_bytes = num_bytes;
header()->unused = 0;
- // Note: If dispatchers are subsequently attached, then |total_size| will have
- // to be adjusted.
+ // Note: If handles are subsequently attached, then |total_size| will have to
+ // be adjusted.
UpdateTotalSize();
}
diff --git a/mojo/edk/system/message_in_transit.h b/mojo/edk/system/message_in_transit.h
index 2d5c049..f2ec026 100644
--- a/mojo/edk/system/message_in_transit.h
+++ b/mojo/edk/system/message_in_transit.h
@@ -15,6 +15,7 @@
#include "mojo/edk/platform/aligned_alloc.h"
#include "mojo/edk/system/channel_endpoint_id.h"
#include "mojo/edk/system/dispatcher.h"
+#include "mojo/edk/system/handle.h"
#include "mojo/edk/system/memory.h"
#include "mojo/public/cpp/system/macros.h"
@@ -183,21 +184,23 @@
size_t buffer_size,
size_t* next_message_size);
- // Makes this message "own" the given set of dispatchers. The dispatchers must
- // not be referenced from anywhere else (in particular, not from the handle
- // table), i.e., each dispatcher must have a reference count of 1. This
- // message must not already have dispatchers.
+ // Makes this message "own" the given set of handles. Each handle's dispatcher
+ // must not be referenced from anywhere else (in particular, not from any
+ // handle in the handle table), i.e., the dispatcher must have a reference
+ // count of 1. This message must not already have handles.
+ void SetHandles(std::unique_ptr<HandleVector> handles);
+ // TODO(vtl): Delete this.
void SetDispatchers(std::unique_ptr<DispatcherVector> dispatchers);
// Sets the |TransportData| for this message. This should only be done when
- // there are no dispatchers and no existing |TransportData|.
+ // there are no handles and no existing |TransportData|.
void SetTransportData(std::unique_ptr<TransportData> transport_data);
- // Serializes any dispatchers to the secondary buffer. This message must not
+ // Serializes any handles to the secondary buffer. This message must not
// already have a secondary buffer (so this must only be called once). The
// caller must ensure (e.g., by holding on to a reference) that |channel|
// stays alive through the call.
- void SerializeAndCloseDispatchers(Channel* channel);
+ void SerializeAndCloseHandles(Channel* channel);
// Gets the main buffer and its size (in number of bytes), respectively.
const void* main_buffer() const { return main_buffer_.get(); }
@@ -229,15 +232,13 @@
header()->destination_id = destination_id;
}
- // Gets the dispatchers attached to this message; this may return null if
- // there are none. Note that the caller may mutate the set of dispatchers
- // (e.g., take ownership of all the dispatchers, leaving the vector empty).
- DispatcherVector* dispatchers() { return dispatchers_.get(); }
+ // Gets the handles attached to this message; this may return null if there
+ // are none. Note that the caller may mutate the set of handles (e.g., take
+ // ownership of all the handles, leaving the vector empty).
+ HandleVector* handles() { return handles_.get(); }
- // Returns true if this message has dispatchers attached.
- bool has_dispatchers() const {
- return dispatchers_ && !dispatchers_->empty();
- }
+ // Returns true if this message has handles attached.
+ bool has_handles() const { return handles_ && !handles_->empty(); }
// Rounds |n| up to a multiple of |kMessageAlignment|.
static inline size_t RoundUpMessageAlignment(size_t n) {
@@ -254,8 +255,8 @@
// Total size of the message, including the header, the message data
// ("bytes") including padding (to make it a multiple of |kMessageAlignment|
// bytes), and serialized handle information. Note that this may not be the
- // correct value if dispatchers are attached but
- // |SerializeAndCloseDispatchers()| has not been called.
+ // correct value if handles are attached but |SerializeAndCloseHandles()|
+ // has not been called.
uint32_t total_size;
Type type; // 2 bytes.
Subtype subtype; // 2 bytes.
@@ -280,11 +281,11 @@
std::unique_ptr<TransportData> transport_data_; // May be null.
- // Any dispatchers that may be attached to this message. These dispatchers
- // should be "owned" by this message, i.e., have a ref count of exactly 1. (We
- // allow a dispatcher entry to be null, in case it couldn't be duplicated for
- // some reason.)
- std::unique_ptr<DispatcherVector> dispatchers_;
+ // Any handles that may be attached to this message. These handles should be
+ // "owned" by this message, i.e., their dispatcher have a ref count of exactly
+ // 1. (We allow a handle entry to be "null"/invalid, in case it couldn't be
+ // duplicated for some reason.)
+ std::unique_ptr<HandleVector> handles_;
MOJO_DISALLOW_COPY_AND_ASSIGN(MessageInTransit);
};
diff --git a/mojo/edk/system/message_pipe.cc b/mojo/edk/system/message_pipe.cc
index 5c73ac9..a1d2d13 100644
--- a/mojo/edk/system/message_pipe.cc
+++ b/mojo/edk/system/message_pipe.cc
@@ -356,24 +356,22 @@
unsigned port,
MessageInTransit* message,
std::vector<HandleTransport>* transports) {
- DCHECK(!message->has_dispatchers());
+ DCHECK(!message->has_handles());
- // Clone the dispatchers and attach them to the message. (This must be done as
- // a separate loop, since we want to leave the dispatchers alone on failure.)
- std::unique_ptr<DispatcherVector> dispatchers(new DispatcherVector());
- dispatchers->reserve(transports->size());
+ // Clone the handles and attach them to the message. (This must be done as a
+ // separate loop, since we want to leave the handles alone on failure.)
+ std::unique_ptr<HandleVector> handles(new HandleVector());
+ handles->reserve(transports->size());
for (size_t i = 0; i < transports->size(); i++) {
if ((*transports)[i].is_valid()) {
- // TODO(vtl): Plumb this into |MessageInTransit|. (I.e., |dispatchers| ->
- // |handles|, etc.)
- Handle h = (*transports)[i].CreateEquivalentHandleAndClose(this, port);
- dispatchers->push_back(std::move(h.dispatcher));
+ handles->push_back(
+ transports->at(i).CreateEquivalentHandleAndClose(this, port));
} else {
LOG(WARNING) << "Enqueueing null dispatcher";
- dispatchers->push_back(nullptr);
+ handles->push_back(Handle());
}
}
- message->SetDispatchers(std::move(dispatchers));
+ message->SetHandles(std::move(handles));
return MOJO_RESULT_OK;
}
diff --git a/mojo/edk/system/transport_data.cc b/mojo/edk/system/transport_data.cc
index fedfce6..058d795 100644
--- a/mojo/edk/system/transport_data.cc
+++ b/mojo/edk/system/transport_data.cc
@@ -19,6 +19,22 @@
namespace mojo {
namespace system {
+namespace {
+
+// TODO(vtl): Temporary, until |TransportData| really supports handles.
+std::unique_ptr<DispatcherVector> DispatcherVectorFromHandleVector(
+ std::unique_ptr<HandleVector> handles) {
+ DCHECK(handles);
+
+ std::unique_ptr<DispatcherVector> dispatchers(new DispatcherVector());
+ dispatchers->reserve(handles->size());
+ for (size_t i = 0; i < handles->size(); i++)
+ dispatchers->push_back(std::move(handles->at(i).dispatcher));
+ return dispatchers;
+}
+
+} // namespace
+
// The maximum amount of space needed per platform handle.
// (|{Channel,RawChannel}::GetSerializedPlatformHandleSize()| should always
// return a value which is at most this. This is only used to calculate
@@ -63,6 +79,12 @@
"alignment");
};
+// TODO(vtl): Make this the real one.
+TransportData::TransportData(std::unique_ptr<HandleVector> handles,
+ Channel* channel)
+ : TransportData(DispatcherVectorFromHandleVector(std::move(handles)),
+ channel) {}
+
TransportData::TransportData(std::unique_ptr<DispatcherVector> dispatchers,
Channel* channel)
: buffer_size_() {
diff --git a/mojo/edk/system/transport_data.h b/mojo/edk/system/transport_data.h
index 771e071..8698a6d 100644
--- a/mojo/edk/system/transport_data.h
+++ b/mojo/edk/system/transport_data.h
@@ -86,6 +86,8 @@
// The maximum total number of platform handles that may be attached.
static size_t GetMaxPlatformHandles();
+ TransportData(std::unique_ptr<HandleVector> handles, Channel* channel);
+ // TODO(vtl): Remove this, once |TransportData| really supports handles.
TransportData(std::unique_ptr<DispatcherVector> dispatchers,
Channel* channel);