Index: mojo/edk/system/shared_buffer_dispatcher.cc |
diff --git a/mojo/edk/system/shared_buffer_dispatcher.cc b/mojo/edk/system/shared_buffer_dispatcher.cc |
index 6f05b8020e911a60d47eff8498ac36e5496c8d54..94b3d2838e94ac634b325bdda5f698d1a7aace2a 100644 |
--- a/mojo/edk/system/shared_buffer_dispatcher.cc |
+++ b/mojo/edk/system/shared_buffer_dispatcher.cc |
@@ -7,7 +7,6 @@ |
#include <stddef.h> |
#include <stdint.h> |
-#include <algorithm> |
#include <limits> |
#include <utility> |
@@ -25,8 +24,7 @@ namespace edk { |
namespace { |
struct MOJO_ALIGNAS(8) SerializedSharedBufferDispatcher { |
- MOJO_ALIGNAS(4) uint32_t num_bytes; |
- MOJO_ALIGNAS(4) uint32_t platform_handle_index; |
+ size_t num_bytes; |
Anand Mistry (off Chromium)
2016/01/28 02:26:24
Please don't use size_t in serialised messages.
|
}; |
} // namespace |
@@ -85,33 +83,28 @@ MojoResult SharedBufferDispatcher::Create( |
return MOJO_RESULT_OK; |
} |
-Dispatcher::Type SharedBufferDispatcher::GetType() const { |
- return Type::SHARED_BUFFER; |
-} |
- |
// static |
scoped_refptr<SharedBufferDispatcher> SharedBufferDispatcher::Deserialize( |
- const void* source, |
- size_t size, |
- PlatformHandleVector* platform_handles) { |
- |
- if (size != sizeof(SerializedSharedBufferDispatcher)) { |
+ const void* bytes, |
+ size_t num_bytes, |
+ const ports::PortName* ports, |
+ size_t num_ports, |
+ PlatformHandle* platform_handles, |
+ size_t num_platform_handles) { |
+ if (num_bytes != sizeof(SerializedSharedBufferDispatcher)) { |
LOG(ERROR) << "Invalid serialized shared buffer dispatcher (bad size)"; |
return nullptr; |
} |
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) { |
+ static_cast<const SerializedSharedBufferDispatcher*>(bytes); |
+ if (!serialization->num_bytes) { |
LOG(ERROR) |
<< "Invalid serialized shared buffer dispatcher (invalid num_bytes)"; |
return nullptr; |
} |
- if (!platform_handles || platform_handle_index >= platform_handles->size()) { |
+ if (!platform_handles || num_platform_handles != 1 || num_ports) { |
LOG(ERROR) |
<< "Invalid serialized shared buffer dispatcher (missing handles)"; |
return nullptr; |
@@ -121,13 +114,13 @@ scoped_refptr<SharedBufferDispatcher> SharedBufferDispatcher::Deserialize( |
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]); |
+ std::swap(platform_handle, *platform_handles); |
// Wrapping |platform_handle| in a |ScopedPlatformHandle| means that it'll be |
// closed even if creation fails. |
scoped_refptr<PlatformSharedBuffer> shared_buffer( |
internal::g_platform_support->CreateSharedBufferFromHandle( |
- num_bytes, ScopedPlatformHandle(platform_handle))); |
+ serialization->num_bytes, ScopedPlatformHandle(platform_handle))); |
if (!shared_buffer) { |
LOG(ERROR) |
<< "Invalid serialized shared buffer dispatcher (invalid num_bytes?)"; |
@@ -137,91 +130,52 @@ scoped_refptr<SharedBufferDispatcher> SharedBufferDispatcher::Deserialize( |
return CreateInternal(std::move(shared_buffer)); |
} |
-SharedBufferDispatcher::SharedBufferDispatcher( |
- scoped_refptr<PlatformSharedBuffer> shared_buffer) |
- : shared_buffer_(shared_buffer) { |
- DCHECK(shared_buffer_); |
-} |
- |
-SharedBufferDispatcher::~SharedBufferDispatcher() { |
+Dispatcher::Type SharedBufferDispatcher::GetType() const { |
+ return Type::SHARED_BUFFER; |
} |
-// static |
-MojoResult SharedBufferDispatcher::ValidateDuplicateOptions( |
- const MojoDuplicateBufferHandleOptions* in_options, |
- MojoDuplicateBufferHandleOptions* out_options) { |
- const MojoDuplicateBufferHandleOptionsFlags kKnownFlags = |
- MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE; |
- static const MojoDuplicateBufferHandleOptions kDefaultOptions = { |
- static_cast<uint32_t>(sizeof(MojoDuplicateBufferHandleOptions)), |
- MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE}; |
- |
- *out_options = kDefaultOptions; |
- if (!in_options) |
- return MOJO_RESULT_OK; |
- |
- UserOptionsReader<MojoDuplicateBufferHandleOptions> reader(in_options); |
- if (!reader.is_valid()) |
+MojoResult SharedBufferDispatcher::Close() { |
+ base::AutoLock lock(lock_); |
+ if (!shared_buffer_ || in_transit_) |
return MOJO_RESULT_INVALID_ARGUMENT; |
- if (!OPTIONS_STRUCT_HAS_MEMBER(MojoDuplicateBufferHandleOptions, flags, |
- reader)) |
- return MOJO_RESULT_OK; |
- if ((reader.options().flags & ~kKnownFlags)) |
- return MOJO_RESULT_UNIMPLEMENTED; |
- out_options->flags = reader.options().flags; |
- |
- // Checks for fields beyond |flags|: |
- |
- // (Nothing here yet.) |
- |
- return MOJO_RESULT_OK; |
-} |
- |
-void SharedBufferDispatcher::CloseImplNoLock() { |
- lock().AssertAcquired(); |
- DCHECK(shared_buffer_); |
shared_buffer_ = nullptr; |
+ return MOJO_RESULT_OK; |
} |
-scoped_refptr<Dispatcher> |
-SharedBufferDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { |
- lock().AssertAcquired(); |
- DCHECK(shared_buffer_); |
- return CreateInternal(std::move(shared_buffer_)); |
-} |
- |
-MojoResult SharedBufferDispatcher::DuplicateBufferHandleImplNoLock( |
+MojoResult SharedBufferDispatcher::DuplicateBufferHandle( |
const MojoDuplicateBufferHandleOptions* options, |
scoped_refptr<Dispatcher>* new_dispatcher) { |
- lock().AssertAcquired(); |
- |
MojoDuplicateBufferHandleOptions validated_options; |
MojoResult result = ValidateDuplicateOptions(options, &validated_options); |
if (result != MOJO_RESULT_OK) |
return result; |
// Note: Since this is "duplicate", we keep our ref to |shared_buffer_|. |
+ base::AutoLock lock(lock_); |
+ if (in_transit_) |
+ return MOJO_RESULT_INVALID_ARGUMENT; |
*new_dispatcher = CreateInternal(shared_buffer_); |
return MOJO_RESULT_OK; |
} |
-MojoResult SharedBufferDispatcher::MapBufferImplNoLock( |
+MojoResult SharedBufferDispatcher::MapBuffer( |
uint64_t offset, |
uint64_t num_bytes, |
MojoMapBufferFlags flags, |
scoped_ptr<PlatformSharedBufferMapping>* mapping) { |
- lock().AssertAcquired(); |
- DCHECK(shared_buffer_); |
- |
if (offset > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) |
return MOJO_RESULT_INVALID_ARGUMENT; |
if (num_bytes > static_cast<uint64_t>(std::numeric_limits<size_t>::max())) |
return MOJO_RESULT_INVALID_ARGUMENT; |
- if (!shared_buffer_->IsValidMap(static_cast<size_t>(offset), |
- static_cast<size_t>(num_bytes))) |
+ base::AutoLock lock(lock_); |
+ DCHECK(shared_buffer_); |
+ if (in_transit_ || |
+ !shared_buffer_->IsValidMap(static_cast<size_t>(offset), |
+ static_cast<size_t>(num_bytes))) { |
return MOJO_RESULT_INVALID_ARGUMENT; |
+ } |
DCHECK(mapping); |
*mapping = shared_buffer_->MapNoCheck(static_cast<size_t>(offset), |
@@ -232,46 +186,93 @@ MojoResult SharedBufferDispatcher::MapBufferImplNoLock( |
return MOJO_RESULT_OK; |
} |
-void SharedBufferDispatcher::StartSerializeImplNoLock( |
- size_t* max_size, |
- size_t* max_platform_handles) { |
- *max_size = sizeof(SerializedSharedBufferDispatcher); |
- *max_platform_handles = 1; |
+void SharedBufferDispatcher::StartSerialize(uint32_t* num_bytes, |
+ uint32_t* num_ports, |
+ uint32_t* num_platform_handles) { |
+ *num_bytes = sizeof(SerializedSharedBufferDispatcher); |
+ *num_ports = 0; |
+ *num_platform_handles = 1; |
} |
-bool SharedBufferDispatcher::EndSerializeAndCloseImplNoLock( |
- void* destination, |
- size_t* actual_size, |
- PlatformHandleVector* platform_handles) { |
- DCHECK(shared_buffer_); |
- |
+bool SharedBufferDispatcher::EndSerialize(void* destination, |
+ ports::PortName* ports, |
+ PlatformHandle* handles) { |
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. |
- ScopedPlatformHandle platform_handle( |
- shared_buffer_->HasOneRef() ? shared_buffer_->PassPlatformHandle() |
- : shared_buffer_->DuplicatePlatformHandle()); |
- if (!platform_handle.is_valid()) { |
+ base::AutoLock lock(lock_); |
+ serialization->num_bytes = shared_buffer_->GetNumBytes(); |
+ |
+ handle_for_transit_ = shared_buffer_->DuplicatePlatformHandle(); |
+ if (!handle_for_transit_.is_valid()) { |
shared_buffer_ = nullptr; |
return false; |
} |
+ handles[0] = handle_for_transit_.get(); |
+ return true; |
+} |
- DCHECK(shared_buffer_->GetNumBytes() < std::numeric_limits<uint32_t>::max()); |
- serialization->num_bytes = |
- static_cast<uint32_t>(shared_buffer_->GetNumBytes()); |
- DCHECK(platform_handles->size() < std::numeric_limits<uint32_t>::max()); |
- serialization->platform_handle_index = |
- static_cast<uint32_t>(platform_handles->size()); |
- platform_handles->push_back(platform_handle.release()); |
- *actual_size = sizeof(SerializedSharedBufferDispatcher); |
+bool SharedBufferDispatcher::BeginTransit() { |
+ base::AutoLock lock(lock_); |
+ if (in_transit_) |
+ return false; |
+ in_transit_ = shared_buffer_ != nullptr; |
+ return in_transit_; |
+} |
+void SharedBufferDispatcher::CompleteTransitAndClose() { |
+ base::AutoLock lock(lock_); |
+ in_transit_ = false; |
shared_buffer_ = nullptr; |
+ ignore_result(handle_for_transit_.release()); |
+} |
- return true; |
+void SharedBufferDispatcher::CancelTransit() { |
+ base::AutoLock lock(lock_); |
+ in_transit_ = false; |
+ handle_for_transit_.reset(); |
+} |
+ |
+SharedBufferDispatcher::SharedBufferDispatcher( |
+ scoped_refptr<PlatformSharedBuffer> shared_buffer) |
+ : shared_buffer_(shared_buffer) { |
+ DCHECK(shared_buffer_); |
} |
+SharedBufferDispatcher::~SharedBufferDispatcher() { |
+ DCHECK(!shared_buffer_ && !in_transit_); |
+} |
+ |
+// static |
+MojoResult SharedBufferDispatcher::ValidateDuplicateOptions( |
+ const MojoDuplicateBufferHandleOptions* in_options, |
+ MojoDuplicateBufferHandleOptions* out_options) { |
+ const MojoDuplicateBufferHandleOptionsFlags kKnownFlags = |
+ MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE; |
+ static const MojoDuplicateBufferHandleOptions kDefaultOptions = { |
+ static_cast<uint32_t>(sizeof(MojoDuplicateBufferHandleOptions)), |
+ MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE}; |
+ |
+ *out_options = kDefaultOptions; |
+ if (!in_options) |
+ return MOJO_RESULT_OK; |
+ |
+ UserOptionsReader<MojoDuplicateBufferHandleOptions> reader(in_options); |
+ if (!reader.is_valid()) |
+ return MOJO_RESULT_INVALID_ARGUMENT; |
+ |
+ if (!OPTIONS_STRUCT_HAS_MEMBER(MojoDuplicateBufferHandleOptions, flags, |
+ reader)) |
+ return MOJO_RESULT_OK; |
+ if ((reader.options().flags & ~kKnownFlags)) |
+ return MOJO_RESULT_UNIMPLEMENTED; |
+ out_options->flags = reader.options().flags; |
+ |
+ // Checks for fields beyond |flags|: |
+ |
+ // (Nothing here yet.) |
+ |
+ return MOJO_RESULT_OK; |
+} |
} // namespace edk |
} // namespace mojo |