Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(365)

Unified Diff: mojo/system/shared_buffer_dispatcher.cc

Issue 304233005: Mojo: Implement passing of shared buffers across processes on POSIX. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mojo/system/shared_buffer_dispatcher.cc
diff --git a/mojo/system/shared_buffer_dispatcher.cc b/mojo/system/shared_buffer_dispatcher.cc
index 3c94c8aca5a067772f2866e170a04a00a030656f..7d7ee2c1eb1e69335ac5363218b8a2740ba09f1c 100644
--- a/mojo/system/shared_buffer_dispatcher.cc
+++ b/mojo/system/shared_buffer_dispatcher.cc
@@ -15,6 +15,15 @@
namespace mojo {
namespace system {
+namespace {
+
+struct SerializedSharedBufferDispatcher {
+ size_t num_bytes;
+ size_t platform_handle_index;
+};
+
+} // namespace
+
// static
MojoResult SharedBufferDispatcher::ValidateOptions(
const MojoCreateSharedBufferOptions* in_options,
@@ -61,6 +70,55 @@ Dispatcher::Type SharedBufferDispatcher::GetType() const {
return kTypeSharedBuffer;
}
+// static
+scoped_refptr<SharedBufferDispatcher> SharedBufferDispatcher::Deserialize(
+ Channel* channel,
+ const void* source,
+ size_t size,
+ embedder::PlatformHandleVector* platform_handles) {
+ if (size != sizeof(SerializedSharedBufferDispatcher)) {
+ LOG(ERROR) << "Invalid serialized shared buffer dispatcher (bad size)";
yzshen1 2014/05/30 00:09:35 nit: extra space before "dispatcher".
+ return scoped_refptr<SharedBufferDispatcher>();
+ }
+
+ const SerializedSharedBufferDispatcher* serialization =
+ static_cast<const SerializedSharedBufferDispatcher*>(source);
+ size_t num_bytes = serialization->num_bytes;
+ size_t platform_handle_index = serialization->platform_handle_index;
+
+ if (!num_bytes) {
+ LOG(ERROR)
+ << "Invalid serialized shared buffer dispatcher (invalid num_bytes)";
+ return scoped_refptr<SharedBufferDispatcher>();
+ }
+
+ if (!platform_handles || platform_handle_index >= platform_handles->size()) {
+ LOG(ERROR)
+ << "Invalid serialized shared buffer dispatcher (missing handles)";
+ return scoped_refptr<SharedBufferDispatcher>();
+ }
+
+ // Starts off invalid, which is what we want.
+ embedder::PlatformHandle platform_handle;
+ // We take ownership of the handle, so we have to invalidate the one in
+ // |platform_handles|.
+ std::swap(platform_handle, (*platform_handles)[platform_handle_index]);
+
+ // Wrapping |platform_handle| in a |ScopedPlatformHandle| means that it'll be
+ // closed even if creation fails.
+ scoped_refptr<RawSharedBuffer> shared_buffer(
+ RawSharedBuffer::CreateFromPlatformHandle(num_bytes,
+ embedder::ScopedPlatformHandle(platform_handle)));
+ if (!shared_buffer) {
+ LOG(ERROR)
yzshen1 2014/05/30 00:09:35 wrong indent.
+ << "Invalid serialized shared buffer dispatcher (invalid num_bytes?)";
+ return scoped_refptr<SharedBufferDispatcher>();
+ }
+
+ return scoped_refptr<SharedBufferDispatcher>(new SharedBufferDispatcher(
+ shared_buffer));
+}
+
SharedBufferDispatcher::SharedBufferDispatcher(
scoped_refptr<RawSharedBuffer> shared_buffer)
: shared_buffer_(shared_buffer) {
@@ -132,6 +190,47 @@ MojoResult SharedBufferDispatcher::MapBufferImplNoLock(
return MOJO_RESULT_OK;
}
+void SharedBufferDispatcher::StartSerializeImplNoLock(
+ Channel* /*channel*/,
+ size_t* max_size,
+ size_t* max_platform_handles) {
+ DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
+ *max_size = sizeof(SerializedSharedBufferDispatcher);
+ *max_platform_handles = 1;
+}
+
+bool SharedBufferDispatcher::EndSerializeAndCloseImplNoLock(
+ Channel* /*channel*/,
+ void* destination,
+ size_t* actual_size,
+ embedder::PlatformHandleVector* platform_handles) {
+ DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
+ DCHECK(shared_buffer_);
+
+ SerializedSharedBufferDispatcher* serialization =
+ static_cast<SerializedSharedBufferDispatcher*>(destination);
+ // If there's only one reference to |shared_buffer_|, then it's ours (and no
+ // one else can make any more references to it), so we can just take its
+ // handle.
+ embedder::ScopedPlatformHandle platform_handle(
+ shared_buffer_->HasOneRef() ?
+ shared_buffer_->PassPlatformHandle() :
+ shared_buffer_->DuplicatePlatformHandle());
+ if (!platform_handle.is_valid()) {
+ shared_buffer_ = NULL;
+ return false;
+ }
+
+ serialization->num_bytes = shared_buffer_->num_bytes();
+ serialization->platform_handle_index = platform_handles->size();
+ platform_handles->push_back(platform_handle.release());
+ *actual_size = sizeof(SerializedSharedBufferDispatcher);
+
+ shared_buffer_ = NULL;
+
+ return true;
+}
+
MojoWaitFlags SharedBufferDispatcher::SatisfiedFlagsNoLock() const {
// TODO(vtl): Add transferrable flag.
return MOJO_WAIT_FLAG_NONE;
« mojo/system/raw_shared_buffer_posix.cc ('K') | « mojo/system/shared_buffer_dispatcher.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698