From 388ba91f3896021ae25dd902198e24f71a3c6404 Mon Sep 17 00:00:00 2001 From: "viettrungluu@chromium.org" Date: Tue, 1 Apr 2014 16:38:46 +0000 Subject: Mojo: Move mojo/public/bindings/lib to mojo/public/cpp/bindings/lib. R=darin@chromium.org Review URL: https://codereview.chromium.org/220243007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@260886 0039d316-1c4b-4281-b951-d872f2087c98 --- mojo/mojo_public.gypi | 52 +-- .../cpp_templates/module-internal.h.tmpl | 2 +- .../generators/cpp_templates/module.cc.tmpl | 4 +- mojo/public/bindings/lib/DEPS | 8 - mojo/public/bindings/lib/TODO | 7 - mojo/public/bindings/lib/array.cc | 38 --- mojo/public/bindings/lib/array_internal.cc | 59 ---- mojo/public/bindings/lib/array_internal.h | 372 --------------------- mojo/public/bindings/lib/bindings_internal.h | 141 -------- mojo/public/bindings/lib/bindings_serialization.cc | 73 ---- mojo/public/bindings/lib/bindings_serialization.h | 67 ---- mojo/public/bindings/lib/buffer.cc | 27 -- mojo/public/bindings/lib/callback_internal.h | 55 --- mojo/public/bindings/lib/connector.cc | 130 ------- mojo/public/bindings/lib/connector.h | 80 ----- mojo/public/bindings/lib/fixed_buffer.cc | 54 --- mojo/public/bindings/lib/fixed_buffer.h | 68 ---- mojo/public/bindings/lib/interface.cc | 19 -- mojo/public/bindings/lib/message.cc | 84 ----- mojo/public/bindings/lib/message_builder.cc | 52 --- mojo/public/bindings/lib/message_builder.h | 63 ---- mojo/public/bindings/lib/message_internal.h | 44 --- mojo/public/bindings/lib/message_queue.cc | 50 --- mojo/public/bindings/lib/message_queue.h | 47 --- mojo/public/bindings/lib/router.cc | 137 -------- mojo/public/bindings/lib/router.h | 73 ---- mojo/public/bindings/lib/scratch_buffer.cc | 98 ------ mojo/public/bindings/lib/scratch_buffer.h | 54 --- mojo/public/bindings/lib/shared_data.h | 81 ----- mojo/public/bindings/lib/shared_ptr.h | 63 ---- mojo/public/bindings/lib/sync_dispatcher.cc | 27 -- mojo/public/bindings/tests/array_unittest.cc | 4 +- mojo/public/bindings/tests/buffer_unittest.cc | 6 +- mojo/public/bindings/tests/connector_unittest.cc | 6 +- mojo/public/bindings/tests/router_unittest.cc | 6 +- mojo/public/cpp/bindings/DEPS | 4 - mojo/public/cpp/bindings/allocation_scope.h | 2 +- mojo/public/cpp/bindings/array.h | 2 +- mojo/public/cpp/bindings/callback.h | 4 +- mojo/public/cpp/bindings/callback.h.pump | 4 +- mojo/public/cpp/bindings/lib/DEPS | 5 + mojo/public/cpp/bindings/lib/TODO | 7 + mojo/public/cpp/bindings/lib/array.cc | 38 +++ mojo/public/cpp/bindings/lib/array_internal.cc | 59 ++++ mojo/public/cpp/bindings/lib/array_internal.h | 372 +++++++++++++++++++++ mojo/public/cpp/bindings/lib/bindings_internal.h | 141 ++++++++ .../cpp/bindings/lib/bindings_serialization.cc | 73 ++++ .../cpp/bindings/lib/bindings_serialization.h | 67 ++++ mojo/public/cpp/bindings/lib/buffer.cc | 27 ++ mojo/public/cpp/bindings/lib/callback_internal.h | 55 +++ mojo/public/cpp/bindings/lib/connector.cc | 130 +++++++ mojo/public/cpp/bindings/lib/connector.h | 80 +++++ mojo/public/cpp/bindings/lib/fixed_buffer.cc | 54 +++ mojo/public/cpp/bindings/lib/fixed_buffer.h | 68 ++++ mojo/public/cpp/bindings/lib/interface.cc | 19 ++ mojo/public/cpp/bindings/lib/message.cc | 84 +++++ mojo/public/cpp/bindings/lib/message_builder.cc | 52 +++ mojo/public/cpp/bindings/lib/message_builder.h | 63 ++++ mojo/public/cpp/bindings/lib/message_internal.h | 44 +++ mojo/public/cpp/bindings/lib/message_queue.cc | 50 +++ mojo/public/cpp/bindings/lib/message_queue.h | 47 +++ mojo/public/cpp/bindings/lib/router.cc | 137 ++++++++ mojo/public/cpp/bindings/lib/router.h | 73 ++++ mojo/public/cpp/bindings/lib/scratch_buffer.cc | 98 ++++++ mojo/public/cpp/bindings/lib/scratch_buffer.h | 54 +++ mojo/public/cpp/bindings/lib/shared_data.h | 81 +++++ mojo/public/cpp/bindings/lib/shared_ptr.h | 63 ++++ mojo/public/cpp/bindings/lib/sync_dispatcher.cc | 27 ++ mojo/public/cpp/bindings/message.h | 2 +- mojo/public/cpp/bindings/passable.h | 2 +- mojo/public/cpp/bindings/remote_ptr.h | 2 +- 71 files changed, 2117 insertions(+), 2124 deletions(-) delete mode 100644 mojo/public/bindings/lib/DEPS delete mode 100644 mojo/public/bindings/lib/TODO delete mode 100644 mojo/public/bindings/lib/array.cc delete mode 100644 mojo/public/bindings/lib/array_internal.cc delete mode 100644 mojo/public/bindings/lib/array_internal.h delete mode 100644 mojo/public/bindings/lib/bindings_internal.h delete mode 100644 mojo/public/bindings/lib/bindings_serialization.cc delete mode 100644 mojo/public/bindings/lib/bindings_serialization.h delete mode 100644 mojo/public/bindings/lib/buffer.cc delete mode 100644 mojo/public/bindings/lib/callback_internal.h delete mode 100644 mojo/public/bindings/lib/connector.cc delete mode 100644 mojo/public/bindings/lib/connector.h delete mode 100644 mojo/public/bindings/lib/fixed_buffer.cc delete mode 100644 mojo/public/bindings/lib/fixed_buffer.h delete mode 100644 mojo/public/bindings/lib/interface.cc delete mode 100644 mojo/public/bindings/lib/message.cc delete mode 100644 mojo/public/bindings/lib/message_builder.cc delete mode 100644 mojo/public/bindings/lib/message_builder.h delete mode 100644 mojo/public/bindings/lib/message_internal.h delete mode 100644 mojo/public/bindings/lib/message_queue.cc delete mode 100644 mojo/public/bindings/lib/message_queue.h delete mode 100644 mojo/public/bindings/lib/router.cc delete mode 100644 mojo/public/bindings/lib/router.h delete mode 100644 mojo/public/bindings/lib/scratch_buffer.cc delete mode 100644 mojo/public/bindings/lib/scratch_buffer.h delete mode 100644 mojo/public/bindings/lib/shared_data.h delete mode 100644 mojo/public/bindings/lib/shared_ptr.h delete mode 100644 mojo/public/bindings/lib/sync_dispatcher.cc delete mode 100644 mojo/public/cpp/bindings/DEPS create mode 100644 mojo/public/cpp/bindings/lib/DEPS create mode 100644 mojo/public/cpp/bindings/lib/TODO create mode 100644 mojo/public/cpp/bindings/lib/array.cc create mode 100644 mojo/public/cpp/bindings/lib/array_internal.cc create mode 100644 mojo/public/cpp/bindings/lib/array_internal.h create mode 100644 mojo/public/cpp/bindings/lib/bindings_internal.h create mode 100644 mojo/public/cpp/bindings/lib/bindings_serialization.cc create mode 100644 mojo/public/cpp/bindings/lib/bindings_serialization.h create mode 100644 mojo/public/cpp/bindings/lib/buffer.cc create mode 100644 mojo/public/cpp/bindings/lib/callback_internal.h create mode 100644 mojo/public/cpp/bindings/lib/connector.cc create mode 100644 mojo/public/cpp/bindings/lib/connector.h create mode 100644 mojo/public/cpp/bindings/lib/fixed_buffer.cc create mode 100644 mojo/public/cpp/bindings/lib/fixed_buffer.h create mode 100644 mojo/public/cpp/bindings/lib/interface.cc create mode 100644 mojo/public/cpp/bindings/lib/message.cc create mode 100644 mojo/public/cpp/bindings/lib/message_builder.cc create mode 100644 mojo/public/cpp/bindings/lib/message_builder.h create mode 100644 mojo/public/cpp/bindings/lib/message_internal.h create mode 100644 mojo/public/cpp/bindings/lib/message_queue.cc create mode 100644 mojo/public/cpp/bindings/lib/message_queue.h create mode 100644 mojo/public/cpp/bindings/lib/router.cc create mode 100644 mojo/public/cpp/bindings/lib/router.h create mode 100644 mojo/public/cpp/bindings/lib/scratch_buffer.cc create mode 100644 mojo/public/cpp/bindings/lib/scratch_buffer.h create mode 100644 mojo/public/cpp/bindings/lib/shared_data.h create mode 100644 mojo/public/cpp/bindings/lib/shared_ptr.h create mode 100644 mojo/public/cpp/bindings/lib/sync_dispatcher.cc diff --git a/mojo/mojo_public.gypi b/mojo/mojo_public.gypi index 9e06c04..84bfe88 100644 --- a/mojo/mojo_public.gypi +++ b/mojo/mojo_public.gypi @@ -248,32 +248,6 @@ 'sources': [ 'public/bindings/js/constants.cc', 'public/bindings/js/constants.h', - 'public/bindings/lib/array.cc', - 'public/bindings/lib/array_internal.h', - 'public/bindings/lib/array_internal.cc', - 'public/bindings/lib/bindings_internal.h', - 'public/bindings/lib/bindings_serialization.cc', - 'public/bindings/lib/bindings_serialization.h', - 'public/bindings/lib/buffer.cc', - 'public/bindings/lib/callback_internal.h', - 'public/bindings/lib/connector.cc', - 'public/bindings/lib/connector.h', - 'public/bindings/lib/fixed_buffer.cc', - 'public/bindings/lib/fixed_buffer.h', - 'public/bindings/lib/interface.cc', - 'public/bindings/lib/message.cc', - 'public/bindings/lib/message_builder.cc', - 'public/bindings/lib/message_builder.h', - 'public/bindings/lib/message_internal.h', - 'public/bindings/lib/message_queue.cc', - 'public/bindings/lib/message_queue.h', - 'public/bindings/lib/router.cc', - 'public/bindings/lib/router.h', - 'public/bindings/lib/scratch_buffer.cc', - 'public/bindings/lib/scratch_buffer.h', - 'public/bindings/lib/shared_data.h', - 'public/bindings/lib/shared_ptr.h', - 'public/bindings/lib/sync_dispatcher.cc', 'public/cpp/bindings/allocation_scope.h', 'public/cpp/bindings/array.h', 'public/cpp/bindings/buffer.h', @@ -285,6 +259,32 @@ 'public/cpp/bindings/remote_ptr.h', 'public/cpp/bindings/sync_dispatcher.h', 'public/cpp/bindings/type_converter.h', + 'public/cpp/bindings/lib/array.cc', + 'public/cpp/bindings/lib/array_internal.h', + 'public/cpp/bindings/lib/array_internal.cc', + 'public/cpp/bindings/lib/bindings_internal.h', + 'public/cpp/bindings/lib/bindings_serialization.cc', + 'public/cpp/bindings/lib/bindings_serialization.h', + 'public/cpp/bindings/lib/buffer.cc', + 'public/cpp/bindings/lib/callback_internal.h', + 'public/cpp/bindings/lib/connector.cc', + 'public/cpp/bindings/lib/connector.h', + 'public/cpp/bindings/lib/fixed_buffer.cc', + 'public/cpp/bindings/lib/fixed_buffer.h', + 'public/cpp/bindings/lib/interface.cc', + 'public/cpp/bindings/lib/message.cc', + 'public/cpp/bindings/lib/message_builder.cc', + 'public/cpp/bindings/lib/message_builder.h', + 'public/cpp/bindings/lib/message_internal.h', + 'public/cpp/bindings/lib/message_queue.cc', + 'public/cpp/bindings/lib/message_queue.h', + 'public/cpp/bindings/lib/router.cc', + 'public/cpp/bindings/lib/router.h', + 'public/cpp/bindings/lib/scratch_buffer.cc', + 'public/cpp/bindings/lib/scratch_buffer.h', + 'public/cpp/bindings/lib/shared_data.h', + 'public/cpp/bindings/lib/shared_ptr.h', + 'public/cpp/bindings/lib/sync_dispatcher.cc', ], }, { diff --git a/mojo/public/bindings/generators/cpp_templates/module-internal.h.tmpl b/mojo/public/bindings/generators/cpp_templates/module-internal.h.tmpl index 6839207..d298cc3 100644 --- a/mojo/public/bindings/generators/cpp_templates/module-internal.h.tmpl +++ b/mojo/public/bindings/generators/cpp_templates/module-internal.h.tmpl @@ -8,7 +8,7 @@ #ifndef {{header_guard}} #define {{header_guard}} -#include "mojo/public/bindings/lib/bindings_internal.h" +#include "mojo/public/cpp/bindings/lib/bindings_internal.h" {%- for import in imports %} #include "{{import.module.path}}-internal.h" {%- endfor %} diff --git a/mojo/public/bindings/generators/cpp_templates/module.cc.tmpl b/mojo/public/bindings/generators/cpp_templates/module.cc.tmpl index 1c530c4..33bd46b 100644 --- a/mojo/public/bindings/generators/cpp_templates/module.cc.tmpl +++ b/mojo/public/bindings/generators/cpp_templates/module.cc.tmpl @@ -9,8 +9,8 @@ #include "{{module.path}}.h" -#include "mojo/public/bindings/lib/bindings_serialization.h" -#include "mojo/public/bindings/lib/message_builder.h" +#include "mojo/public/cpp/bindings/lib/bindings_serialization.h" +#include "mojo/public/cpp/bindings/lib/message_builder.h" namespace {{namespace}} { namespace internal { diff --git a/mojo/public/bindings/lib/DEPS b/mojo/public/bindings/lib/DEPS deleted file mode 100644 index fe8a2b3..0000000 --- a/mojo/public/bindings/lib/DEPS +++ /dev/null @@ -1,8 +0,0 @@ -include_rules = [ - "-mojo", - "+mojo/public/cpp/bindings", - "+mojo/public/cpp/environment", - "+mojo/public/cpp/system", - # TODO(vtl): Temporary, until lib is moved. - "+mojo/public/bindings/lib", -] diff --git a/mojo/public/bindings/lib/TODO b/mojo/public/bindings/lib/TODO deleted file mode 100644 index 318edcf..0000000 --- a/mojo/public/bindings/lib/TODO +++ /dev/null @@ -1,7 +0,0 @@ -TODOs: - - Ensure validation checks are solid - - Add tests of validation logic - - Optimize Buffer classes? - - Make "Clone" method public? - - Add compile-time asserts to verify object packing and padding. - - Investigate making arrays of objects not be arrays of pointers. diff --git a/mojo/public/bindings/lib/array.cc b/mojo/public/bindings/lib/array.cc deleted file mode 100644 index 6745adc..0000000 --- a/mojo/public/bindings/lib/array.cc +++ /dev/null @@ -1,38 +0,0 @@ -// 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. - -#include "mojo/public/cpp/bindings/array.h" - -namespace mojo { - -// static -String TypeConverter::ConvertFrom(const std::string& input, - Buffer* buf) { - String::Builder result(input.size(), buf); - if (!input.empty()) - memcpy(&result[0], input.data(), input.size()); - return result.Finish(); -} -// static -std::string TypeConverter::ConvertTo(const String& input) { - if (input.is_null() || input.size() == 0) - return std::string(); - - return std::string(&input[0], &input[0] + input.size()); -} - -// static -String TypeConverter::ConvertFrom(const char* input, - Buffer* buf) { - if (!input) - return String(); - - size_t size = strlen(input); - String::Builder result(size, buf); - if (size != 0) - memcpy(&result[0], input, size); - return result.Finish(); -} - -} // namespace mojo diff --git a/mojo/public/bindings/lib/array_internal.cc b/mojo/public/bindings/lib/array_internal.cc deleted file mode 100644 index a10fe23..0000000 --- a/mojo/public/bindings/lib/array_internal.cc +++ /dev/null @@ -1,59 +0,0 @@ -// 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. - -#include "mojo/public/bindings/lib/array_internal.h" - -namespace mojo { -namespace internal { - -ArrayDataTraits::BitRef::~BitRef() { -} - -ArrayDataTraits::BitRef::BitRef(uint8_t* storage, uint8_t mask) - : storage_(storage), - mask_(mask) { -} - -ArrayDataTraits::BitRef& -ArrayDataTraits::BitRef::operator=(bool value) { - if (value) { - *storage_ |= mask_; - } else { - *storage_ &= ~mask_; - } - return *this; -} - -ArrayDataTraits::BitRef& -ArrayDataTraits::BitRef::operator=(const BitRef& value) { - return (*this) = static_cast(value); -} - -ArrayDataTraits::BitRef::operator bool() const { - return (*storage_ & mask_) != 0; -} - -// static -void ArraySerializationHelper::EncodePointersAndHandles( - const ArrayHeader* header, - ElementType* elements, - std::vector* handles) { - for (uint32_t i = 0; i < header->num_elements; ++i) - EncodeHandle(&elements[i], handles); -} - -// static -bool ArraySerializationHelper::DecodePointersAndHandles( - const ArrayHeader* header, - ElementType* elements, - Message* message) { - for (uint32_t i = 0; i < header->num_elements; ++i) { - if (!DecodeHandle(&elements[i], message->mutable_handles())) - return false; - } - return true; -} - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/bindings/lib/array_internal.h b/mojo/public/bindings/lib/array_internal.h deleted file mode 100644 index 1ca84d0..0000000 --- a/mojo/public/bindings/lib/array_internal.h +++ /dev/null @@ -1,372 +0,0 @@ -// 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_PUBLIC_BINDINGS_LIB_ARRAY_INTERNAL_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_ARRAY_INTERNAL_H_ - -#include - -#include "mojo/public/bindings/lib/bindings_internal.h" -#include "mojo/public/bindings/lib/bindings_serialization.h" -#include "mojo/public/cpp/bindings/buffer.h" -#include "mojo/public/cpp/bindings/passable.h" -#include "mojo/public/cpp/system/core.h" - -namespace mojo { -template class Array; - -namespace internal { - -template -struct ArrayDataTraits { - typedef T StorageType; - typedef Array Wrapper; - typedef T& Ref; - typedef T const& ConstRef; - - static size_t GetStorageSize(size_t num_elements) { - return sizeof(StorageType) * num_elements; - } - static Ref ToRef(StorageType* storage, size_t offset) { - return storage[offset]; - } - static ConstRef ToConstRef(const StorageType* storage, size_t offset) { - return storage[offset]; - } -}; - -template -struct ArrayDataTraits { - typedef StructPointer

StorageType; - typedef Array Wrapper; - typedef P*& Ref; - typedef P* const& ConstRef; - - static size_t GetStorageSize(size_t num_elements) { - return sizeof(StorageType) * num_elements; - } - static Ref ToRef(StorageType* storage, size_t offset) { - return storage[offset].ptr; - } - static ConstRef ToConstRef(const StorageType* storage, size_t offset) { - return storage[offset].ptr; - } -}; - -// Specialization of Arrays for bools, optimized for space. It has the -// following differences from a generalized Array: -// * Each element takes up a single bit of memory. -// * Accessing a non-const single element uses a helper class |BitRef|, which -// emulates a reference to a bool. -template <> -struct ArrayDataTraits { - // Helper class to emulate a reference to a bool, used for direct element - // access. - class BitRef { - public: - ~BitRef(); - BitRef& operator=(bool value); - BitRef& operator=(const BitRef& value); - operator bool() const; - private: - friend struct ArrayDataTraits; - BitRef(uint8_t* storage, uint8_t mask); - BitRef(); - uint8_t* storage_; - uint8_t mask_; - }; - - typedef uint8_t StorageType; - typedef Array Wrapper; - typedef BitRef Ref; - typedef bool ConstRef; - - static size_t GetStorageSize(size_t num_elements) { - return ((num_elements + 7) / 8); - } - static BitRef ToRef(StorageType* storage, size_t offset) { - return BitRef(&storage[offset / 8], 1 << (offset % 8)); - } - static bool ToConstRef(const StorageType* storage, size_t offset) { - return (storage[offset / 8] & (1 << (offset % 8))) != 0; - } -}; - -// What follows is code to support the serialization of Array_Data. There -// are two interesting cases: arrays of primitives and arrays of objects. -// Arrays of objects are represented as arrays of pointers to objects. - -template -struct ArraySerializationHelper { - typedef T ElementType; - - static size_t ComputeSizeOfElements(const ArrayHeader* header, - const ElementType* elements) { - return 0; - } - - static void CloneElements(const ArrayHeader* header, - ElementType* elements, - Buffer* buf) { - } - - static void EncodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - std::vector* handles) { - } - - static bool DecodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - Message* message) { - return true; - } -}; - -template <> -struct ArraySerializationHelper { - typedef Handle ElementType; - - static size_t ComputeSizeOfElements(const ArrayHeader* header, - const ElementType* elements) { - return 0; - } - - static void CloneElements(const ArrayHeader* header, - ElementType* elements, - Buffer* buf) { - } - - static void EncodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - std::vector* handles); - - static bool DecodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - Message* message); -}; - -template -struct ArraySerializationHelper { - typedef StructPointer

ElementType; - - static size_t ComputeSizeOfElements(const ArrayHeader* header, - const ElementType* elements) { - size_t result = 0; - for (uint32_t i = 0; i < header->num_elements; ++i) { - if (elements[i].ptr) - result += elements[i].ptr->ComputeSize(); - } - return result; - } - - static void CloneElements(const ArrayHeader* header, - ElementType* elements, - Buffer* buf) { - for (uint32_t i = 0; i < header->num_elements; ++i) { - if (elements[i].ptr) - elements[i].ptr = elements[i].ptr->Clone(buf); - } - } - - static void EncodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - std::vector* handles) { - for (uint32_t i = 0; i < header->num_elements; ++i) - Encode(&elements[i], handles); - } - - static bool DecodePointersAndHandles(const ArrayHeader* header, - ElementType* elements, - Message* message) { - for (uint32_t i = 0; i < header->num_elements; ++i) { - if (!Decode(&elements[i], message)) - return false; - } - return true; - } -}; - -template -class Array_Data { - public: - typedef ArrayDataTraits Traits; - typedef typename Traits::StorageType StorageType; - typedef typename Traits::Wrapper Wrapper; - typedef typename Traits::Ref Ref; - typedef typename Traits::ConstRef ConstRef; - - static Array_Data* New(size_t num_elements, Buffer* buf) { - size_t num_bytes = sizeof(Array_Data) + - Traits::GetStorageSize(num_elements); - return new (buf->Allocate(num_bytes)) Array_Data(num_bytes, - num_elements); - } - - size_t size() const { return header_.num_elements; } - - Ref at(size_t offset) { - assert(offset < static_cast(header_.num_elements)); - return Traits::ToRef(storage(), offset); - } - - ConstRef at(size_t offset) const { - assert(offset < static_cast(header_.num_elements)); - return Traits::ToConstRef(storage(), offset); - } - - StorageType* storage() { - return reinterpret_cast( - reinterpret_cast(this) + sizeof(*this)); - } - - const StorageType* storage() const { - return reinterpret_cast( - reinterpret_cast(this) + sizeof(*this)); - } - - size_t ComputeSize() const { - return Align(header_.num_bytes) + - ArraySerializationHelper::ComputeSizeOfElements(&header_, storage()); - } - - Array_Data* Clone(Buffer* buf) const { - Array_Data* clone = New(header_.num_elements, buf); - memcpy(clone->storage(), - storage(), - header_.num_bytes - sizeof(Array_Data)); - - ArraySerializationHelper::CloneElements(&clone->header_, - clone->storage(), buf); - return clone; - } - - void CloseHandles() { - // TODO(darin): Implement! - } - - void EncodePointersAndHandles(std::vector* handles) { - ArraySerializationHelper::EncodePointersAndHandles(&header_, storage(), - handles); - } - - bool DecodePointersAndHandles(Message* message) { - return ArraySerializationHelper::DecodePointersAndHandles(&header_, - storage(), - message); - } - - private: - Array_Data(size_t num_bytes, size_t num_elements) { - header_.num_bytes = static_cast(num_bytes); - header_.num_elements = static_cast(num_elements); - } - ~Array_Data() {} - - internal::ArrayHeader header_; - - // Elements of type internal::ArrayDataTraits::StorageType follow. -}; -MOJO_COMPILE_ASSERT(sizeof(Array_Data) == 8, bad_sizeof_Array_Data); - -// UTF-8 encoded -typedef Array_Data String_Data; - -template struct ArrayTraits {}; - -template struct ArrayTraits { - typedef Array_Data DataType; - typedef const T& ConstRef; - typedef T& Ref; - static typename T::Data* ToArrayElement(const T& value) { - return Unwrap(value); - } - // Something sketchy is indeed happening here... - static Ref ToRef(typename T::Data*& data) { - return *reinterpret_cast(&data); - } - static ConstRef ToConstRef(typename T::Data* const& data) { - return *reinterpret_cast(&data); - } -}; - -template struct ArrayTraits { - typedef Array_Data DataType; - typedef const T& ConstRef; - typedef T& Ref; - static T ToArrayElement(const T& value) { - return value; - } - static Ref ToRef(T& data) { return data; } - static ConstRef ToConstRef(const T& data) { return data; } -}; - -template <> struct ArrayTraits { - typedef Array_Data DataType; - typedef bool ConstRef; - typedef ArrayDataTraits::Ref Ref; - static bool ToArrayElement(const bool& value) { - return value; - } - static Ref ToRef(const Ref& data) { return data; } - static ConstRef ToConstRef(ConstRef data) { return data; } -}; - -template <> struct ArrayTraits { - typedef Array_Data DataType; - typedef Passable ConstRef; - typedef AssignableAndPassable Ref; - static Handle ToArrayElement(const Handle& value) { - return value; - } - static Ref ToRef(Handle& data) { return Ref(&data); } - static ConstRef ToConstRef(const Handle& data) { - return ConstRef(const_cast(&data)); - } -}; - -template <> struct ArrayTraits { - typedef Array_Data DataType; - typedef Passable ConstRef; - typedef AssignableAndPassable Ref; - static DataPipeConsumerHandle ToArrayElement( - const DataPipeConsumerHandle& value) { - return value; - } - static Ref ToRef(DataPipeConsumerHandle& data) { return Ref(&data); } - static ConstRef ToConstRef(const DataPipeConsumerHandle& data) { - return ConstRef(const_cast(&data)); - } -}; - -template <> struct ArrayTraits { - typedef Array_Data DataType; - typedef Passable ConstRef; - typedef AssignableAndPassable Ref; - static DataPipeProducerHandle ToArrayElement( - const DataPipeProducerHandle& value) { - return value; - } - static Ref ToRef(DataPipeProducerHandle& data) { return Ref(&data); } - static ConstRef ToConstRef(const DataPipeProducerHandle& data) { - return ConstRef(const_cast(&data)); - } -}; - -template <> struct ArrayTraits { - typedef Array_Data DataType; - typedef Passable ConstRef; - typedef AssignableAndPassable Ref; - static MessagePipeHandle ToArrayElement(const MessagePipeHandle& value) { - return value; - } - static Ref ToRef(MessagePipeHandle& data) { return Ref(&data); } - static ConstRef ToConstRef(const MessagePipeHandle& data) { - return ConstRef(const_cast(&data)); - } -}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_ARRAY_INTERNAL_H_ diff --git a/mojo/public/bindings/lib/bindings_internal.h b/mojo/public/bindings/lib/bindings_internal.h deleted file mode 100644 index 3a167f3..0000000 --- a/mojo/public/bindings/lib/bindings_internal.h +++ /dev/null @@ -1,141 +0,0 @@ -// 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_PUBLIC_BINDINGS_LIB_BINDINGS_INTERNAL_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_INTERNAL_H_ - -#include "mojo/public/cpp/system/core.h" - -namespace mojo { -namespace internal { -template class Array_Data; - -#pragma pack(push, 1) - -struct StructHeader { - uint32_t num_bytes; - uint32_t num_fields; -}; -MOJO_COMPILE_ASSERT(sizeof(StructHeader) == 8, bad_sizeof_StructHeader); - -struct ArrayHeader { - uint32_t num_bytes; - uint32_t num_elements; -}; -MOJO_COMPILE_ASSERT(sizeof(ArrayHeader) == 8, bad_sizeof_ArrayHeader); - -template -union StructPointer { - uint64_t offset; - T* ptr; -}; -MOJO_COMPILE_ASSERT(sizeof(StructPointer) == 8, bad_sizeof_StructPointer); - -template -union ArrayPointer { - uint64_t offset; - Array_Data* ptr; -}; -MOJO_COMPILE_ASSERT(sizeof(ArrayPointer) == 8, bad_sizeof_ArrayPointer); - -union StringPointer { - uint64_t offset; - Array_Data* ptr; -}; -MOJO_COMPILE_ASSERT(sizeof(StringPointer) == 8, bad_sizeof_StringPointer); - -#pragma pack(pop) - -template -void ResetIfNonNull(T* ptr) { - if (ptr) - *ptr = T(); -} - -template -T FetchAndReset(T* ptr) { - T temp = *ptr; - *ptr = T(); - return temp; -} - -template -class WrapperHelper { - public: - static const T Wrap(const typename T::Data* data) { - return T(typename T::Wrap(), const_cast(data)); - } - static typename T::Data* Unwrap(const T& object) { - return const_cast(object.data_); - } -}; - -template -inline const typename Data::Wrapper Wrap(const Data* data) { - return WrapperHelper::Wrap(data); -} - -template -inline typename T::Data* Unwrap(const T& object) { - return WrapperHelper::Unwrap(object); -} - -template struct TypeTraits { - static const bool kIsObject = true; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; -template <> struct TypeTraits { - static const bool kIsObject = false; -}; - -template class ObjectTraits {}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_INTERNAL_H_ diff --git a/mojo/public/bindings/lib/bindings_serialization.cc b/mojo/public/bindings/lib/bindings_serialization.cc deleted file mode 100644 index 31603a4..0000000 --- a/mojo/public/bindings/lib/bindings_serialization.cc +++ /dev/null @@ -1,73 +0,0 @@ -// 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. - -#include "mojo/public/bindings/lib/bindings_serialization.h" - -#include - -#include "mojo/public/bindings/lib/bindings_internal.h" - -namespace mojo { -namespace internal { - -size_t Align(size_t size) { - const size_t kAlignment = 8; - return size + (kAlignment - (size % kAlignment)) % kAlignment; -} - -void EncodePointer(const void* ptr, uint64_t* offset) { - if (!ptr) { - *offset = 0; - return; - } - - const char* p_obj = reinterpret_cast(ptr); - const char* p_slot = reinterpret_cast(offset); - assert(p_obj > p_slot); - - *offset = static_cast(p_obj - p_slot); -} - -const void* DecodePointerRaw(const uint64_t* offset) { - if (!*offset) - return NULL; - return reinterpret_cast(offset) + *offset; -} - -bool ValidatePointer(const void* ptr, const Message& message) { - const uint8_t* data = static_cast(ptr); - if (reinterpret_cast(data) % 8 != 0) - return false; - - const uint8_t* data_start = message.data(); - const uint8_t* data_end = data_start + message.data_num_bytes(); - - return data >= data_start && data < data_end; -} - -void EncodeHandle(Handle* handle, std::vector* handles) { - if (handle->is_valid()) { - handles->push_back(*handle); - handle->set_value(static_cast(handles->size() - 1)); - } else { - // Encode -1 to mean the invalid handle. - handle->set_value(static_cast(-1)); - } -} - -bool DecodeHandle(Handle* handle, std::vector* handles) { - // Decode -1 to mean the invalid handle. - if (handle->value() == static_cast(-1)) { - *handle = Handle(); - return true; - } - if (handle->value() >= handles->size()) - return false; - // Just leave holes in the vector so we don't screw up other indices. - *handle = FetchAndReset(&handles->at(handle->value())); - return true; -} - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/bindings/lib/bindings_serialization.h b/mojo/public/bindings/lib/bindings_serialization.h deleted file mode 100644 index 1be889c..0000000 --- a/mojo/public/bindings/lib/bindings_serialization.h +++ /dev/null @@ -1,67 +0,0 @@ -// 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_PUBLIC_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ - -#include - -#include "mojo/public/cpp/bindings/buffer.h" -#include "mojo/public/cpp/bindings/message.h" - -namespace mojo { -namespace internal { - -size_t Align(size_t size); - -// Pointers are encoded as relative offsets. The offsets are relative to the -// address of where the offset value is stored, such that the pointer may be -// recovered with the expression: -// -// ptr = reinterpret_cast(offset) + *offset -// -// A null pointer is encoded as an offset value of 0. -// -void EncodePointer(const void* ptr, uint64_t* offset); -const void* DecodePointerRaw(const uint64_t* offset); - -template -inline void DecodePointer(const uint64_t* offset, T** ptr) { - *ptr = reinterpret_cast(const_cast(DecodePointerRaw(offset))); -} - -// Check that the given pointer references memory contained within the message. -bool ValidatePointer(const void* ptr, const Message& message); - -// Handles are encoded as indices into a vector of handles. These functions -// manipulate the value of |handle|, mapping it to and from an index. -void EncodeHandle(Handle* handle, std::vector* handles); -bool DecodeHandle(Handle* handle, std::vector* handles); - -// The following 2 functions are used to encode/decode all objects (structs and -// arrays) in a consistent manner. - -template -inline void Encode(T* obj, std::vector* handles) { - if (obj->ptr) - obj->ptr->EncodePointersAndHandles(handles); - EncodePointer(obj->ptr, &obj->offset); -} - -template -inline bool Decode(T* obj, Message* message) { - DecodePointer(&obj->offset, &obj->ptr); - if (obj->ptr) { - if (!ValidatePointer(obj->ptr, *message)) - return false; - if (!obj->ptr->DecodePointersAndHandles(message)) - return false; - } - return true; -} - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ diff --git a/mojo/public/bindings/lib/buffer.cc b/mojo/public/bindings/lib/buffer.cc deleted file mode 100644 index 4404df8..0000000 --- a/mojo/public/bindings/lib/buffer.cc +++ /dev/null @@ -1,27 +0,0 @@ -// 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. - -#include "mojo/public/cpp/bindings/buffer.h" - -#include - -#include "mojo/public/cpp/environment/buffer_tls.h" -#include "mojo/public/cpp/system/macros.h" - -namespace mojo { - -Buffer::Buffer() { - previous_ = internal::SetCurrentBuffer(this); -} - -Buffer::~Buffer() { - Buffer* buf MOJO_ALLOW_UNUSED = internal::SetCurrentBuffer(previous_); - assert(buf == this); -} - -Buffer* Buffer::current() { - return internal::GetCurrentBuffer(); -} - -} // namespace mojo diff --git a/mojo/public/bindings/lib/callback_internal.h b/mojo/public/bindings/lib/callback_internal.h deleted file mode 100644 index 4e7e996..0000000 --- a/mojo/public/bindings/lib/callback_internal.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2014 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_PUBLIC_BINDINGS_LIB_CALLBACK_INTERNAL_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_CALLBACK_INTERNAL_H_ - -#include "mojo/public/bindings/lib/bindings_internal.h" - -namespace mojo { -namespace internal { - -template ::kIsObject> -struct Callback_ParamTraits {}; - -template -struct Callback_ParamTraits { - typedef const T& ForwardType; - static const bool kIsScopedHandle = false; -}; - -template -struct Callback_ParamTraits { - typedef T ForwardType; - static const bool kIsScopedHandle = false; -}; - -template -struct Callback_ParamTraits, true> { - typedef ScopedHandleBase ForwardType; - static const bool kIsScopedHandle = true; -}; - -template -struct EnableIf {}; - -template -struct EnableIf { typedef T type; }; - -template -typename EnableIf::kIsScopedHandle, T>::type& - Callback_Forward(T& t) { - return t; -} - -template -typename EnableIf::kIsScopedHandle, T>::type - Callback_Forward(T& t) { - return t.Pass(); -} - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_CALLBACK_INTERNAL_H_ diff --git a/mojo/public/bindings/lib/connector.cc b/mojo/public/bindings/lib/connector.cc deleted file mode 100644 index 7a07409..0000000 --- a/mojo/public/bindings/lib/connector.cc +++ /dev/null @@ -1,130 +0,0 @@ -// 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. - -#include "mojo/public/bindings/lib/connector.h" - -#include -#include - -#include "mojo/public/cpp/bindings/error_handler.h" - -namespace mojo { -namespace internal { - -// ---------------------------------------------------------------------------- - -Connector::Connector(ScopedMessagePipeHandle message_pipe, - MojoAsyncWaiter* waiter) - : error_handler_(NULL), - waiter_(waiter), - message_pipe_(message_pipe.Pass()), - incoming_receiver_(NULL), - async_wait_id_(0), - error_(false), - drop_writes_(false) { - // Even though we don't have an incoming receiver, we still want to monitor - // the message pipe to know if is closed or encounters an error. - WaitToReadMore(); -} - -Connector::~Connector() { - if (async_wait_id_) - waiter_->CancelWait(waiter_, async_wait_id_); -} - -void Connector::CloseMessagePipe() { - Close(message_pipe_.Pass()); -} - -bool Connector::Accept(Message* message) { - if (error_) - return false; - - if (drop_writes_) - return true; - - MojoResult rv = WriteMessageRaw( - message_pipe_.get(), - message->data(), - message->data_num_bytes(), - message->mutable_handles()->empty() ? NULL : - reinterpret_cast( - &message->mutable_handles()->front()), - static_cast(message->mutable_handles()->size()), - MOJO_WRITE_MESSAGE_FLAG_NONE); - - switch (rv) { - case MOJO_RESULT_OK: - // The handles were successfully transferred, so we don't need the message - // to track their lifetime any longer. - message->mutable_handles()->clear(); - break; - case MOJO_RESULT_FAILED_PRECONDITION: - // There's no point in continuing to write to this pipe since the other - // end is gone. Avoid writing any future messages. Hide write failures - // from the caller since we'd like them to continue consuming any backlog - // of incoming messages before regarding the message pipe as closed. - drop_writes_ = true; - break; - default: - // This particular write was rejected, presumably because of bad input. - // The pipe is not necessarily in a bad state. - return false; - } - return true; -} - -bool Connector::AcceptWithResponder(Message* message, - MessageReceiver* responder) { - // TODO(darin): Implement this! - assert(false); - return false; -} - -// static -void Connector::CallOnHandleReady(void* closure, MojoResult result) { - Connector* self = static_cast(closure); - self->OnHandleReady(result); -} - -void Connector::OnHandleReady(MojoResult result) { - async_wait_id_ = 0; - - if (result == MOJO_RESULT_OK) { - ReadMore(); - } else { - error_ = true; - } - - if (error_ && error_handler_) - error_handler_->OnError(); -} - -void Connector::WaitToReadMore() { - async_wait_id_ = waiter_->AsyncWait(waiter_, - message_pipe_.get().value(), - MOJO_WAIT_FLAG_READABLE, - MOJO_DEADLINE_INDEFINITE, - &Connector::CallOnHandleReady, - this); -} - -void Connector::ReadMore() { - while (true) { - MojoResult rv; - - rv = ReadAndDispatchMessage(message_pipe_.get(), incoming_receiver_, NULL); - if (rv == MOJO_RESULT_SHOULD_WAIT) { - WaitToReadMore(); - break; - } - if (rv != MOJO_RESULT_OK) { - error_ = true; - break; - } - } -} - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/bindings/lib/connector.h b/mojo/public/bindings/lib/connector.h deleted file mode 100644 index 833acf0..0000000 --- a/mojo/public/bindings/lib/connector.h +++ /dev/null @@ -1,80 +0,0 @@ -// 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_PUBLIC_BINDINGS_LIB_CONNECTOR_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_CONNECTOR_H_ - -#include "mojo/public/bindings/lib/message_queue.h" -#include "mojo/public/cpp/bindings/message.h" -#include "mojo/public/cpp/environment/default_async_waiter.h" -#include "mojo/public/cpp/system/core.h" - -namespace mojo { -class ErrorHandler; - -namespace internal { - -// The Connector class is responsible for performing read/write operations on a -// MessagePipe. It writes messages it receives through the MessageReceiver -// interface that it subclasses, and it forwards messages it reads through the -// MessageReceiver interface assigned as its incoming receiver. -// -// NOTE: MessagePipe I/O is non-blocking. -// -class Connector : public MessageReceiver { - public: - // The Connector takes ownership of |message_pipe|. - explicit Connector(ScopedMessagePipeHandle message_pipe, - MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()); - virtual ~Connector(); - - // Sets the receiver to handle messages read from the message pipe. The - // Connector will read messages from the pipe regardless of whether or not an - // incoming receiver has been set. - void set_incoming_receiver(MessageReceiver* receiver) { - incoming_receiver_ = receiver; - } - - // Sets the error handler to receive notifications when an error is - // encountered while reading from the pipe or waiting to read from the pipe. - void set_error_handler(ErrorHandler* error_handler) { - error_handler_ = error_handler; - } - - // Returns true if an error was encountered while reading from the pipe or - // waiting to read from the pipe. - bool encountered_error() const { return error_; } - - // Closes the pipe, triggering the error state. - void CloseMessagePipe(); - - // MessageReceiver implementation: - virtual bool Accept(Message* message) MOJO_OVERRIDE; - virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder) - MOJO_OVERRIDE; - - private: - static void CallOnHandleReady(void* closure, MojoResult result); - void OnHandleReady(MojoResult result); - - void WaitToReadMore(); - void ReadMore(); - - ErrorHandler* error_handler_; - MojoAsyncWaiter* waiter_; - - ScopedMessagePipeHandle message_pipe_; - MessageReceiver* incoming_receiver_; - - MojoAsyncWaitID async_wait_id_; - bool error_; - bool drop_writes_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(Connector); -}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_CONNECTOR_H_ diff --git a/mojo/public/bindings/lib/fixed_buffer.cc b/mojo/public/bindings/lib/fixed_buffer.cc deleted file mode 100644 index 09e3094..0000000 --- a/mojo/public/bindings/lib/fixed_buffer.cc +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2014 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. - -#include "mojo/public/bindings/lib/fixed_buffer.h" - -#include -#include -#include - -#include - -#include "mojo/public/bindings/lib/bindings_serialization.h" - -namespace mojo { -namespace internal { - -FixedBuffer::FixedBuffer(size_t size) - : ptr_(NULL), - cursor_(0), - size_(internal::Align(size)) { - ptr_ = static_cast(calloc(size_, 1)); -} - -FixedBuffer::~FixedBuffer() { - free(ptr_); -} - -void* FixedBuffer::Allocate(size_t delta, Destructor dtor) { - assert(!dtor); - - delta = internal::Align(delta); - - if (delta == 0 || delta > size_ - cursor_) { - assert(false); - return NULL; - } - - char* result = ptr_ + cursor_; - cursor_ += delta; - - return result; -} - -void* FixedBuffer::Leak() { - char* ptr = ptr_; - ptr_ = NULL; - cursor_ = 0; - size_ = 0; - return ptr; -} - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/bindings/lib/fixed_buffer.h b/mojo/public/bindings/lib/fixed_buffer.h deleted file mode 100644 index 76f95f0..0000000 --- a/mojo/public/bindings/lib/fixed_buffer.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2014 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_PUBLIC_BINDINGS_LIB_FIXED_BUFFER_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_FIXED_BUFFER_H_ - -#include "mojo/public/cpp/bindings/buffer.h" -#include "mojo/public/cpp/system/macros.h" - -namespace mojo { -namespace internal { - -// FixedBuffer provides a simple way to allocate objects within a fixed chunk -// of memory. Objects are allocated by calling the |Allocate| method, which -// extends the buffer accordingly. Objects allocated in this way are not freed -// explicitly. Instead, they remain valid so long as the FixedBuffer remains -// valid. The Leak method may be used to steal the underlying memory from the -// FixedBuffer. -// -// Typical usage: -// -// { -// FixedBuffer buf(8 + 8); -// -// int* a = static_cast(buf->Allocate(sizeof(int))); -// *a = 2; -// -// double* b = static_cast(buf->Allocate(sizeof(double))); -// *b = 3.14f; -// -// void* data = buf.Leak(); -// Process(data); -// -// free(data); -// } -// -class FixedBuffer : public Buffer { - public: - explicit FixedBuffer(size_t size); - virtual ~FixedBuffer(); - - // Grows the buffer by |num_bytes| and returns a pointer to the start of the - // addition. The resulting address is 8-byte aligned, and the content of the - // memory is zero-filled. - virtual void* Allocate(size_t num_bytes, Destructor func = NULL) - MOJO_OVERRIDE; - - size_t size() const { return size_; } - - // Returns the internal memory owned by the Buffer to the caller. The Buffer - // relinquishes its pointer, effectively resetting the state of the Buffer - // and leaving the caller responsible for freeing the returned memory address - // when no longer needed. - void* Leak(); - - private: - char* ptr_; - size_t cursor_; - size_t size_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(FixedBuffer); -}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_FIXED_BUFFER_H_ diff --git a/mojo/public/bindings/lib/interface.cc b/mojo/public/bindings/lib/interface.cc deleted file mode 100644 index 3b552be..0000000 --- a/mojo/public/bindings/lib/interface.cc +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2014 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. - -#include "mojo/public/cpp/bindings/interface.h" - -namespace mojo { - -bool NoInterfaceStub::Accept(Message* message) { - return false; -} - -bool NoInterfaceStub::AcceptWithResponder(Message* message, - MessageReceiver* responder) { - return false; -} - -} // namespace mojo - diff --git a/mojo/public/bindings/lib/message.cc b/mojo/public/bindings/lib/message.cc deleted file mode 100644 index 8ec188e2..0000000 --- a/mojo/public/bindings/lib/message.cc +++ /dev/null @@ -1,84 +0,0 @@ -// 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. - -#include "mojo/public/cpp/bindings/message.h" - -#include -#include - -#include - -namespace mojo { - -Message::Message() - : data_num_bytes_(0), - data_(NULL) { -} - -Message::~Message() { - free(data_); - - for (std::vector::iterator it = handles_.begin(); - it != handles_.end(); ++it) { - if (it->is_valid()) - CloseRaw(*it); - } -} - -void Message::AllocUninitializedData(uint32_t num_bytes) { - assert(!data_); - data_num_bytes_ = num_bytes; - data_ = static_cast(malloc(num_bytes)); -} - -void Message::AdoptData(uint32_t num_bytes, internal::MessageData* data) { - assert(!data_); - data_num_bytes_ = num_bytes; - data_ = data; -} - -void Message::Swap(Message* other) { - std::swap(data_num_bytes_, other->data_num_bytes_); - std::swap(data_, other->data_); - std::swap(handles_, other->handles_); -} - -MojoResult ReadAndDispatchMessage(MessagePipeHandle handle, - MessageReceiver* receiver, - bool* receiver_result) { - MojoResult rv; - - uint32_t num_bytes = 0, num_handles = 0; - rv = ReadMessageRaw(handle, - NULL, - &num_bytes, - NULL, - &num_handles, - MOJO_READ_MESSAGE_FLAG_NONE); - if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED) - return rv; - - Message message; - message.AllocUninitializedData(num_bytes); - message.mutable_handles()->resize(num_handles); - - rv = ReadMessageRaw(handle, - message.mutable_data(), - &num_bytes, - message.mutable_handles()->empty() - ? NULL - : reinterpret_cast( - &message.mutable_handles()->front()), - &num_handles, - MOJO_READ_MESSAGE_FLAG_NONE); - if (receiver && rv == MOJO_RESULT_OK) { - bool result = receiver->Accept(&message); - if (receiver_result) - *receiver_result = result; - } - - return rv; -} - -} // namespace mojo diff --git a/mojo/public/bindings/lib/message_builder.cc b/mojo/public/bindings/lib/message_builder.cc deleted file mode 100644 index 5cdd40e..0000000 --- a/mojo/public/bindings/lib/message_builder.cc +++ /dev/null @@ -1,52 +0,0 @@ -// 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. - -#include "mojo/public/bindings/lib/message_builder.h" - -#include "mojo/public/cpp/bindings/message.h" - -namespace mojo { -namespace internal { - -template -void Allocate(Buffer* buf, Header** header) { - *header = static_cast(buf->Allocate(sizeof(Header))); - (*header)->num_bytes = sizeof(Header); -} - -MessageBuilder::MessageBuilder(uint32_t name, size_t payload_size) - : buf_(sizeof(MessageHeader) + payload_size) { - MessageHeader* header; - Allocate(&buf_, &header); - header->num_fields = 2; - header->name = name; -} - -MessageBuilder::~MessageBuilder() { -} - -void MessageBuilder::Finish(Message* message) { - uint32_t num_bytes = static_cast(buf_.size()); - message->AdoptData(num_bytes, static_cast(buf_.Leak())); -} - -MessageBuilder::MessageBuilder(size_t size) - : buf_(size) { -} - -MessageWithRequestIDBuilder::MessageWithRequestIDBuilder(uint32_t name, - size_t payload_size, - uint32_t flags, - uint64_t request_id) - : MessageBuilder(sizeof(MessageHeaderWithRequestID) + payload_size) { - MessageHeaderWithRequestID* header; - Allocate(&buf_, &header); - header->num_fields = 3; - header->name = name; - header->flags = flags; - header->request_id = request_id; -} - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/bindings/lib/message_builder.h b/mojo/public/bindings/lib/message_builder.h deleted file mode 100644 index 7158d5b..0000000 --- a/mojo/public/bindings/lib/message_builder.h +++ /dev/null @@ -1,63 +0,0 @@ -// 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_PUBLIC_BINDINGS_LIB_MESSAGE_BUILDER_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_MESSAGE_BUILDER_H_ - -#include - -#include "mojo/public/bindings/lib/fixed_buffer.h" -#include "mojo/public/bindings/lib/message_internal.h" - -namespace mojo { -class Message; - -namespace internal { - -class MessageBuilder { - public: - MessageBuilder(uint32_t name, size_t payload_size); - ~MessageBuilder(); - - Buffer* buffer() { return &buf_; } - - // Call Finish when done making allocations in |buffer()|. Upon return, - // |message| will contain the message data, and |buffer()| will no longer be - // valid to reference. - void Finish(Message* message); - - protected: - explicit MessageBuilder(size_t size); - FixedBuffer buf_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(MessageBuilder); -}; - -class MessageWithRequestIDBuilder : public MessageBuilder { - public: - MessageWithRequestIDBuilder(uint32_t name, size_t payload_size, - uint32_t flags, uint64_t request_id); -}; - -class RequestMessageBuilder : public MessageWithRequestIDBuilder { - public: - RequestMessageBuilder(uint32_t name, size_t payload_size) - : MessageWithRequestIDBuilder(name, payload_size, kMessageExpectsResponse, - 0) { - } -}; - -class ResponseMessageBuilder : public MessageWithRequestIDBuilder { - public: - ResponseMessageBuilder(uint32_t name, size_t payload_size, - uint64_t request_id) - : MessageWithRequestIDBuilder(name, payload_size, kMessageIsResponse, - request_id) { - } -}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_MESSAGE_BUILDER_H_ diff --git a/mojo/public/bindings/lib/message_internal.h b/mojo/public/bindings/lib/message_internal.h deleted file mode 100644 index f238bb2..0000000 --- a/mojo/public/bindings/lib/message_internal.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2014 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_PUBLIC_BINDINGS_LIB_MESSAGE_INTERNAL_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_MESSAGE_INTERNAL_H_ - -#include "mojo/public/bindings/lib/bindings_internal.h" - -namespace mojo { -namespace internal { - -#pragma pack(push, 1) - -enum { - kMessageExpectsResponse = 1 << 0, - kMessageIsResponse = 1 << 1 -}; - -struct MessageHeader : internal::StructHeader { - uint32_t name; - uint32_t flags; -}; -MOJO_COMPILE_ASSERT(sizeof(MessageHeader) == 16, bad_sizeof_MessageHeader); - -struct MessageHeaderWithRequestID : MessageHeader { - uint64_t request_id; -}; -MOJO_COMPILE_ASSERT(sizeof(MessageHeaderWithRequestID) == 24, - bad_sizeof_MessageHeaderWithRequestID); - -struct MessageData { - MessageHeader header; -}; - -MOJO_COMPILE_ASSERT(sizeof(MessageData) == sizeof(MessageHeader), - bad_sizeof_MessageData); - -#pragma pack(pop) - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_MESSAGE_INTERNAL_H_ diff --git a/mojo/public/bindings/lib/message_queue.cc b/mojo/public/bindings/lib/message_queue.cc deleted file mode 100644 index ce5e347..0000000 --- a/mojo/public/bindings/lib/message_queue.cc +++ /dev/null @@ -1,50 +0,0 @@ -// 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. - -#include "mojo/public/bindings/lib/message_queue.h" - -#include -#include - -#include "mojo/public/cpp/bindings/message.h" - -namespace mojo { -namespace internal { - -MessageQueue::MessageQueue() { -} - -MessageQueue::~MessageQueue() { - while (!queue_.empty()) - Pop(); -} - -bool MessageQueue::IsEmpty() const { - return queue_.empty(); -} - -Message* MessageQueue::Peek() { - assert(!queue_.empty()); - return queue_.front(); -} - -void MessageQueue::Push(Message* message) { - queue_.push(new Message()); - queue_.back()->Swap(message); -} - -void MessageQueue::Pop(Message* message) { - assert(!queue_.empty()); - queue_.front()->Swap(message); - Pop(); -} - -void MessageQueue::Pop() { - assert(!queue_.empty()); - delete queue_.front(); - queue_.pop(); -} - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/bindings/lib/message_queue.h b/mojo/public/bindings/lib/message_queue.h deleted file mode 100644 index d1c535b..0000000 --- a/mojo/public/bindings/lib/message_queue.h +++ /dev/null @@ -1,47 +0,0 @@ -// 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_PUBLIC_BINDINGS_LIB_MESSAGE_QUEUE_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_MESSAGE_QUEUE_H_ - -#include - -#include "mojo/public/cpp/system/macros.h" - -namespace mojo { -class Message; - -namespace internal { - -// A queue for Message objects. -class MessageQueue { - public: - MessageQueue(); - ~MessageQueue(); - - bool IsEmpty() const; - Message* Peek(); - - // This method transfers ownership of |message->data| and |message->handles| - // to the message queue, resetting |message| in the process. - void Push(Message* message); - - // Removes the next message from the queue, transferring ownership of its - // data and handles to the given |message|. - void Pop(Message* message); - - // Removes the next message from the queue, discarding its data and handles. - // This is meant to be used in conjunction with |Peek|. - void Pop(); - - private: - std::queue queue_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(MessageQueue); -}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_MESSAGE_QUEUE_H_ diff --git a/mojo/public/bindings/lib/router.cc b/mojo/public/bindings/lib/router.cc deleted file mode 100644 index 90e0541..0000000 --- a/mojo/public/bindings/lib/router.cc +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2014 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. - -#include "mojo/public/bindings/lib/router.h" - -namespace mojo { -namespace internal { - -// ---------------------------------------------------------------------------- - -class ResponderThunk : public MessageReceiver { - public: - explicit ResponderThunk(const SharedData& router) - : router_(router) { - } - virtual ~ResponderThunk() { - } - - // MessageReceiver implementation: - virtual bool Accept(Message* message) MOJO_OVERRIDE { - assert(message->has_flag(kMessageIsResponse)); - - bool result = false; - - Router* router = router_.value(); - if (router) - result = router->Accept(message); - - return result; - } - - virtual bool AcceptWithResponder(Message* message, - MessageReceiver* responder) MOJO_OVERRIDE { - assert(false); // not reached! - return false; - } - - private: - SharedData router_; -}; - -// ---------------------------------------------------------------------------- - -Router::HandleIncomingMessageThunk::HandleIncomingMessageThunk(Router* router) - : router_(router) { -} - -Router::HandleIncomingMessageThunk::~HandleIncomingMessageThunk() { -} - -bool Router::HandleIncomingMessageThunk::Accept(Message* message) { - return router_->HandleIncomingMessage(message); -} - -bool Router::HandleIncomingMessageThunk::AcceptWithResponder( - Message* message, - MessageReceiver* responder) { - assert(false); // not reached! - return false; -} - -// ---------------------------------------------------------------------------- - -Router::Router(ScopedMessagePipeHandle message_pipe, MojoAsyncWaiter* waiter) - : connector_(message_pipe.Pass(), waiter), - weak_self_(this), - incoming_receiver_(NULL), - thunk_(this), - next_request_id_(0) { - connector_.set_incoming_receiver(&thunk_); -} - -Router::~Router() { - weak_self_.set_value(NULL); -} - -bool Router::Accept(Message* message) { - assert(!message->has_flag(kMessageExpectsResponse)); - return connector_.Accept(message); -} - -bool Router::AcceptWithResponder(Message* message, - MessageReceiver* responder) { - assert(message->has_flag(kMessageExpectsResponse)); - - // Reserve 0 in case we want it to convey special meaning in the future. - uint64_t request_id = next_request_id_++; - if (request_id == 0) - request_id = next_request_id_++; - - message->set_request_id(request_id); - if (!connector_.Accept(message)) - return false; - - // We assume ownership of |responder|. - responders_[request_id] = responder; - return true; -} - -bool Router::HandleIncomingMessage(Message* message) { - if (message->has_flag(kMessageExpectsResponse)) { - if (incoming_receiver_) { - MessageReceiver* responder = new ResponderThunk(weak_self_); - bool ok = incoming_receiver_->AcceptWithResponder(message, responder); - if (!ok) - delete responder; - return ok; - } - - // If we receive a request expecting a response when the client is not - // listening, then we have no choice but to tear down the pipe. - connector_.CloseMessagePipe(); - } else if (message->has_flag(kMessageIsResponse)) { - uint64_t request_id = message->request_id(); - ResponderMap::iterator it = responders_.find(request_id); - if (it == responders_.end()) { - assert(false); - return false; - } - MessageReceiver* responder = it->second; - responders_.erase(it); - responder->Accept(message); - delete responder; - } else { - if (incoming_receiver_) - return incoming_receiver_->Accept(message); - // OK to drop message on the floor. - } - - return false; -} - -// ---------------------------------------------------------------------------- - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/bindings/lib/router.h b/mojo/public/bindings/lib/router.h deleted file mode 100644 index edd2ad5..0000000 --- a/mojo/public/bindings/lib/router.h +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2014 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_PUBLIC_BINDINGS_LIB_ROUTER_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_ROUTER_H_ - -#include - -#include "mojo/public/bindings/lib/connector.h" -#include "mojo/public/bindings/lib/shared_data.h" - -namespace mojo { -namespace internal { - -class Router : public MessageReceiver { - public: - // The Router takes ownership of |message_pipe|. - explicit Router(ScopedMessagePipeHandle message_pipe, - MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()); - virtual ~Router(); - - // Sets the receiver to handle messages read from the message pipe that do - // not have the kMessageIsResponse flag set. - void set_incoming_receiver(MessageReceiver* receiver) { - incoming_receiver_ = receiver; - } - - // Sets the error handler to receive notifications when an error is - // encountered while reading from the pipe or waiting to read from the pipe. - void set_error_handler(ErrorHandler* error_handler) { - connector_.set_error_handler(error_handler); - } - - // Returns true if an error was encountered while reading from the pipe or - // waiting to read from the pipe. - bool encountered_error() const { return connector_.encountered_error(); } - - // MessageReceiver implementation: - virtual bool Accept(Message* message) MOJO_OVERRIDE; - virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder) - MOJO_OVERRIDE; - - private: - typedef std::map ResponderMap; - - class HandleIncomingMessageThunk : public MessageReceiver { - public: - HandleIncomingMessageThunk(Router* router); - virtual ~HandleIncomingMessageThunk(); - - // MessageReceiver implementation: - virtual bool Accept(Message* message) MOJO_OVERRIDE; - virtual bool AcceptWithResponder(Message* message, - MessageReceiver* responder) MOJO_OVERRIDE; - private: - Router* router_; - }; - - bool HandleIncomingMessage(Message* message); - - Connector connector_; - SharedData weak_self_; - MessageReceiver* incoming_receiver_; - HandleIncomingMessageThunk thunk_; - ResponderMap responders_; - uint64_t next_request_id_; -}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_ROUTER_H_ diff --git a/mojo/public/bindings/lib/scratch_buffer.cc b/mojo/public/bindings/lib/scratch_buffer.cc deleted file mode 100644 index abfb5fe..0000000 --- a/mojo/public/bindings/lib/scratch_buffer.cc +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2014 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. - -#include "mojo/public/bindings/lib/scratch_buffer.h" - -#include -#include -#include - -#include - -#include "mojo/public/bindings/lib/bindings_serialization.h" - -// Scrub memory in debug builds to help catch use-after-free bugs. -#ifdef NDEBUG -#define DEBUG_SCRUB(address, size) (void) (address), (void) (size) -#else -#define DEBUG_SCRUB(address, size) memset(address, 0xCD, size) -#endif - -namespace mojo { -namespace internal { - -ScratchBuffer::ScratchBuffer() - : overflow_(NULL) { - fixed_.next = NULL; - fixed_.cursor = fixed_data_; - fixed_.end = fixed_data_ + kMinSegmentSize; -} - -ScratchBuffer::~ScratchBuffer() { - // Invoke destructors in reverse order to mirror allocation order. - std::deque::reverse_iterator it; - for (it = pending_dtors_.rbegin(); it != pending_dtors_.rend(); ++it) - it->func(it->address); - - while (overflow_) { - Segment* doomed = overflow_; - overflow_ = overflow_->next; - DEBUG_SCRUB(doomed, doomed->end - reinterpret_cast(doomed)); - free(doomed); - } - DEBUG_SCRUB(fixed_data_, sizeof(fixed_data_)); -} - -void* ScratchBuffer::Allocate(size_t delta, Destructor func) { - delta = internal::Align(delta); - - void* result = AllocateInSegment(&fixed_, delta); - if (!result) { - if (overflow_) - result = AllocateInSegment(overflow_, delta); - - if (!result) { - AddOverflowSegment(delta); - result = AllocateInSegment(overflow_, delta); - } - } - - if (func) { - PendingDestructor dtor; - dtor.func = func; - dtor.address = result; - pending_dtors_.push_back(dtor); - } - return result; -} - -void* ScratchBuffer::AllocateInSegment(Segment* segment, size_t delta) { - void* result; - if (static_cast(segment->end - segment->cursor) >= delta) { - result = segment->cursor; - memset(result, 0, delta); - segment->cursor += delta; - } else { - result = NULL; - } - return result; -} - -void ScratchBuffer::AddOverflowSegment(size_t delta) { - if (delta < kMinSegmentSize) - delta = kMinSegmentSize; - - // Ensure segment buffer is aligned. - size_t segment_size = internal::Align(sizeof(Segment)) + delta; - - Segment* segment = static_cast(malloc(segment_size)); - segment->next = overflow_; - segment->cursor = reinterpret_cast(segment + 1); - segment->end = segment->cursor + delta; - - overflow_ = segment; -} - -} // namespace internal -} // namespace mojo diff --git a/mojo/public/bindings/lib/scratch_buffer.h b/mojo/public/bindings/lib/scratch_buffer.h deleted file mode 100644 index 310969b..0000000 --- a/mojo/public/bindings/lib/scratch_buffer.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2014 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_PUBLIC_BINDINGS_LIB_SCRATCH_BUFFER_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_SCRATCH_BUFFER_H_ - -#include - -#include "mojo/public/cpp/bindings/buffer.h" -#include "mojo/public/cpp/system/macros.h" - -namespace mojo { -namespace internal { - -// The following class is designed to be allocated on the stack. If necessary, -// it will failover to allocating objects on the heap. -class ScratchBuffer : public Buffer { - public: - ScratchBuffer(); - virtual ~ScratchBuffer(); - - virtual void* Allocate(size_t num_bytes, Destructor func = NULL) - MOJO_OVERRIDE; - - private: - enum { kMinSegmentSize = 512 }; - - struct Segment { - Segment* next; - char* cursor; - char* end; - }; - - void* AllocateInSegment(Segment* segment, size_t num_bytes); - void AddOverflowSegment(size_t delta); - - char fixed_data_[kMinSegmentSize]; - Segment fixed_; - Segment* overflow_; - - struct PendingDestructor { - Destructor func; - void* address; - }; - std::deque pending_dtors_; - - MOJO_DISALLOW_COPY_AND_ASSIGN(ScratchBuffer); -}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_SCRATCH_BUFFER_H_ diff --git a/mojo/public/bindings/lib/shared_data.h b/mojo/public/bindings/lib/shared_data.h deleted file mode 100644 index c40b8f9..0000000 --- a/mojo/public/bindings/lib/shared_data.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2014 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_PUBLIC_BINDINGS_LIB_SHARED_DATA_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_SHARED_DATA_H_ - -namespace mojo { -namespace internal { - -// Used to allocate an instance of T that can be shared via reference counting. -template -class SharedData { - public: - ~SharedData() { - holder_->Release(); - } - - SharedData() : holder_(new Holder()) { - } - - explicit SharedData(const T& value) : holder_(new Holder(value)) { - } - - SharedData(const SharedData& other) : holder_(other.holder_) { - holder_->Retain(); - } - - SharedData& operator=(const SharedData& other) { - if (other.holder_ == holder_) - return *this; - holder_->Release(); - holder_ = other.holder_; - holder_->Retain(); - } - - void reset() { - holder_->Release(); - holder_ = new Holder(); - } - - void reset(const T& value) { - holder_->Release(); - holder_ = new Holder(value); - } - - void set_value(const T& value) { - holder_->value = value; - } - T* mutable_value() { - return &holder_->value; - } - const T& value() const { - return holder_->value; - } - - private: - class Holder { - public: - Holder() : value(), ref_count_(1) { - } - Holder(const T& value) : value(value), ref_count_(1) { - } - - void Retain() { ++ref_count_; } - void Release() { if (--ref_count_ == 0) delete this; } - - T value; - - private: - int ref_count_; - MOJO_DISALLOW_COPY_AND_ASSIGN(Holder); - }; - - Holder* holder_; -}; - -} // namespace internal -} // namespace mojo - -#endif // MOJO_PUBLIC_BINDINGS_LIB_SHARED_DATA_H_ diff --git a/mojo/public/bindings/lib/shared_ptr.h b/mojo/public/bindings/lib/shared_ptr.h deleted file mode 100644 index 537b39e..0000000 --- a/mojo/public/bindings/lib/shared_ptr.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2014 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_PUBLIC_BINDINGS_LIB_SHARED_PTR_H_ -#define MOJO_PUBLIC_BINDINGS_LIB_SHARED_PTR_H_ - -#include "mojo/public/bindings/lib/shared_data.h" - -namespace mojo { -namespace internal { - -// Used to manage a heap-allocated instance of P that can be shared via -// reference counting. When the last reference is dropped, the instance is -// deleted. -template -class SharedPtr { - public: - SharedPtr() {} - - explicit SharedPtr(P* ptr) { - impl_.mutable_value()->ptr = ptr; - } - - // Default copy-constructor and assignment operator are OK. - - P* get() { - return impl_.value().ptr; - } - const P* get() const { - return impl_.value().ptr; - } - - P* operator->() { return get(); } - const P* operator->() const { return get(); } - - private: - class Impl { - public: - ~Impl() { - if (ptr) - delete ptr; - } - - Impl() : ptr(NULL) { - } - - Impl(P* ptr) : ptr(ptr) { - } - - P* ptr; - - private: - MOJO_DISALLOW_COPY_AND_ASSIGN(Impl); - }; - - SharedData impl_; -}; - -} // namespace mojo -} // namespace internal - -#endif // MOJO_PUBLIC_BINDINGS_LIB_SHARED_PTR_H_ diff --git a/mojo/public/bindings/lib/sync_dispatcher.cc b/mojo/public/bindings/lib/sync_dispatcher.cc deleted file mode 100644 index acb537e..0000000 --- a/mojo/public/bindings/lib/sync_dispatcher.cc +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 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. - -#include "mojo/public/cpp/bindings/sync_dispatcher.h" - -#include - -#include "mojo/public/cpp/bindings/message.h" - -namespace mojo { - -bool WaitForMessageAndDispatch(MessagePipeHandle handle, - MessageReceiver* receiver) { - while (true) { - bool result; - MojoResult rv = ReadAndDispatchMessage(handle, receiver, &result); - if (rv == MOJO_RESULT_OK) - return result; - if (rv == MOJO_RESULT_SHOULD_WAIT) - rv = Wait(handle, MOJO_WAIT_FLAG_READABLE, MOJO_DEADLINE_INDEFINITE); - if (rv != MOJO_RESULT_OK) - return false; - } -} - -} // namespace mojo diff --git a/mojo/public/bindings/tests/array_unittest.cc b/mojo/public/bindings/tests/array_unittest.cc index 2cc300a..72033ea 100644 --- a/mojo/public/bindings/tests/array_unittest.cc +++ b/mojo/public/bindings/tests/array_unittest.cc @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/public/bindings/lib/fixed_buffer.h" -#include "mojo/public/bindings/lib/scratch_buffer.h" #include "mojo/public/cpp/bindings/allocation_scope.h" #include "mojo/public/cpp/bindings/array.h" +#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" +#include "mojo/public/cpp/bindings/lib/scratch_buffer.h" #include "mojo/public/cpp/environment/environment.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/mojo/public/bindings/tests/buffer_unittest.cc b/mojo/public/bindings/tests/buffer_unittest.cc index bc0e3a8..49753e1 100644 --- a/mojo/public/bindings/tests/buffer_unittest.cc +++ b/mojo/public/bindings/tests/buffer_unittest.cc @@ -4,10 +4,10 @@ #include -#include "mojo/public/bindings/lib/bindings_serialization.h" -#include "mojo/public/bindings/lib/fixed_buffer.h" -#include "mojo/public/bindings/lib/scratch_buffer.h" #include "mojo/public/cpp/bindings/buffer.h" +#include "mojo/public/cpp/bindings/lib/bindings_serialization.h" +#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" +#include "mojo/public/cpp/bindings/lib/scratch_buffer.h" #include "mojo/public/cpp/environment/environment.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/mojo/public/bindings/tests/connector_unittest.cc b/mojo/public/bindings/tests/connector_unittest.cc index 94eb951..bd856c7 100644 --- a/mojo/public/bindings/tests/connector_unittest.cc +++ b/mojo/public/bindings/tests/connector_unittest.cc @@ -5,9 +5,9 @@ #include #include -#include "mojo/public/bindings/lib/connector.h" -#include "mojo/public/bindings/lib/message_builder.h" -#include "mojo/public/bindings/lib/message_queue.h" +#include "mojo/public/cpp/bindings/lib/connector.h" +#include "mojo/public/cpp/bindings/lib/message_builder.h" +#include "mojo/public/cpp/bindings/lib/message_queue.h" #include "mojo/public/cpp/environment/environment.h" #include "mojo/public/cpp/system/macros.h" #include "mojo/public/cpp/utility/run_loop.h" diff --git a/mojo/public/bindings/tests/router_unittest.cc b/mojo/public/bindings/tests/router_unittest.cc index b86ede6..4b2d0dc 100644 --- a/mojo/public/bindings/tests/router_unittest.cc +++ b/mojo/public/bindings/tests/router_unittest.cc @@ -5,9 +5,9 @@ #include #include -#include "mojo/public/bindings/lib/message_builder.h" -#include "mojo/public/bindings/lib/message_queue.h" -#include "mojo/public/bindings/lib/router.h" +#include "mojo/public/cpp/bindings/lib/message_builder.h" +#include "mojo/public/cpp/bindings/lib/message_queue.h" +#include "mojo/public/cpp/bindings/lib/router.h" #include "mojo/public/cpp/environment/environment.h" #include "mojo/public/cpp/system/macros.h" #include "mojo/public/cpp/utility/run_loop.h" diff --git a/mojo/public/cpp/bindings/DEPS b/mojo/public/cpp/bindings/DEPS deleted file mode 100644 index ba2a571..0000000 --- a/mojo/public/cpp/bindings/DEPS +++ /dev/null @@ -1,4 +0,0 @@ -include_rules = [ - # TODO(vtl): Temporary, until we move lib here. - "+mojo/public/bindings/lib", -] diff --git a/mojo/public/cpp/bindings/allocation_scope.h b/mojo/public/cpp/bindings/allocation_scope.h index e372457..110c9b3 100644 --- a/mojo/public/cpp/bindings/allocation_scope.h +++ b/mojo/public/cpp/bindings/allocation_scope.h @@ -5,7 +5,7 @@ #ifndef MOJO_PUBLIC_CPP_BINDINGS_ALLOCATION_SCOPE_H_ #define MOJO_PUBLIC_CPP_BINDINGS_ALLOCATION_SCOPE_H_ -#include "mojo/public/bindings/lib/scratch_buffer.h" +#include "mojo/public/cpp/bindings/lib/scratch_buffer.h" #include "mojo/public/cpp/system/macros.h" namespace mojo { diff --git a/mojo/public/cpp/bindings/array.h b/mojo/public/cpp/bindings/array.h index 601eedc..72aa56d 100644 --- a/mojo/public/cpp/bindings/array.h +++ b/mojo/public/cpp/bindings/array.h @@ -11,7 +11,7 @@ #include #include -#include "mojo/public/bindings/lib/array_internal.h" +#include "mojo/public/cpp/bindings/lib/array_internal.h" #include "mojo/public/cpp/bindings/type_converter.h" namespace mojo { diff --git a/mojo/public/cpp/bindings/callback.h b/mojo/public/cpp/bindings/callback.h index 766c9c3..4192f89 100644 --- a/mojo/public/cpp/bindings/callback.h +++ b/mojo/public/cpp/bindings/callback.h @@ -11,8 +11,8 @@ #ifndef MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_ #define MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_ -#include "mojo/public/bindings/lib/callback_internal.h" -#include "mojo/public/bindings/lib/shared_ptr.h" +#include "mojo/public/cpp/bindings/lib/callback_internal.h" +#include "mojo/public/cpp/bindings/lib/shared_ptr.h" namespace mojo { diff --git a/mojo/public/cpp/bindings/callback.h.pump b/mojo/public/cpp/bindings/callback.h.pump index 998324f..5452abb 100644 --- a/mojo/public/cpp/bindings/callback.h.pump +++ b/mojo/public/cpp/bindings/callback.h.pump @@ -14,8 +14,8 @@ $var MAX_ARITY = 7 #ifndef MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_ #define MOJO_PUBLIC_CPP_BINDINGS_CALLBACK_H_ -#include "mojo/public/bindings/lib/callback_internal.h" -#include "mojo/public/bindings/lib/shared_ptr.h" +#include "mojo/public/cpp/bindings/lib/callback_internal.h" +#include "mojo/public/cpp/bindings/lib/shared_ptr.h" namespace mojo { diff --git a/mojo/public/cpp/bindings/lib/DEPS b/mojo/public/cpp/bindings/lib/DEPS new file mode 100644 index 0000000..b809b58 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/DEPS @@ -0,0 +1,5 @@ +include_rules = [ + "+mojo/public/cpp/bindings", + "+mojo/public/cpp/environment", + "+mojo/public/cpp/system", +] diff --git a/mojo/public/cpp/bindings/lib/TODO b/mojo/public/cpp/bindings/lib/TODO new file mode 100644 index 0000000..318edcf --- /dev/null +++ b/mojo/public/cpp/bindings/lib/TODO @@ -0,0 +1,7 @@ +TODOs: + - Ensure validation checks are solid + - Add tests of validation logic + - Optimize Buffer classes? + - Make "Clone" method public? + - Add compile-time asserts to verify object packing and padding. + - Investigate making arrays of objects not be arrays of pointers. diff --git a/mojo/public/cpp/bindings/lib/array.cc b/mojo/public/cpp/bindings/lib/array.cc new file mode 100644 index 0000000..6745adc --- /dev/null +++ b/mojo/public/cpp/bindings/lib/array.cc @@ -0,0 +1,38 @@ +// 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. + +#include "mojo/public/cpp/bindings/array.h" + +namespace mojo { + +// static +String TypeConverter::ConvertFrom(const std::string& input, + Buffer* buf) { + String::Builder result(input.size(), buf); + if (!input.empty()) + memcpy(&result[0], input.data(), input.size()); + return result.Finish(); +} +// static +std::string TypeConverter::ConvertTo(const String& input) { + if (input.is_null() || input.size() == 0) + return std::string(); + + return std::string(&input[0], &input[0] + input.size()); +} + +// static +String TypeConverter::ConvertFrom(const char* input, + Buffer* buf) { + if (!input) + return String(); + + size_t size = strlen(input); + String::Builder result(size, buf); + if (size != 0) + memcpy(&result[0], input, size); + return result.Finish(); +} + +} // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/array_internal.cc b/mojo/public/cpp/bindings/lib/array_internal.cc new file mode 100644 index 0000000..efdda8c --- /dev/null +++ b/mojo/public/cpp/bindings/lib/array_internal.cc @@ -0,0 +1,59 @@ +// 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. + +#include "mojo/public/cpp/bindings/lib/array_internal.h" + +namespace mojo { +namespace internal { + +ArrayDataTraits::BitRef::~BitRef() { +} + +ArrayDataTraits::BitRef::BitRef(uint8_t* storage, uint8_t mask) + : storage_(storage), + mask_(mask) { +} + +ArrayDataTraits::BitRef& +ArrayDataTraits::BitRef::operator=(bool value) { + if (value) { + *storage_ |= mask_; + } else { + *storage_ &= ~mask_; + } + return *this; +} + +ArrayDataTraits::BitRef& +ArrayDataTraits::BitRef::operator=(const BitRef& value) { + return (*this) = static_cast(value); +} + +ArrayDataTraits::BitRef::operator bool() const { + return (*storage_ & mask_) != 0; +} + +// static +void ArraySerializationHelper::EncodePointersAndHandles( + const ArrayHeader* header, + ElementType* elements, + std::vector* handles) { + for (uint32_t i = 0; i < header->num_elements; ++i) + EncodeHandle(&elements[i], handles); +} + +// static +bool ArraySerializationHelper::DecodePointersAndHandles( + const ArrayHeader* header, + ElementType* elements, + Message* message) { + for (uint32_t i = 0; i < header->num_elements; ++i) { + if (!DecodeHandle(&elements[i], message->mutable_handles())) + return false; + } + return true; +} + +} // namespace internal +} // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/array_internal.h b/mojo/public/cpp/bindings/lib/array_internal.h new file mode 100644 index 0000000..978dca3 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/array_internal.h @@ -0,0 +1,372 @@ +// 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_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ + +#include + +#include "mojo/public/cpp/bindings/buffer.h" +#include "mojo/public/cpp/bindings/lib/bindings_internal.h" +#include "mojo/public/cpp/bindings/lib/bindings_serialization.h" +#include "mojo/public/cpp/bindings/passable.h" +#include "mojo/public/cpp/system/core.h" + +namespace mojo { +template class Array; + +namespace internal { + +template +struct ArrayDataTraits { + typedef T StorageType; + typedef Array Wrapper; + typedef T& Ref; + typedef T const& ConstRef; + + static size_t GetStorageSize(size_t num_elements) { + return sizeof(StorageType) * num_elements; + } + static Ref ToRef(StorageType* storage, size_t offset) { + return storage[offset]; + } + static ConstRef ToConstRef(const StorageType* storage, size_t offset) { + return storage[offset]; + } +}; + +template +struct ArrayDataTraits { + typedef StructPointer

StorageType; + typedef Array Wrapper; + typedef P*& Ref; + typedef P* const& ConstRef; + + static size_t GetStorageSize(size_t num_elements) { + return sizeof(StorageType) * num_elements; + } + static Ref ToRef(StorageType* storage, size_t offset) { + return storage[offset].ptr; + } + static ConstRef ToConstRef(const StorageType* storage, size_t offset) { + return storage[offset].ptr; + } +}; + +// Specialization of Arrays for bools, optimized for space. It has the +// following differences from a generalized Array: +// * Each element takes up a single bit of memory. +// * Accessing a non-const single element uses a helper class |BitRef|, which +// emulates a reference to a bool. +template <> +struct ArrayDataTraits { + // Helper class to emulate a reference to a bool, used for direct element + // access. + class BitRef { + public: + ~BitRef(); + BitRef& operator=(bool value); + BitRef& operator=(const BitRef& value); + operator bool() const; + private: + friend struct ArrayDataTraits; + BitRef(uint8_t* storage, uint8_t mask); + BitRef(); + uint8_t* storage_; + uint8_t mask_; + }; + + typedef uint8_t StorageType; + typedef Array Wrapper; + typedef BitRef Ref; + typedef bool ConstRef; + + static size_t GetStorageSize(size_t num_elements) { + return ((num_elements + 7) / 8); + } + static BitRef ToRef(StorageType* storage, size_t offset) { + return BitRef(&storage[offset / 8], 1 << (offset % 8)); + } + static bool ToConstRef(const StorageType* storage, size_t offset) { + return (storage[offset / 8] & (1 << (offset % 8))) != 0; + } +}; + +// What follows is code to support the serialization of Array_Data. There +// are two interesting cases: arrays of primitives and arrays of objects. +// Arrays of objects are represented as arrays of pointers to objects. + +template +struct ArraySerializationHelper { + typedef T ElementType; + + static size_t ComputeSizeOfElements(const ArrayHeader* header, + const ElementType* elements) { + return 0; + } + + static void CloneElements(const ArrayHeader* header, + ElementType* elements, + Buffer* buf) { + } + + static void EncodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + std::vector* handles) { + } + + static bool DecodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + Message* message) { + return true; + } +}; + +template <> +struct ArraySerializationHelper { + typedef Handle ElementType; + + static size_t ComputeSizeOfElements(const ArrayHeader* header, + const ElementType* elements) { + return 0; + } + + static void CloneElements(const ArrayHeader* header, + ElementType* elements, + Buffer* buf) { + } + + static void EncodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + std::vector* handles); + + static bool DecodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + Message* message); +}; + +template +struct ArraySerializationHelper { + typedef StructPointer

ElementType; + + static size_t ComputeSizeOfElements(const ArrayHeader* header, + const ElementType* elements) { + size_t result = 0; + for (uint32_t i = 0; i < header->num_elements; ++i) { + if (elements[i].ptr) + result += elements[i].ptr->ComputeSize(); + } + return result; + } + + static void CloneElements(const ArrayHeader* header, + ElementType* elements, + Buffer* buf) { + for (uint32_t i = 0; i < header->num_elements; ++i) { + if (elements[i].ptr) + elements[i].ptr = elements[i].ptr->Clone(buf); + } + } + + static void EncodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + std::vector* handles) { + for (uint32_t i = 0; i < header->num_elements; ++i) + Encode(&elements[i], handles); + } + + static bool DecodePointersAndHandles(const ArrayHeader* header, + ElementType* elements, + Message* message) { + for (uint32_t i = 0; i < header->num_elements; ++i) { + if (!Decode(&elements[i], message)) + return false; + } + return true; + } +}; + +template +class Array_Data { + public: + typedef ArrayDataTraits Traits; + typedef typename Traits::StorageType StorageType; + typedef typename Traits::Wrapper Wrapper; + typedef typename Traits::Ref Ref; + typedef typename Traits::ConstRef ConstRef; + + static Array_Data* New(size_t num_elements, Buffer* buf) { + size_t num_bytes = sizeof(Array_Data) + + Traits::GetStorageSize(num_elements); + return new (buf->Allocate(num_bytes)) Array_Data(num_bytes, + num_elements); + } + + size_t size() const { return header_.num_elements; } + + Ref at(size_t offset) { + assert(offset < static_cast(header_.num_elements)); + return Traits::ToRef(storage(), offset); + } + + ConstRef at(size_t offset) const { + assert(offset < static_cast(header_.num_elements)); + return Traits::ToConstRef(storage(), offset); + } + + StorageType* storage() { + return reinterpret_cast( + reinterpret_cast(this) + sizeof(*this)); + } + + const StorageType* storage() const { + return reinterpret_cast( + reinterpret_cast(this) + sizeof(*this)); + } + + size_t ComputeSize() const { + return Align(header_.num_bytes) + + ArraySerializationHelper::ComputeSizeOfElements(&header_, storage()); + } + + Array_Data* Clone(Buffer* buf) const { + Array_Data* clone = New(header_.num_elements, buf); + memcpy(clone->storage(), + storage(), + header_.num_bytes - sizeof(Array_Data)); + + ArraySerializationHelper::CloneElements(&clone->header_, + clone->storage(), buf); + return clone; + } + + void CloseHandles() { + // TODO(darin): Implement! + } + + void EncodePointersAndHandles(std::vector* handles) { + ArraySerializationHelper::EncodePointersAndHandles(&header_, storage(), + handles); + } + + bool DecodePointersAndHandles(Message* message) { + return ArraySerializationHelper::DecodePointersAndHandles(&header_, + storage(), + message); + } + + private: + Array_Data(size_t num_bytes, size_t num_elements) { + header_.num_bytes = static_cast(num_bytes); + header_.num_elements = static_cast(num_elements); + } + ~Array_Data() {} + + internal::ArrayHeader header_; + + // Elements of type internal::ArrayDataTraits::StorageType follow. +}; +MOJO_COMPILE_ASSERT(sizeof(Array_Data) == 8, bad_sizeof_Array_Data); + +// UTF-8 encoded +typedef Array_Data String_Data; + +template struct ArrayTraits {}; + +template struct ArrayTraits { + typedef Array_Data DataType; + typedef const T& ConstRef; + typedef T& Ref; + static typename T::Data* ToArrayElement(const T& value) { + return Unwrap(value); + } + // Something sketchy is indeed happening here... + static Ref ToRef(typename T::Data*& data) { + return *reinterpret_cast(&data); + } + static ConstRef ToConstRef(typename T::Data* const& data) { + return *reinterpret_cast(&data); + } +}; + +template struct ArrayTraits { + typedef Array_Data DataType; + typedef const T& ConstRef; + typedef T& Ref; + static T ToArrayElement(const T& value) { + return value; + } + static Ref ToRef(T& data) { return data; } + static ConstRef ToConstRef(const T& data) { return data; } +}; + +template <> struct ArrayTraits { + typedef Array_Data DataType; + typedef bool ConstRef; + typedef ArrayDataTraits::Ref Ref; + static bool ToArrayElement(const bool& value) { + return value; + } + static Ref ToRef(const Ref& data) { return data; } + static ConstRef ToConstRef(ConstRef data) { return data; } +}; + +template <> struct ArrayTraits { + typedef Array_Data DataType; + typedef Passable ConstRef; + typedef AssignableAndPassable Ref; + static Handle ToArrayElement(const Handle& value) { + return value; + } + static Ref ToRef(Handle& data) { return Ref(&data); } + static ConstRef ToConstRef(const Handle& data) { + return ConstRef(const_cast(&data)); + } +}; + +template <> struct ArrayTraits { + typedef Array_Data DataType; + typedef Passable ConstRef; + typedef AssignableAndPassable Ref; + static DataPipeConsumerHandle ToArrayElement( + const DataPipeConsumerHandle& value) { + return value; + } + static Ref ToRef(DataPipeConsumerHandle& data) { return Ref(&data); } + static ConstRef ToConstRef(const DataPipeConsumerHandle& data) { + return ConstRef(const_cast(&data)); + } +}; + +template <> struct ArrayTraits { + typedef Array_Data DataType; + typedef Passable ConstRef; + typedef AssignableAndPassable Ref; + static DataPipeProducerHandle ToArrayElement( + const DataPipeProducerHandle& value) { + return value; + } + static Ref ToRef(DataPipeProducerHandle& data) { return Ref(&data); } + static ConstRef ToConstRef(const DataPipeProducerHandle& data) { + return ConstRef(const_cast(&data)); + } +}; + +template <> struct ArrayTraits { + typedef Array_Data DataType; + typedef Passable ConstRef; + typedef AssignableAndPassable Ref; + static MessagePipeHandle ToArrayElement(const MessagePipeHandle& value) { + return value; + } + static Ref ToRef(MessagePipeHandle& data) { return Ref(&data); } + static ConstRef ToConstRef(const MessagePipeHandle& data) { + return ConstRef(const_cast(&data)); + } +}; + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_INTERNAL_H_ diff --git a/mojo/public/cpp/bindings/lib/bindings_internal.h b/mojo/public/cpp/bindings/lib/bindings_internal.h new file mode 100644 index 0000000..ef6fc47 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/bindings_internal.h @@ -0,0 +1,141 @@ +// 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_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_INTERNAL_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_INTERNAL_H_ + +#include "mojo/public/cpp/system/core.h" + +namespace mojo { +namespace internal { +template class Array_Data; + +#pragma pack(push, 1) + +struct StructHeader { + uint32_t num_bytes; + uint32_t num_fields; +}; +MOJO_COMPILE_ASSERT(sizeof(StructHeader) == 8, bad_sizeof_StructHeader); + +struct ArrayHeader { + uint32_t num_bytes; + uint32_t num_elements; +}; +MOJO_COMPILE_ASSERT(sizeof(ArrayHeader) == 8, bad_sizeof_ArrayHeader); + +template +union StructPointer { + uint64_t offset; + T* ptr; +}; +MOJO_COMPILE_ASSERT(sizeof(StructPointer) == 8, bad_sizeof_StructPointer); + +template +union ArrayPointer { + uint64_t offset; + Array_Data* ptr; +}; +MOJO_COMPILE_ASSERT(sizeof(ArrayPointer) == 8, bad_sizeof_ArrayPointer); + +union StringPointer { + uint64_t offset; + Array_Data* ptr; +}; +MOJO_COMPILE_ASSERT(sizeof(StringPointer) == 8, bad_sizeof_StringPointer); + +#pragma pack(pop) + +template +void ResetIfNonNull(T* ptr) { + if (ptr) + *ptr = T(); +} + +template +T FetchAndReset(T* ptr) { + T temp = *ptr; + *ptr = T(); + return temp; +} + +template +class WrapperHelper { + public: + static const T Wrap(const typename T::Data* data) { + return T(typename T::Wrap(), const_cast(data)); + } + static typename T::Data* Unwrap(const T& object) { + return const_cast(object.data_); + } +}; + +template +inline const typename Data::Wrapper Wrap(const Data* data) { + return WrapperHelper::Wrap(data); +} + +template +inline typename T::Data* Unwrap(const T& object) { + return WrapperHelper::Unwrap(object); +} + +template struct TypeTraits { + static const bool kIsObject = true; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; +template <> struct TypeTraits { + static const bool kIsObject = false; +}; + +template class ObjectTraits {}; + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_INTERNAL_H_ diff --git a/mojo/public/cpp/bindings/lib/bindings_serialization.cc b/mojo/public/cpp/bindings/lib/bindings_serialization.cc new file mode 100644 index 0000000..ff06d95 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/bindings_serialization.cc @@ -0,0 +1,73 @@ +// 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. + +#include "mojo/public/cpp/bindings/lib/bindings_serialization.h" + +#include + +#include "mojo/public/cpp/bindings/lib/bindings_internal.h" + +namespace mojo { +namespace internal { + +size_t Align(size_t size) { + const size_t kAlignment = 8; + return size + (kAlignment - (size % kAlignment)) % kAlignment; +} + +void EncodePointer(const void* ptr, uint64_t* offset) { + if (!ptr) { + *offset = 0; + return; + } + + const char* p_obj = reinterpret_cast(ptr); + const char* p_slot = reinterpret_cast(offset); + assert(p_obj > p_slot); + + *offset = static_cast(p_obj - p_slot); +} + +const void* DecodePointerRaw(const uint64_t* offset) { + if (!*offset) + return NULL; + return reinterpret_cast(offset) + *offset; +} + +bool ValidatePointer(const void* ptr, const Message& message) { + const uint8_t* data = static_cast(ptr); + if (reinterpret_cast(data) % 8 != 0) + return false; + + const uint8_t* data_start = message.data(); + const uint8_t* data_end = data_start + message.data_num_bytes(); + + return data >= data_start && data < data_end; +} + +void EncodeHandle(Handle* handle, std::vector* handles) { + if (handle->is_valid()) { + handles->push_back(*handle); + handle->set_value(static_cast(handles->size() - 1)); + } else { + // Encode -1 to mean the invalid handle. + handle->set_value(static_cast(-1)); + } +} + +bool DecodeHandle(Handle* handle, std::vector* handles) { + // Decode -1 to mean the invalid handle. + if (handle->value() == static_cast(-1)) { + *handle = Handle(); + return true; + } + if (handle->value() >= handles->size()) + return false; + // Just leave holes in the vector so we don't screw up other indices. + *handle = FetchAndReset(&handles->at(handle->value())); + return true; +} + +} // namespace internal +} // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/bindings_serialization.h b/mojo/public/cpp/bindings/lib/bindings_serialization.h new file mode 100644 index 0000000..a860b14 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/bindings_serialization.h @@ -0,0 +1,67 @@ +// 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_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ + +#include + +#include "mojo/public/cpp/bindings/buffer.h" +#include "mojo/public/cpp/bindings/message.h" + +namespace mojo { +namespace internal { + +size_t Align(size_t size); + +// Pointers are encoded as relative offsets. The offsets are relative to the +// address of where the offset value is stored, such that the pointer may be +// recovered with the expression: +// +// ptr = reinterpret_cast(offset) + *offset +// +// A null pointer is encoded as an offset value of 0. +// +void EncodePointer(const void* ptr, uint64_t* offset); +const void* DecodePointerRaw(const uint64_t* offset); + +template +inline void DecodePointer(const uint64_t* offset, T** ptr) { + *ptr = reinterpret_cast(const_cast(DecodePointerRaw(offset))); +} + +// Check that the given pointer references memory contained within the message. +bool ValidatePointer(const void* ptr, const Message& message); + +// Handles are encoded as indices into a vector of handles. These functions +// manipulate the value of |handle|, mapping it to and from an index. +void EncodeHandle(Handle* handle, std::vector* handles); +bool DecodeHandle(Handle* handle, std::vector* handles); + +// The following 2 functions are used to encode/decode all objects (structs and +// arrays) in a consistent manner. + +template +inline void Encode(T* obj, std::vector* handles) { + if (obj->ptr) + obj->ptr->EncodePointersAndHandles(handles); + EncodePointer(obj->ptr, &obj->offset); +} + +template +inline bool Decode(T* obj, Message* message) { + DecodePointer(&obj->offset, &obj->ptr); + if (obj->ptr) { + if (!ValidatePointer(obj->ptr, *message)) + return false; + if (!obj->ptr->DecodePointersAndHandles(message)) + return false; + } + return true; +} + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_BINDINGS_SERIALIZATION_H_ diff --git a/mojo/public/cpp/bindings/lib/buffer.cc b/mojo/public/cpp/bindings/lib/buffer.cc new file mode 100644 index 0000000..4404df8 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/buffer.cc @@ -0,0 +1,27 @@ +// 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. + +#include "mojo/public/cpp/bindings/buffer.h" + +#include + +#include "mojo/public/cpp/environment/buffer_tls.h" +#include "mojo/public/cpp/system/macros.h" + +namespace mojo { + +Buffer::Buffer() { + previous_ = internal::SetCurrentBuffer(this); +} + +Buffer::~Buffer() { + Buffer* buf MOJO_ALLOW_UNUSED = internal::SetCurrentBuffer(previous_); + assert(buf == this); +} + +Buffer* Buffer::current() { + return internal::GetCurrentBuffer(); +} + +} // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/callback_internal.h b/mojo/public/cpp/bindings/lib/callback_internal.h new file mode 100644 index 0000000..4802e43 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/callback_internal.h @@ -0,0 +1,55 @@ +// Copyright 2014 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_PUBLIC_CPP_BINDINGS_LIB_CALLBACK_INTERNAL_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_CALLBACK_INTERNAL_H_ + +#include "mojo/public/cpp/bindings/lib/bindings_internal.h" + +namespace mojo { +namespace internal { + +template ::kIsObject> +struct Callback_ParamTraits {}; + +template +struct Callback_ParamTraits { + typedef const T& ForwardType; + static const bool kIsScopedHandle = false; +}; + +template +struct Callback_ParamTraits { + typedef T ForwardType; + static const bool kIsScopedHandle = false; +}; + +template +struct Callback_ParamTraits, true> { + typedef ScopedHandleBase ForwardType; + static const bool kIsScopedHandle = true; +}; + +template +struct EnableIf {}; + +template +struct EnableIf { typedef T type; }; + +template +typename EnableIf::kIsScopedHandle, T>::type& + Callback_Forward(T& t) { + return t; +} + +template +typename EnableIf::kIsScopedHandle, T>::type + Callback_Forward(T& t) { + return t.Pass(); +} + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_CALLBACK_INTERNAL_H_ diff --git a/mojo/public/cpp/bindings/lib/connector.cc b/mojo/public/cpp/bindings/lib/connector.cc new file mode 100644 index 0000000..319631c --- /dev/null +++ b/mojo/public/cpp/bindings/lib/connector.cc @@ -0,0 +1,130 @@ +// 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. + +#include "mojo/public/cpp/bindings/lib/connector.h" + +#include +#include + +#include "mojo/public/cpp/bindings/error_handler.h" + +namespace mojo { +namespace internal { + +// ---------------------------------------------------------------------------- + +Connector::Connector(ScopedMessagePipeHandle message_pipe, + MojoAsyncWaiter* waiter) + : error_handler_(NULL), + waiter_(waiter), + message_pipe_(message_pipe.Pass()), + incoming_receiver_(NULL), + async_wait_id_(0), + error_(false), + drop_writes_(false) { + // Even though we don't have an incoming receiver, we still want to monitor + // the message pipe to know if is closed or encounters an error. + WaitToReadMore(); +} + +Connector::~Connector() { + if (async_wait_id_) + waiter_->CancelWait(waiter_, async_wait_id_); +} + +void Connector::CloseMessagePipe() { + Close(message_pipe_.Pass()); +} + +bool Connector::Accept(Message* message) { + if (error_) + return false; + + if (drop_writes_) + return true; + + MojoResult rv = WriteMessageRaw( + message_pipe_.get(), + message->data(), + message->data_num_bytes(), + message->mutable_handles()->empty() ? NULL : + reinterpret_cast( + &message->mutable_handles()->front()), + static_cast(message->mutable_handles()->size()), + MOJO_WRITE_MESSAGE_FLAG_NONE); + + switch (rv) { + case MOJO_RESULT_OK: + // The handles were successfully transferred, so we don't need the message + // to track their lifetime any longer. + message->mutable_handles()->clear(); + break; + case MOJO_RESULT_FAILED_PRECONDITION: + // There's no point in continuing to write to this pipe since the other + // end is gone. Avoid writing any future messages. Hide write failures + // from the caller since we'd like them to continue consuming any backlog + // of incoming messages before regarding the message pipe as closed. + drop_writes_ = true; + break; + default: + // This particular write was rejected, presumably because of bad input. + // The pipe is not necessarily in a bad state. + return false; + } + return true; +} + +bool Connector::AcceptWithResponder(Message* message, + MessageReceiver* responder) { + // TODO(darin): Implement this! + assert(false); + return false; +} + +// static +void Connector::CallOnHandleReady(void* closure, MojoResult result) { + Connector* self = static_cast(closure); + self->OnHandleReady(result); +} + +void Connector::OnHandleReady(MojoResult result) { + async_wait_id_ = 0; + + if (result == MOJO_RESULT_OK) { + ReadMore(); + } else { + error_ = true; + } + + if (error_ && error_handler_) + error_handler_->OnError(); +} + +void Connector::WaitToReadMore() { + async_wait_id_ = waiter_->AsyncWait(waiter_, + message_pipe_.get().value(), + MOJO_WAIT_FLAG_READABLE, + MOJO_DEADLINE_INDEFINITE, + &Connector::CallOnHandleReady, + this); +} + +void Connector::ReadMore() { + while (true) { + MojoResult rv; + + rv = ReadAndDispatchMessage(message_pipe_.get(), incoming_receiver_, NULL); + if (rv == MOJO_RESULT_SHOULD_WAIT) { + WaitToReadMore(); + break; + } + if (rv != MOJO_RESULT_OK) { + error_ = true; + break; + } + } +} + +} // namespace internal +} // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/connector.h b/mojo/public/cpp/bindings/lib/connector.h new file mode 100644 index 0000000..21107d5 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/connector.h @@ -0,0 +1,80 @@ +// 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_PUBLIC_CPP_BINDINGS_LIB_CONNECTOR_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_CONNECTOR_H_ + +#include "mojo/public/cpp/bindings/lib/message_queue.h" +#include "mojo/public/cpp/bindings/message.h" +#include "mojo/public/cpp/environment/default_async_waiter.h" +#include "mojo/public/cpp/system/core.h" + +namespace mojo { +class ErrorHandler; + +namespace internal { + +// The Connector class is responsible for performing read/write operations on a +// MessagePipe. It writes messages it receives through the MessageReceiver +// interface that it subclasses, and it forwards messages it reads through the +// MessageReceiver interface assigned as its incoming receiver. +// +// NOTE: MessagePipe I/O is non-blocking. +// +class Connector : public MessageReceiver { + public: + // The Connector takes ownership of |message_pipe|. + explicit Connector(ScopedMessagePipeHandle message_pipe, + MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()); + virtual ~Connector(); + + // Sets the receiver to handle messages read from the message pipe. The + // Connector will read messages from the pipe regardless of whether or not an + // incoming receiver has been set. + void set_incoming_receiver(MessageReceiver* receiver) { + incoming_receiver_ = receiver; + } + + // Sets the error handler to receive notifications when an error is + // encountered while reading from the pipe or waiting to read from the pipe. + void set_error_handler(ErrorHandler* error_handler) { + error_handler_ = error_handler; + } + + // Returns true if an error was encountered while reading from the pipe or + // waiting to read from the pipe. + bool encountered_error() const { return error_; } + + // Closes the pipe, triggering the error state. + void CloseMessagePipe(); + + // MessageReceiver implementation: + virtual bool Accept(Message* message) MOJO_OVERRIDE; + virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder) + MOJO_OVERRIDE; + + private: + static void CallOnHandleReady(void* closure, MojoResult result); + void OnHandleReady(MojoResult result); + + void WaitToReadMore(); + void ReadMore(); + + ErrorHandler* error_handler_; + MojoAsyncWaiter* waiter_; + + ScopedMessagePipeHandle message_pipe_; + MessageReceiver* incoming_receiver_; + + MojoAsyncWaitID async_wait_id_; + bool error_; + bool drop_writes_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(Connector); +}; + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_CONNECTOR_H_ diff --git a/mojo/public/cpp/bindings/lib/fixed_buffer.cc b/mojo/public/cpp/bindings/lib/fixed_buffer.cc new file mode 100644 index 0000000..7e19ae2 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/fixed_buffer.cc @@ -0,0 +1,54 @@ +// Copyright 2014 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. + +#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" + +#include +#include +#include + +#include + +#include "mojo/public/cpp/bindings/lib/bindings_serialization.h" + +namespace mojo { +namespace internal { + +FixedBuffer::FixedBuffer(size_t size) + : ptr_(NULL), + cursor_(0), + size_(internal::Align(size)) { + ptr_ = static_cast(calloc(size_, 1)); +} + +FixedBuffer::~FixedBuffer() { + free(ptr_); +} + +void* FixedBuffer::Allocate(size_t delta, Destructor dtor) { + assert(!dtor); + + delta = internal::Align(delta); + + if (delta == 0 || delta > size_ - cursor_) { + assert(false); + return NULL; + } + + char* result = ptr_ + cursor_; + cursor_ += delta; + + return result; +} + +void* FixedBuffer::Leak() { + char* ptr = ptr_; + ptr_ = NULL; + cursor_ = 0; + size_ = 0; + return ptr; +} + +} // namespace internal +} // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/fixed_buffer.h b/mojo/public/cpp/bindings/lib/fixed_buffer.h new file mode 100644 index 0000000..f4a9905 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/fixed_buffer.h @@ -0,0 +1,68 @@ +// Copyright 2014 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_PUBLIC_CPP_BINDINGS_LIB_FIXED_BUFFER_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_FIXED_BUFFER_H_ + +#include "mojo/public/cpp/bindings/buffer.h" +#include "mojo/public/cpp/system/macros.h" + +namespace mojo { +namespace internal { + +// FixedBuffer provides a simple way to allocate objects within a fixed chunk +// of memory. Objects are allocated by calling the |Allocate| method, which +// extends the buffer accordingly. Objects allocated in this way are not freed +// explicitly. Instead, they remain valid so long as the FixedBuffer remains +// valid. The Leak method may be used to steal the underlying memory from the +// FixedBuffer. +// +// Typical usage: +// +// { +// FixedBuffer buf(8 + 8); +// +// int* a = static_cast(buf->Allocate(sizeof(int))); +// *a = 2; +// +// double* b = static_cast(buf->Allocate(sizeof(double))); +// *b = 3.14f; +// +// void* data = buf.Leak(); +// Process(data); +// +// free(data); +// } +// +class FixedBuffer : public Buffer { + public: + explicit FixedBuffer(size_t size); + virtual ~FixedBuffer(); + + // Grows the buffer by |num_bytes| and returns a pointer to the start of the + // addition. The resulting address is 8-byte aligned, and the content of the + // memory is zero-filled. + virtual void* Allocate(size_t num_bytes, Destructor func = NULL) + MOJO_OVERRIDE; + + size_t size() const { return size_; } + + // Returns the internal memory owned by the Buffer to the caller. The Buffer + // relinquishes its pointer, effectively resetting the state of the Buffer + // and leaving the caller responsible for freeing the returned memory address + // when no longer needed. + void* Leak(); + + private: + char* ptr_; + size_t cursor_; + size_t size_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(FixedBuffer); +}; + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_FIXED_BUFFER_H_ diff --git a/mojo/public/cpp/bindings/lib/interface.cc b/mojo/public/cpp/bindings/lib/interface.cc new file mode 100644 index 0000000..3b552be --- /dev/null +++ b/mojo/public/cpp/bindings/lib/interface.cc @@ -0,0 +1,19 @@ +// Copyright 2014 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. + +#include "mojo/public/cpp/bindings/interface.h" + +namespace mojo { + +bool NoInterfaceStub::Accept(Message* message) { + return false; +} + +bool NoInterfaceStub::AcceptWithResponder(Message* message, + MessageReceiver* responder) { + return false; +} + +} // namespace mojo + diff --git a/mojo/public/cpp/bindings/lib/message.cc b/mojo/public/cpp/bindings/lib/message.cc new file mode 100644 index 0000000..8ec188e2 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/message.cc @@ -0,0 +1,84 @@ +// 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. + +#include "mojo/public/cpp/bindings/message.h" + +#include +#include + +#include + +namespace mojo { + +Message::Message() + : data_num_bytes_(0), + data_(NULL) { +} + +Message::~Message() { + free(data_); + + for (std::vector::iterator it = handles_.begin(); + it != handles_.end(); ++it) { + if (it->is_valid()) + CloseRaw(*it); + } +} + +void Message::AllocUninitializedData(uint32_t num_bytes) { + assert(!data_); + data_num_bytes_ = num_bytes; + data_ = static_cast(malloc(num_bytes)); +} + +void Message::AdoptData(uint32_t num_bytes, internal::MessageData* data) { + assert(!data_); + data_num_bytes_ = num_bytes; + data_ = data; +} + +void Message::Swap(Message* other) { + std::swap(data_num_bytes_, other->data_num_bytes_); + std::swap(data_, other->data_); + std::swap(handles_, other->handles_); +} + +MojoResult ReadAndDispatchMessage(MessagePipeHandle handle, + MessageReceiver* receiver, + bool* receiver_result) { + MojoResult rv; + + uint32_t num_bytes = 0, num_handles = 0; + rv = ReadMessageRaw(handle, + NULL, + &num_bytes, + NULL, + &num_handles, + MOJO_READ_MESSAGE_FLAG_NONE); + if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED) + return rv; + + Message message; + message.AllocUninitializedData(num_bytes); + message.mutable_handles()->resize(num_handles); + + rv = ReadMessageRaw(handle, + message.mutable_data(), + &num_bytes, + message.mutable_handles()->empty() + ? NULL + : reinterpret_cast( + &message.mutable_handles()->front()), + &num_handles, + MOJO_READ_MESSAGE_FLAG_NONE); + if (receiver && rv == MOJO_RESULT_OK) { + bool result = receiver->Accept(&message); + if (receiver_result) + *receiver_result = result; + } + + return rv; +} + +} // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/message_builder.cc b/mojo/public/cpp/bindings/lib/message_builder.cc new file mode 100644 index 0000000..c746644 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/message_builder.cc @@ -0,0 +1,52 @@ +// 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. + +#include "mojo/public/cpp/bindings/lib/message_builder.h" + +#include "mojo/public/cpp/bindings/message.h" + +namespace mojo { +namespace internal { + +template +void Allocate(Buffer* buf, Header** header) { + *header = static_cast(buf->Allocate(sizeof(Header))); + (*header)->num_bytes = sizeof(Header); +} + +MessageBuilder::MessageBuilder(uint32_t name, size_t payload_size) + : buf_(sizeof(MessageHeader) + payload_size) { + MessageHeader* header; + Allocate(&buf_, &header); + header->num_fields = 2; + header->name = name; +} + +MessageBuilder::~MessageBuilder() { +} + +void MessageBuilder::Finish(Message* message) { + uint32_t num_bytes = static_cast(buf_.size()); + message->AdoptData(num_bytes, static_cast(buf_.Leak())); +} + +MessageBuilder::MessageBuilder(size_t size) + : buf_(size) { +} + +MessageWithRequestIDBuilder::MessageWithRequestIDBuilder(uint32_t name, + size_t payload_size, + uint32_t flags, + uint64_t request_id) + : MessageBuilder(sizeof(MessageHeaderWithRequestID) + payload_size) { + MessageHeaderWithRequestID* header; + Allocate(&buf_, &header); + header->num_fields = 3; + header->name = name; + header->flags = flags; + header->request_id = request_id; +} + +} // namespace internal +} // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/message_builder.h b/mojo/public/cpp/bindings/lib/message_builder.h new file mode 100644 index 0000000..b4988ff9 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/message_builder.h @@ -0,0 +1,63 @@ +// 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_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_BUILDER_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_BUILDER_H_ + +#include + +#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" +#include "mojo/public/cpp/bindings/lib/message_internal.h" + +namespace mojo { +class Message; + +namespace internal { + +class MessageBuilder { + public: + MessageBuilder(uint32_t name, size_t payload_size); + ~MessageBuilder(); + + Buffer* buffer() { return &buf_; } + + // Call Finish when done making allocations in |buffer()|. Upon return, + // |message| will contain the message data, and |buffer()| will no longer be + // valid to reference. + void Finish(Message* message); + + protected: + explicit MessageBuilder(size_t size); + FixedBuffer buf_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(MessageBuilder); +}; + +class MessageWithRequestIDBuilder : public MessageBuilder { + public: + MessageWithRequestIDBuilder(uint32_t name, size_t payload_size, + uint32_t flags, uint64_t request_id); +}; + +class RequestMessageBuilder : public MessageWithRequestIDBuilder { + public: + RequestMessageBuilder(uint32_t name, size_t payload_size) + : MessageWithRequestIDBuilder(name, payload_size, kMessageExpectsResponse, + 0) { + } +}; + +class ResponseMessageBuilder : public MessageWithRequestIDBuilder { + public: + ResponseMessageBuilder(uint32_t name, size_t payload_size, + uint64_t request_id) + : MessageWithRequestIDBuilder(name, payload_size, kMessageIsResponse, + request_id) { + } +}; + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_BUILDER_H_ diff --git a/mojo/public/cpp/bindings/lib/message_internal.h b/mojo/public/cpp/bindings/lib/message_internal.h new file mode 100644 index 0000000..3c67902 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/message_internal.h @@ -0,0 +1,44 @@ +// Copyright 2014 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_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_INTERNAL_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_INTERNAL_H_ + +#include "mojo/public/cpp/bindings/lib/bindings_internal.h" + +namespace mojo { +namespace internal { + +#pragma pack(push, 1) + +enum { + kMessageExpectsResponse = 1 << 0, + kMessageIsResponse = 1 << 1 +}; + +struct MessageHeader : internal::StructHeader { + uint32_t name; + uint32_t flags; +}; +MOJO_COMPILE_ASSERT(sizeof(MessageHeader) == 16, bad_sizeof_MessageHeader); + +struct MessageHeaderWithRequestID : MessageHeader { + uint64_t request_id; +}; +MOJO_COMPILE_ASSERT(sizeof(MessageHeaderWithRequestID) == 24, + bad_sizeof_MessageHeaderWithRequestID); + +struct MessageData { + MessageHeader header; +}; + +MOJO_COMPILE_ASSERT(sizeof(MessageData) == sizeof(MessageHeader), + bad_sizeof_MessageData); + +#pragma pack(pop) + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_INTERNAL_H_ diff --git a/mojo/public/cpp/bindings/lib/message_queue.cc b/mojo/public/cpp/bindings/lib/message_queue.cc new file mode 100644 index 0000000..1982ccb --- /dev/null +++ b/mojo/public/cpp/bindings/lib/message_queue.cc @@ -0,0 +1,50 @@ +// 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. + +#include "mojo/public/cpp/bindings/lib/message_queue.h" + +#include +#include + +#include "mojo/public/cpp/bindings/message.h" + +namespace mojo { +namespace internal { + +MessageQueue::MessageQueue() { +} + +MessageQueue::~MessageQueue() { + while (!queue_.empty()) + Pop(); +} + +bool MessageQueue::IsEmpty() const { + return queue_.empty(); +} + +Message* MessageQueue::Peek() { + assert(!queue_.empty()); + return queue_.front(); +} + +void MessageQueue::Push(Message* message) { + queue_.push(new Message()); + queue_.back()->Swap(message); +} + +void MessageQueue::Pop(Message* message) { + assert(!queue_.empty()); + queue_.front()->Swap(message); + Pop(); +} + +void MessageQueue::Pop() { + assert(!queue_.empty()); + delete queue_.front(); + queue_.pop(); +} + +} // namespace internal +} // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/message_queue.h b/mojo/public/cpp/bindings/lib/message_queue.h new file mode 100644 index 0000000..4e46b54 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/message_queue.h @@ -0,0 +1,47 @@ +// 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_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_QUEUE_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_QUEUE_H_ + +#include + +#include "mojo/public/cpp/system/macros.h" + +namespace mojo { +class Message; + +namespace internal { + +// A queue for Message objects. +class MessageQueue { + public: + MessageQueue(); + ~MessageQueue(); + + bool IsEmpty() const; + Message* Peek(); + + // This method transfers ownership of |message->data| and |message->handles| + // to the message queue, resetting |message| in the process. + void Push(Message* message); + + // Removes the next message from the queue, transferring ownership of its + // data and handles to the given |message|. + void Pop(Message* message); + + // Removes the next message from the queue, discarding its data and handles. + // This is meant to be used in conjunction with |Peek|. + void Pop(); + + private: + std::queue queue_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(MessageQueue); +}; + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_MESSAGE_QUEUE_H_ diff --git a/mojo/public/cpp/bindings/lib/router.cc b/mojo/public/cpp/bindings/lib/router.cc new file mode 100644 index 0000000..594addc --- /dev/null +++ b/mojo/public/cpp/bindings/lib/router.cc @@ -0,0 +1,137 @@ +// Copyright 2014 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. + +#include "mojo/public/cpp/bindings/lib/router.h" + +namespace mojo { +namespace internal { + +// ---------------------------------------------------------------------------- + +class ResponderThunk : public MessageReceiver { + public: + explicit ResponderThunk(const SharedData& router) + : router_(router) { + } + virtual ~ResponderThunk() { + } + + // MessageReceiver implementation: + virtual bool Accept(Message* message) MOJO_OVERRIDE { + assert(message->has_flag(kMessageIsResponse)); + + bool result = false; + + Router* router = router_.value(); + if (router) + result = router->Accept(message); + + return result; + } + + virtual bool AcceptWithResponder(Message* message, + MessageReceiver* responder) MOJO_OVERRIDE { + assert(false); // not reached! + return false; + } + + private: + SharedData router_; +}; + +// ---------------------------------------------------------------------------- + +Router::HandleIncomingMessageThunk::HandleIncomingMessageThunk(Router* router) + : router_(router) { +} + +Router::HandleIncomingMessageThunk::~HandleIncomingMessageThunk() { +} + +bool Router::HandleIncomingMessageThunk::Accept(Message* message) { + return router_->HandleIncomingMessage(message); +} + +bool Router::HandleIncomingMessageThunk::AcceptWithResponder( + Message* message, + MessageReceiver* responder) { + assert(false); // not reached! + return false; +} + +// ---------------------------------------------------------------------------- + +Router::Router(ScopedMessagePipeHandle message_pipe, MojoAsyncWaiter* waiter) + : connector_(message_pipe.Pass(), waiter), + weak_self_(this), + incoming_receiver_(NULL), + thunk_(this), + next_request_id_(0) { + connector_.set_incoming_receiver(&thunk_); +} + +Router::~Router() { + weak_self_.set_value(NULL); +} + +bool Router::Accept(Message* message) { + assert(!message->has_flag(kMessageExpectsResponse)); + return connector_.Accept(message); +} + +bool Router::AcceptWithResponder(Message* message, + MessageReceiver* responder) { + assert(message->has_flag(kMessageExpectsResponse)); + + // Reserve 0 in case we want it to convey special meaning in the future. + uint64_t request_id = next_request_id_++; + if (request_id == 0) + request_id = next_request_id_++; + + message->set_request_id(request_id); + if (!connector_.Accept(message)) + return false; + + // We assume ownership of |responder|. + responders_[request_id] = responder; + return true; +} + +bool Router::HandleIncomingMessage(Message* message) { + if (message->has_flag(kMessageExpectsResponse)) { + if (incoming_receiver_) { + MessageReceiver* responder = new ResponderThunk(weak_self_); + bool ok = incoming_receiver_->AcceptWithResponder(message, responder); + if (!ok) + delete responder; + return ok; + } + + // If we receive a request expecting a response when the client is not + // listening, then we have no choice but to tear down the pipe. + connector_.CloseMessagePipe(); + } else if (message->has_flag(kMessageIsResponse)) { + uint64_t request_id = message->request_id(); + ResponderMap::iterator it = responders_.find(request_id); + if (it == responders_.end()) { + assert(false); + return false; + } + MessageReceiver* responder = it->second; + responders_.erase(it); + responder->Accept(message); + delete responder; + } else { + if (incoming_receiver_) + return incoming_receiver_->Accept(message); + // OK to drop message on the floor. + } + + return false; +} + +// ---------------------------------------------------------------------------- + +} // namespace internal +} // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/router.h b/mojo/public/cpp/bindings/lib/router.h new file mode 100644 index 0000000..31c05f6 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/router.h @@ -0,0 +1,73 @@ +// Copyright 2014 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_PUBLIC_CPP_BINDINGS_LIB_ROUTER_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ROUTER_H_ + +#include + +#include "mojo/public/cpp/bindings/lib/connector.h" +#include "mojo/public/cpp/bindings/lib/shared_data.h" + +namespace mojo { +namespace internal { + +class Router : public MessageReceiver { + public: + // The Router takes ownership of |message_pipe|. + explicit Router(ScopedMessagePipeHandle message_pipe, + MojoAsyncWaiter* waiter = GetDefaultAsyncWaiter()); + virtual ~Router(); + + // Sets the receiver to handle messages read from the message pipe that do + // not have the kMessageIsResponse flag set. + void set_incoming_receiver(MessageReceiver* receiver) { + incoming_receiver_ = receiver; + } + + // Sets the error handler to receive notifications when an error is + // encountered while reading from the pipe or waiting to read from the pipe. + void set_error_handler(ErrorHandler* error_handler) { + connector_.set_error_handler(error_handler); + } + + // Returns true if an error was encountered while reading from the pipe or + // waiting to read from the pipe. + bool encountered_error() const { return connector_.encountered_error(); } + + // MessageReceiver implementation: + virtual bool Accept(Message* message) MOJO_OVERRIDE; + virtual bool AcceptWithResponder(Message* message, MessageReceiver* responder) + MOJO_OVERRIDE; + + private: + typedef std::map ResponderMap; + + class HandleIncomingMessageThunk : public MessageReceiver { + public: + HandleIncomingMessageThunk(Router* router); + virtual ~HandleIncomingMessageThunk(); + + // MessageReceiver implementation: + virtual bool Accept(Message* message) MOJO_OVERRIDE; + virtual bool AcceptWithResponder(Message* message, + MessageReceiver* responder) MOJO_OVERRIDE; + private: + Router* router_; + }; + + bool HandleIncomingMessage(Message* message); + + Connector connector_; + SharedData weak_self_; + MessageReceiver* incoming_receiver_; + HandleIncomingMessageThunk thunk_; + ResponderMap responders_; + uint64_t next_request_id_; +}; + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_ROUTER_H_ diff --git a/mojo/public/cpp/bindings/lib/scratch_buffer.cc b/mojo/public/cpp/bindings/lib/scratch_buffer.cc new file mode 100644 index 0000000..cb894e3 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/scratch_buffer.cc @@ -0,0 +1,98 @@ +// Copyright 2014 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. + +#include "mojo/public/cpp/bindings/lib/scratch_buffer.h" + +#include +#include +#include + +#include + +#include "mojo/public/cpp/bindings/lib/bindings_serialization.h" + +// Scrub memory in debug builds to help catch use-after-free bugs. +#ifdef NDEBUG +#define DEBUG_SCRUB(address, size) (void) (address), (void) (size) +#else +#define DEBUG_SCRUB(address, size) memset(address, 0xCD, size) +#endif + +namespace mojo { +namespace internal { + +ScratchBuffer::ScratchBuffer() + : overflow_(NULL) { + fixed_.next = NULL; + fixed_.cursor = fixed_data_; + fixed_.end = fixed_data_ + kMinSegmentSize; +} + +ScratchBuffer::~ScratchBuffer() { + // Invoke destructors in reverse order to mirror allocation order. + std::deque::reverse_iterator it; + for (it = pending_dtors_.rbegin(); it != pending_dtors_.rend(); ++it) + it->func(it->address); + + while (overflow_) { + Segment* doomed = overflow_; + overflow_ = overflow_->next; + DEBUG_SCRUB(doomed, doomed->end - reinterpret_cast(doomed)); + free(doomed); + } + DEBUG_SCRUB(fixed_data_, sizeof(fixed_data_)); +} + +void* ScratchBuffer::Allocate(size_t delta, Destructor func) { + delta = internal::Align(delta); + + void* result = AllocateInSegment(&fixed_, delta); + if (!result) { + if (overflow_) + result = AllocateInSegment(overflow_, delta); + + if (!result) { + AddOverflowSegment(delta); + result = AllocateInSegment(overflow_, delta); + } + } + + if (func) { + PendingDestructor dtor; + dtor.func = func; + dtor.address = result; + pending_dtors_.push_back(dtor); + } + return result; +} + +void* ScratchBuffer::AllocateInSegment(Segment* segment, size_t delta) { + void* result; + if (static_cast(segment->end - segment->cursor) >= delta) { + result = segment->cursor; + memset(result, 0, delta); + segment->cursor += delta; + } else { + result = NULL; + } + return result; +} + +void ScratchBuffer::AddOverflowSegment(size_t delta) { + if (delta < kMinSegmentSize) + delta = kMinSegmentSize; + + // Ensure segment buffer is aligned. + size_t segment_size = internal::Align(sizeof(Segment)) + delta; + + Segment* segment = static_cast(malloc(segment_size)); + segment->next = overflow_; + segment->cursor = reinterpret_cast(segment + 1); + segment->end = segment->cursor + delta; + + overflow_ = segment; +} + +} // namespace internal +} // namespace mojo diff --git a/mojo/public/cpp/bindings/lib/scratch_buffer.h b/mojo/public/cpp/bindings/lib/scratch_buffer.h new file mode 100644 index 0000000..462c6fe --- /dev/null +++ b/mojo/public/cpp/bindings/lib/scratch_buffer.h @@ -0,0 +1,54 @@ +// Copyright 2014 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_PUBLIC_CPP_BINDINGS_LIB_SCRATCH_BUFFER_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SCRATCH_BUFFER_H_ + +#include + +#include "mojo/public/cpp/bindings/buffer.h" +#include "mojo/public/cpp/system/macros.h" + +namespace mojo { +namespace internal { + +// The following class is designed to be allocated on the stack. If necessary, +// it will failover to allocating objects on the heap. +class ScratchBuffer : public Buffer { + public: + ScratchBuffer(); + virtual ~ScratchBuffer(); + + virtual void* Allocate(size_t num_bytes, Destructor func = NULL) + MOJO_OVERRIDE; + + private: + enum { kMinSegmentSize = 512 }; + + struct Segment { + Segment* next; + char* cursor; + char* end; + }; + + void* AllocateInSegment(Segment* segment, size_t num_bytes); + void AddOverflowSegment(size_t delta); + + char fixed_data_[kMinSegmentSize]; + Segment fixed_; + Segment* overflow_; + + struct PendingDestructor { + Destructor func; + void* address; + }; + std::deque pending_dtors_; + + MOJO_DISALLOW_COPY_AND_ASSIGN(ScratchBuffer); +}; + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SCRATCH_BUFFER_H_ diff --git a/mojo/public/cpp/bindings/lib/shared_data.h b/mojo/public/cpp/bindings/lib/shared_data.h new file mode 100644 index 0000000..e396b0d --- /dev/null +++ b/mojo/public/cpp/bindings/lib/shared_data.h @@ -0,0 +1,81 @@ +// Copyright 2014 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_PUBLIC_CPP_BINDINGS_LIB_SHARED_DATA_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_DATA_H_ + +namespace mojo { +namespace internal { + +// Used to allocate an instance of T that can be shared via reference counting. +template +class SharedData { + public: + ~SharedData() { + holder_->Release(); + } + + SharedData() : holder_(new Holder()) { + } + + explicit SharedData(const T& value) : holder_(new Holder(value)) { + } + + SharedData(const SharedData& other) : holder_(other.holder_) { + holder_->Retain(); + } + + SharedData& operator=(const SharedData& other) { + if (other.holder_ == holder_) + return *this; + holder_->Release(); + holder_ = other.holder_; + holder_->Retain(); + } + + void reset() { + holder_->Release(); + holder_ = new Holder(); + } + + void reset(const T& value) { + holder_->Release(); + holder_ = new Holder(value); + } + + void set_value(const T& value) { + holder_->value = value; + } + T* mutable_value() { + return &holder_->value; + } + const T& value() const { + return holder_->value; + } + + private: + class Holder { + public: + Holder() : value(), ref_count_(1) { + } + Holder(const T& value) : value(value), ref_count_(1) { + } + + void Retain() { ++ref_count_; } + void Release() { if (--ref_count_ == 0) delete this; } + + T value; + + private: + int ref_count_; + MOJO_DISALLOW_COPY_AND_ASSIGN(Holder); + }; + + Holder* holder_; +}; + +} // namespace internal +} // namespace mojo + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_DATA_H_ diff --git a/mojo/public/cpp/bindings/lib/shared_ptr.h b/mojo/public/cpp/bindings/lib/shared_ptr.h new file mode 100644 index 0000000..6ae53a5 --- /dev/null +++ b/mojo/public/cpp/bindings/lib/shared_ptr.h @@ -0,0 +1,63 @@ +// Copyright 2014 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_PUBLIC_CPP_BINDINGS_LIB_SHARED_PTR_H_ +#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_PTR_H_ + +#include "mojo/public/cpp/bindings/lib/shared_data.h" + +namespace mojo { +namespace internal { + +// Used to manage a heap-allocated instance of P that can be shared via +// reference counting. When the last reference is dropped, the instance is +// deleted. +template +class SharedPtr { + public: + SharedPtr() {} + + explicit SharedPtr(P* ptr) { + impl_.mutable_value()->ptr = ptr; + } + + // Default copy-constructor and assignment operator are OK. + + P* get() { + return impl_.value().ptr; + } + const P* get() const { + return impl_.value().ptr; + } + + P* operator->() { return get(); } + const P* operator->() const { return get(); } + + private: + class Impl { + public: + ~Impl() { + if (ptr) + delete ptr; + } + + Impl() : ptr(NULL) { + } + + Impl(P* ptr) : ptr(ptr) { + } + + P* ptr; + + private: + MOJO_DISALLOW_COPY_AND_ASSIGN(Impl); + }; + + SharedData impl_; +}; + +} // namespace mojo +} // namespace internal + +#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_PTR_H_ diff --git a/mojo/public/cpp/bindings/lib/sync_dispatcher.cc b/mojo/public/cpp/bindings/lib/sync_dispatcher.cc new file mode 100644 index 0000000..acb537e --- /dev/null +++ b/mojo/public/cpp/bindings/lib/sync_dispatcher.cc @@ -0,0 +1,27 @@ +// Copyright 2014 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. + +#include "mojo/public/cpp/bindings/sync_dispatcher.h" + +#include + +#include "mojo/public/cpp/bindings/message.h" + +namespace mojo { + +bool WaitForMessageAndDispatch(MessagePipeHandle handle, + MessageReceiver* receiver) { + while (true) { + bool result; + MojoResult rv = ReadAndDispatchMessage(handle, receiver, &result); + if (rv == MOJO_RESULT_OK) + return result; + if (rv == MOJO_RESULT_SHOULD_WAIT) + rv = Wait(handle, MOJO_WAIT_FLAG_READABLE, MOJO_DEADLINE_INDEFINITE); + if (rv != MOJO_RESULT_OK) + return false; + } +} + +} // namespace mojo diff --git a/mojo/public/cpp/bindings/message.h b/mojo/public/cpp/bindings/message.h index 8df1ce0..58001c6 100644 --- a/mojo/public/cpp/bindings/message.h +++ b/mojo/public/cpp/bindings/message.h @@ -9,7 +9,7 @@ #include -#include "mojo/public/bindings/lib/message_internal.h" +#include "mojo/public/cpp/bindings/lib/message_internal.h" namespace mojo { diff --git a/mojo/public/cpp/bindings/passable.h b/mojo/public/cpp/bindings/passable.h index 3d5c2ca..0e109d6 100644 --- a/mojo/public/cpp/bindings/passable.h +++ b/mojo/public/cpp/bindings/passable.h @@ -5,7 +5,7 @@ #ifndef MOJO_PUBLIC_CPP_BINDINGS_PASSABLE_H_ #define MOJO_PUBLIC_CPP_BINDINGS_PASSABLE_H_ -#include "mojo/public/bindings/lib/bindings_internal.h" +#include "mojo/public/cpp/bindings/lib/bindings_internal.h" #include "mojo/public/cpp/system/core.h" namespace mojo { diff --git a/mojo/public/cpp/bindings/remote_ptr.h b/mojo/public/cpp/bindings/remote_ptr.h index 9bc629f..63ee719 100644 --- a/mojo/public/cpp/bindings/remote_ptr.h +++ b/mojo/public/cpp/bindings/remote_ptr.h @@ -7,8 +7,8 @@ #include -#include "mojo/public/bindings/lib/router.h" #include "mojo/public/cpp/bindings/interface.h" +#include "mojo/public/cpp/bindings/lib/router.h" #include "mojo/public/cpp/system/macros.h" namespace mojo { -- cgit v1.1