| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/system/message_in_transit.h" | 5 #include "mojo/system/message_in_transit.h" |
| 6 | 6 |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include <new> | 10 #include <new> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/compiler_specific.h" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "build/build_config.h" | |
| 15 #include "mojo/system/limits.h" | 15 #include "mojo/system/limits.h" |
| 16 | 16 |
| 17 namespace mojo { | 17 namespace mojo { |
| 18 namespace system { | 18 namespace system { |
| 19 | 19 |
| 20 // Avoid dangerous situations, but making sure that the size of the "header" + | 20 // Avoid dangerous situations, but making sure that the size of the "header" + |
| 21 // the size of the data fits into a 31-bit number. | 21 // the size of the data fits into a 31-bit number. |
| 22 COMPILE_ASSERT(static_cast<uint64_t>(sizeof(MessageInTransit)) + | 22 COMPILE_ASSERT(static_cast<uint64_t>(sizeof(MessageInTransit)) + |
| 23 kMaxMessageNumBytes <= 0x7fffffff, | 23 kMaxMessageNumBytes <= 0x7fffffff, |
| 24 kMaxMessageNumBytes_too_big); | 24 kMaxMessageNumBytes_too_big); |
| 25 | 25 |
| 26 COMPILE_ASSERT(sizeof(MessageInTransit) % | 26 COMPILE_ASSERT(sizeof(MessageInTransit) % |
| 27 MessageInTransit::kMessageAlignment == 0, | 27 MessageInTransit::kMessageAlignment == 0, |
| 28 sizeof_MessageInTransit_not_a_multiple_of_alignment); | 28 sizeof_MessageInTransit_not_a_multiple_of_alignment); |
| 29 | 29 |
| 30 // C++ requires that storage be declared (in a single compilation unit), but | 30 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
| 31 // MSVS isn't standards-conformant and doesn't handle this correctly. | 31 MessageInTransit::kTypeMessagePipeEndpoint; |
| 32 #if !defined(COMPILER_MSVC) | 32 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
| 33 const size_t MessageInTransit::kMessageAlignment; | 33 MessageInTransit::kTypeMessagePipe; |
| 34 #endif | 34 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Type |
| 35 MessageInTransit::TYPE_CHANNEL; |
| 36 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype |
| 37 MessageInTransit::kSubtypeMessagePipeEndpointData; |
| 38 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::Subtype |
| 39 MessageInTransit::kSubtypeMessagePipePeerClosed; |
| 40 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId |
| 41 MessageInTransit::kInvalidEndpointId; |
| 42 STATIC_CONST_MEMBER_DEFINITION const size_t MessageInTransit::kMessageAlignment; |
| 35 | 43 |
| 36 // static | 44 // static |
| 37 MessageInTransit* MessageInTransit::Create(const void* bytes, | 45 MessageInTransit* MessageInTransit::Create(Type type, |
| 46 Subtype subtype, |
| 47 const void* bytes, |
| 38 uint32_t num_bytes) { | 48 uint32_t num_bytes) { |
| 39 const size_t size_with_header = sizeof(MessageInTransit) + num_bytes; | 49 const size_t size_with_header = sizeof(MessageInTransit) + num_bytes; |
| 40 const size_t size_with_header_and_padding = | 50 const size_t size_with_header_and_padding = |
| 41 RoundUpMessageAlignment(size_with_header); | 51 RoundUpMessageAlignment(size_with_header); |
| 42 | 52 |
| 43 char* buffer = static_cast<char*>(malloc(size_with_header_and_padding)); | 53 char* buffer = static_cast<char*>(malloc(size_with_header_and_padding)); |
| 44 DCHECK_EQ(reinterpret_cast<size_t>(buffer) % | 54 DCHECK_EQ(reinterpret_cast<size_t>(buffer) % |
| 45 MessageInTransit::kMessageAlignment, 0u); | 55 MessageInTransit::kMessageAlignment, 0u); |
| 46 | 56 |
| 47 // The buffer consists of the header (a |MessageInTransit|, constructed using | 57 // The buffer consists of the header (a |MessageInTransit|, constructed using |
| 48 // a placement new), followed by the data, followed by padding (of zeros). | 58 // a placement new), followed by the data, followed by padding (of zeros). |
| 49 MessageInTransit* rv = new (buffer) MessageInTransit(num_bytes); | 59 MessageInTransit* rv = |
| 60 new (buffer) MessageInTransit(num_bytes, type, subtype); |
| 50 memcpy(buffer + sizeof(MessageInTransit), bytes, num_bytes); | 61 memcpy(buffer + sizeof(MessageInTransit), bytes, num_bytes); |
| 51 memset(buffer + size_with_header, 0, | 62 memset(buffer + size_with_header, 0, |
| 52 size_with_header_and_padding - size_with_header); | 63 size_with_header_and_padding - size_with_header); |
| 53 return rv; | 64 return rv; |
| 54 } | 65 } |
| 55 | 66 |
| 56 } // namespace system | 67 } // namespace system |
| 57 } // namespace mojo | 68 } // namespace mojo |
| OLD | NEW |