OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_ID_H_ | 5 #ifndef MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_ID_H_ |
6 #define MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_ID_H_ | 6 #define MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_ID_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include <ostream> | 11 #include <ostream> |
12 | 12 |
13 #include "base/containers/hash_tables.h" | 13 #include "base/containers/hash_tables.h" |
| 14 #include "base/gtest_prod_util.h" |
14 #include "base/macros.h" | 15 #include "base/macros.h" |
15 #include "build/build_config.h" | 16 #include "build/build_config.h" |
| 17 #include "mojo/edk/system/system_impl_export.h" |
16 | 18 |
17 namespace mojo { | 19 namespace mojo { |
18 namespace system { | 20 namespace system { |
19 | 21 |
20 // ChannelEndpointId ----------------------------------------------------------- | 22 // ChannelEndpointId ----------------------------------------------------------- |
21 | 23 |
22 class LocalChannelEndpointIdGenerator; | 24 class LocalChannelEndpointIdGenerator; |
| 25 FORWARD_DECLARE_TEST(LocalChannelEndpointIdGeneratorTest, WrapAround); |
23 | 26 |
24 // Represents an ID for an endpoint (i.e., one side of a message pipe) on a | 27 // Represents an ID for an endpoint (i.e., one side of a message pipe) on a |
25 // |Channel|. This class must be POD. | 28 // |Channel|. This class must be POD. |
26 class ChannelEndpointId { | 29 class MOJO_SYSTEM_IMPL_EXPORT ChannelEndpointId { |
27 public: | 30 public: |
28 ChannelEndpointId() : value_(0) {} | 31 ChannelEndpointId() : value_(0) {} |
29 ChannelEndpointId(const ChannelEndpointId& other) : value_(other.value_) {} | 32 ChannelEndpointId(const ChannelEndpointId& other) : value_(other.value_) {} |
30 | 33 |
31 // Returns the local ID to use for the first message pipe endpoint on a | 34 // Returns the local ID to use for the first message pipe endpoint on a |
32 // channel. | 35 // channel. |
33 static ChannelEndpointId GetBootstrap() { | 36 static ChannelEndpointId GetBootstrap() { |
34 ChannelEndpointId rv; | 37 ChannelEndpointId rv; |
35 rv.value_ = 1; | 38 rv.value_ = 1; |
36 return rv; | 39 return rv; |
37 } | 40 } |
38 | 41 |
39 bool operator==(const ChannelEndpointId& other) const { | 42 bool operator==(const ChannelEndpointId& other) const { |
40 return value_ == other.value_; | 43 return value_ == other.value_; |
41 } | 44 } |
42 bool operator!=(const ChannelEndpointId& other) const { | 45 bool operator!=(const ChannelEndpointId& other) const { |
43 return !operator==(other); | 46 return !operator==(other); |
44 } | 47 } |
45 // So that we can be used in |std::map|, etc. | 48 // So that we can be used in |std::map|, etc. |
46 bool operator<(const ChannelEndpointId& other) const { | 49 bool operator<(const ChannelEndpointId& other) const { |
47 return value_ < other.value_; | 50 return value_ < other.value_; |
48 } | 51 } |
49 | 52 |
50 bool is_valid() const { return !!value_; } | 53 bool is_valid() const { return !!value_; } |
51 uint32_t value() const { return value_; } | 54 uint32_t value() const { return value_; } |
52 | 55 |
53 private: | 56 private: |
54 friend class LocalChannelEndpointIdGenerator; | 57 friend class LocalChannelEndpointIdGenerator; |
| 58 FRIEND_TEST_ALL_PREFIXES(LocalChannelEndpointIdGeneratorTest, WrapAround); |
55 | 59 |
56 uint32_t value_; | 60 uint32_t value_; |
57 | 61 |
58 // Copying and assignment allowed. | 62 // Copying and assignment allowed. |
59 }; | 63 }; |
60 // This wrapper should add no overhead. | 64 // This wrapper should add no overhead. |
61 // TODO(vtl): Rewrite |sizeof(uint32_t)| as |sizeof(ChannelEndpointId::value)| | 65 // TODO(vtl): Rewrite |sizeof(uint32_t)| as |sizeof(ChannelEndpointId::value)| |
62 // once we have sufficient C++11 support. | 66 // once we have sufficient C++11 support. |
63 static_assert(sizeof(ChannelEndpointId) == sizeof(uint32_t), | 67 static_assert(sizeof(ChannelEndpointId) == sizeof(uint32_t), |
64 "ChannelEndpointId has incorrect size"); | 68 "ChannelEndpointId has incorrect size"); |
65 | 69 |
66 // So logging macros and |DCHECK_EQ()|, etc. work. | 70 // So logging macros and |DCHECK_EQ()|, etc. work. |
67 inline std::ostream& operator<<(std::ostream& out, | 71 inline std::ostream& operator<<(std::ostream& out, |
68 const ChannelEndpointId& channel_endpoint_id) { | 72 const ChannelEndpointId& channel_endpoint_id) { |
69 return out << channel_endpoint_id.value(); | 73 return out << channel_endpoint_id.value(); |
70 } | 74 } |
71 | 75 |
72 // LocalChannelEndpointIdGenerator --------------------------------------------- | 76 // LocalChannelEndpointIdGenerator --------------------------------------------- |
73 | 77 |
74 // A simple generator for "new" local |ChannelEndpointId|s. It does not track | 78 // A simple generator for "new" local |ChannelEndpointId|s. It does not track |
75 // used/existing IDs; that must be done separately. (This class is not | 79 // used/existing IDs; that must be done separately. (This class is not |
76 // thread-safe.) | 80 // thread-safe.) |
77 class LocalChannelEndpointIdGenerator { | 81 class MOJO_SYSTEM_IMPL_EXPORT LocalChannelEndpointIdGenerator { |
78 public: | 82 public: |
79 LocalChannelEndpointIdGenerator() | 83 LocalChannelEndpointIdGenerator() |
80 : next_channel_endpoint_id_(ChannelEndpointId::GetBootstrap()) {} | 84 : next_channel_endpoint_id_(ChannelEndpointId::GetBootstrap()) {} |
81 | 85 |
82 ChannelEndpointId GetNext() { | 86 ChannelEndpointId GetNext(); |
83 ChannelEndpointId rv = next_channel_endpoint_id_; | |
84 next_channel_endpoint_id_.value_++; | |
85 // Skip over the invalid value, in case we wrap. | |
86 if (!next_channel_endpoint_id_.is_valid()) | |
87 next_channel_endpoint_id_.value_++; | |
88 return rv; | |
89 } | |
90 | 87 |
91 private: | 88 private: |
| 89 FRIEND_TEST_ALL_PREFIXES(LocalChannelEndpointIdGeneratorTest, WrapAround); |
| 90 |
92 ChannelEndpointId next_channel_endpoint_id_; | 91 ChannelEndpointId next_channel_endpoint_id_; |
93 | 92 |
94 DISALLOW_COPY_AND_ASSIGN(LocalChannelEndpointIdGenerator); | 93 DISALLOW_COPY_AND_ASSIGN(LocalChannelEndpointIdGenerator); |
95 }; | 94 }; |
96 | 95 |
97 } // namespace system | 96 } // namespace system |
98 } // namespace mojo | 97 } // namespace mojo |
99 | 98 |
100 // Define "hash" functions for |ChannelEndpointId|s, so they can be used in hash | 99 // Define "hash" functions for |ChannelEndpointId|s, so they can be used in hash |
101 // tables. | 100 // tables. |
(...skipping 13 matching lines...) Expand all Loading... |
115 #elif defined(COMPILER_MSVC) | 114 #elif defined(COMPILER_MSVC) |
116 | 115 |
117 inline size_t hash_value(mojo::system::ChannelEndpointId channel_endpoint_id) { | 116 inline size_t hash_value(mojo::system::ChannelEndpointId channel_endpoint_id) { |
118 return static_cast<size_t>(channel_endpoint_id.value()); | 117 return static_cast<size_t>(channel_endpoint_id.value()); |
119 } | 118 } |
120 #endif | 119 #endif |
121 | 120 |
122 } // namespace BASE_HASH_NAMESPACE | 121 } // namespace BASE_HASH_NAMESPACE |
123 | 122 |
124 #endif // MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_ID_H_ | 123 #endif // MOJO_EDK_SYSTEM_CHANNEL_ENDPOINT_ID_H_ |
OLD | NEW |