Skip to content

Commit 1833aa6

Browse files
authored
Merge pull request #452 from evoskuil/master
Implement conditional compile for block allocator.
2 parents 516682b + 4353287 commit 1833aa6

File tree

12 files changed

+69
-8
lines changed

12 files changed

+69
-8
lines changed

include/bitcoin/network/async/desubscriber.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,12 @@ class desubscriber final
6565
/// Invoke each handler in order, with default arguments, then drop all.
6666
void stop_default(const code& ec) NOEXCEPT;
6767

68-
/// The map size.
68+
/// Subscriber map size.
6969
size_t size() const NOEXCEPT;
7070

71+
/// True if no subscribers.
72+
bool empty() const NOEXCEPT;
73+
7174
private:
7275
// This is thread safe.
7376
asio::strand& strand_;

include/bitcoin/network/async/subscriber.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,12 @@ class subscriber final
5353
/// Invoke each handler in order, with default arguments, then drop all.
5454
void stop_default(const code& ec) NOEXCEPT;
5555

56-
/// The queue size.
56+
/// Subscriber queue size.
5757
size_t size() const NOEXCEPT;
5858

59+
/// True if no subscribers.
60+
bool empty() const NOEXCEPT;
61+
5962
private:
6063
// This is thread safe.
6164
asio::strand& strand_;

include/bitcoin/network/async/unsubscriber.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,12 @@ class unsubscriber final
5757
/// Invoke each handler in order, with default arguments, then drop all.
5858
void stop_default(const code& ec) NOEXCEPT;
5959

60-
/// The list size.
60+
/// Subscriber list size.
6161
size_t size() const NOEXCEPT;
6262

63+
/// True if no subscribers.
64+
bool empty() const NOEXCEPT;
65+
6366
private:
6467
// This is thread safe.
6568
asio::strand& strand_;

include/bitcoin/network/impl/async/desubscriber.ipp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ size() const NOEXCEPT
143143
return map_.size();
144144
}
145145

146+
template <typename Key, typename... Args>
147+
bool desubscriber<Key, Args...>::
148+
empty() const NOEXCEPT
149+
{
150+
BC_ASSERT_MSG(strand_.running_in_this_thread(), "strand");
151+
return map_.empty();
152+
}
153+
146154
} // namespace network
147155
} // namespace libbitcoin
148156

include/bitcoin/network/impl/async/subscriber.ipp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ size() const NOEXCEPT
109109
return queue_.size();
110110
}
111111

112+
template <typename... Args>
113+
bool subscriber<Args...>::
114+
empty() const NOEXCEPT
115+
{
116+
BC_ASSERT_MSG(strand_.running_in_this_thread(), "strand");
117+
return queue_.empty();
118+
}
119+
112120
} // namespace network
113121
} // namespace libbitcoin
114122

include/bitcoin/network/impl/async/unsubscriber.ipp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,14 @@ size() const NOEXCEPT
118118
return queue_.size();
119119
}
120120

121+
template <typename... Args>
122+
bool unsubscriber<Args...>::
123+
empty() const NOEXCEPT
124+
{
125+
BC_ASSERT_MSG(strand_.running_in_this_thread(), "strand");
126+
return queue_.empty();
127+
}
128+
121129
} // namespace network
122130
} // namespace libbitcoin
123131

include/bitcoin/network/net/distributor.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ class BCT_API distributor
113113
const system::data_chunk& data) NOEXCEPT
114114
{
115115
// Avoid deserialization if there are no subscribers for the type.
116-
if (!is_zero(subscriber.size()))
116+
if (!subscriber.empty())
117117
{
118118
// Subscribers are notified only with stop code or error::success.
119119
const auto ptr = messages::deserialize<Message>(data, version);

src/messages/block.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ typename block::cptr block::deserialize(arena& arena, uint32_t version,
5858

5959
// Set starting address of block allocation (nullptr if not detachable).
6060
const auto memory = pointer_cast<uint8_t>(arena.start(data.size()));
61+
if (is_null(memory))
62+
return nullptr;
6163

6264
istream source{ data };
6365
byte_reader reader{ source, &arena };

src/net/distributor.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,15 @@
2323
#include <bitcoin/network/memory.hpp>
2424
#include <bitcoin/network/messages/messages.hpp>
2525

26+
// Set false to use default block allocation.
27+
constexpr bool use_block_allocator = true;
28+
2629
namespace libbitcoin {
2730
namespace network {
2831

32+
// Compiler can't see is_null(arena).
33+
BC_PUSH_WARNING(NO_UNGUARDED_POINTERS)
34+
2935
using namespace system;
3036

3137
#define SUBSCRIBER(name) name##_subscriber_
@@ -159,22 +165,31 @@ code distributor::do_notify<messages::block>(
159165
distributor::block_subscriber& subscriber, uint32_t version,
160166
const system::data_chunk& data) NOEXCEPT
161167
{
162-
if (!is_zero(subscriber.size()))
168+
if (subscriber.empty())
169+
return error::success;
170+
171+
if constexpr (use_block_allocator)
163172
{
164173
const auto arena = memory_.get_arena();
165-
if (arena == nullptr)
174+
if (is_null(arena))
166175
return error::operation_failed;
167176

168177
const auto ptr = messages::block::deserialize(*arena, version, data);
169178
if (!ptr)
170179
return error::invalid_message;
171180

172181
subscriber.notify(error::success, ptr);
182+
return error::success;
183+
}
184+
else
185+
{
186+
return do_notify<messages::block>(subscriber, version, data);
173187
}
174188

175-
return error::success;
176189
}
177190

191+
BC_POP_WARNING()
192+
178193
#undef SUBSCRIBER
179194
#undef MAKE_SUBSCRIBER
180195
#undef CASE_NOTIFY

test/async/desubscriber.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,19 @@ BOOST_AUTO_TEST_CASE(desubscriber__subscribe__stopped__subscriber_stopped)
3535
std::pair<code, size_t> retry_result;
3636
boost::asio::post(strand, [&]() NOEXCEPT
3737
{
38+
result &= instance.empty();
3839
result &= is_zero(instance.size());
3940
result &= !instance.subscribe([&](code value, size_t size) NOEXCEPT
4041
{
4142
stop_result = { value, size };
4243
return true;
4344
}, 0);
4445

46+
result &= !instance.empty();
4547
result &= is_one(instance.size());
4648
instance.stop(ec, expected);
4749

50+
result &= instance.empty();
4851
result &= is_zero(instance.size());
4952
result &= (instance.subscribe([&](code value, size_t size) NOEXCEPT
5053
{

test/async/subscriber.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,18 @@ BOOST_AUTO_TEST_CASE(subscriber__subscribe__stopped__subscriber_stopped)
3535
std::pair<code, size_t> retry_result;
3636
boost::asio::post(strand, [&]() NOEXCEPT
3737
{
38+
result &= instance.empty();
3839
result &= is_zero(instance.size());
3940
result &= !instance.subscribe([&](code value, size_t size) NOEXCEPT
4041
{
4142
stop_result = { value, size };
4243
});
4344

45+
result &= !instance.empty();
4446
result &= is_one(instance.size());
4547
instance.stop(ec, expected);
4648

49+
result &= instance.empty();
4750
result &= is_zero(instance.size());
4851
result &= (instance.subscribe([&](code value, size_t size) NOEXCEPT
4952
{

test/async/unsubscriber.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ BOOST_AUTO_TEST_CASE(unsubscriber__subscribe__stopped__subscriber_stopped)
4141
stop_result = { value, size };
4242
return true;
4343
});
44-
44+
45+
result &= !instance.empty();
4546
result &= is_one(instance.size());
4647
instance.stop(ec, expected);
4748

49+
result &= instance.empty();
4850
result &= is_zero(instance.size());
4951
result &= (instance.subscribe([&](code value, size_t size) NOEXCEPT
5052
{
@@ -116,6 +118,7 @@ BOOST_AUTO_TEST_CASE(unsubscriber__subscribe__removed__expected)
116118
std::pair<code, size_t> second_result;
117119
boost::asio::post(strand, [&]() NOEXCEPT
118120
{
121+
result &= instance.empty();
119122
result &= is_zero(instance.size());
120123
result &= !instance.subscribe([&](code value, size_t size) NOEXCEPT
121124
{
@@ -131,8 +134,10 @@ BOOST_AUTO_TEST_CASE(unsubscriber__subscribe__removed__expected)
131134
return true;
132135
});
133136

137+
result &= !instance.empty();
134138
result &= is_one(instance.size());
135139
instance.stop(ec2, expected2);
140+
result &= instance.empty();
136141
result &= is_zero(instance.size());
137142
});
138143

0 commit comments

Comments
 (0)