Skip to content

Commit

Permalink
Merge pull request libbitcoin#377 from evoskuil/master
Browse files Browse the repository at this point in the history
Add BIND_THIS, use __VA_ARGS__ to simplify variadic macros.
  • Loading branch information
evoskuil authored Feb 29, 2024
2 parents 89dd990 + 6d07a32 commit 147da53
Show file tree
Hide file tree
Showing 18 changed files with 107 additions and 152 deletions.
25 changes: 10 additions & 15 deletions include/bitcoin/network/define.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,16 @@
namespace libbitcoin {
namespace network {

// The 'bind' method and 'CLASS' names are conventional.
#define BIND1(method, p1) \
bind<CLASS>(&CLASS::method, p1)
#define BIND2(method, p1, p2) \
bind<CLASS>(&CLASS::method, p1, p2)
#define BIND3(method, p1, p2, p3) \
bind<CLASS>(&CLASS::method, p1, p2, p3)
#define BIND4(method, p1, p2, p3, p4) \
bind<CLASS>(&CLASS::method, p1, p2, p3, p4)
#define BIND5(method, p1, p2, p3, p4, p5) \
bind<CLASS>(&CLASS::method, p1, p2, p3, p4, p5)
#define BIND6(method, p1, p2, p3, p4, p5, p6) \
bind<CLASS>(&CLASS::method, p1, p2, p3, p4, p5, p6)
#define BIND7(method, p1, p2, p3, p4, p5, p6, p7) \
bind<CLASS>(&CLASS::method, p1, p2, p3, p4, p5, p6, p7)
#define BIND_SHARED(method, args) \
std::bind(std::forward<Method>(method), shared_from_base<Derived>(), \
std::forward<Args>(args)...)
#define BIND_THIS(method, args) \
std::bind(std::forward<Method>(method), static_cast<Derived*>(this), \
std::forward<Args>(args)...)
#define BIND(method, ...) \
bind<CLASS>(&CLASS::method, __VA_ARGS__)
#define POST(method, ...) \
post<CLASS>(&CLASS::method, __VA_ARGS__)

} // namespace network
} // namespace libbitcoin
Expand Down
69 changes: 17 additions & 52 deletions include/bitcoin/network/protocols/protocol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,6 @@
namespace libbitcoin {
namespace network {

#define BOUND_PROTOCOL(method, args) \
std::bind(std::forward<Method>(method), shared_from_base<Protocol>(), \
std::forward<Args>(args)...)

/// This class is thread safe, except for:
/// * start/started must be called on strand.
/// * setters should only be invoked during handshake.
Expand Down Expand Up @@ -76,47 +72,46 @@ class BCT_API protocol
/// -----------------------------------------------------------------------

/// Bind a method in base or derived class (use BIND#).
template <class Protocol, typename Method, typename... Args>
template <class Derived, typename Method, typename... Args>
auto bind(Method&& method, Args&&... args) NOEXCEPT
{
return BOUND_PROTOCOL(method, args);
return BIND_SHARED(method, args);
}

/// Post a method in base or derived class to channel strand (use POST#).
template <class Protocol, typename Method, typename... Args>
template <class Derived, typename Method, typename... Args>
auto post(Method&& method, Args&&... args) NOEXCEPT
{
return boost::asio::post(channel_->strand(),
BOUND_PROTOCOL(method, args));
BIND_SHARED(method, args));
}

/// Send a message instance to peer (use SEND#).
template <class Protocol, class Message, typename Method, typename... Args>
template <class Derived, class Message, typename Method, typename... Args>
void send(const Message& message, Method&& method, Args&&... args) NOEXCEPT
{
BC_ASSERT_MSG(stranded(), "strand");
channel_->send<Message>(message, BOUND_PROTOCOL(method, args));
channel_->send<Message>(message, BIND_SHARED(method, args));
}

/// Subscribe to channel messages by type (use SUBSCRIBE_CHANNEL#).
/// Method is invoked with error::subscriber_stopped if already stopped.
template <class Protocol, class Message, typename Method, typename... Args>
template <class Derived, class Message, typename Method, typename... Args>
void subscribe_channel(Method&& method, Args&&... args) NOEXCEPT
{
BC_ASSERT_MSG(stranded(), "strand");
channel_->subscribe<Message>(BOUND_PROTOCOL(method, args));
channel_->subscribe<Message>(BIND_SHARED(method, args));
}

/// Subscribe to messages broadcasts by type (use SUBSCRIBE_BROADCAST#).
/// Method is invoked with error::subscriber_stopped if already stopped.
template <class Protocol, class Message, typename Method, typename... Args>
template <class Derived, class Message, typename Method, typename... Args>
void subscribe_broadcast(Method&& method, Args&&... args) NOEXCEPT
{
BC_ASSERT_MSG(stranded(), "strand");

// handler is a bool function, causes problem with std::bind.
const auto bouncer =
[self = shared_from_this(), handler = BOUND_PROTOCOL(method, args)]
const auto bouncer = [self = shared_from_this(),
handler = BIND_SHARED(method, args)]
(const auto& ec, const typename Message::cptr& message, auto id)
{
return self->handle_broadcast<Message>(ec, message, id, handler);
Expand Down Expand Up @@ -229,42 +224,12 @@ class BCT_API protocol
bool started_{};
};

#undef BOUND_PROTOCOL

// See define.hpp for BIND# macros.

#define POST1(method, p1) \
post<CLASS>(&CLASS::method, p1)
#define POST2(method, p1, p2) \
post<CLASS>(&CLASS::method, p1, p2)
#define POST3(method, p1, p2, p3) \
post<CLASS>(&CLASS::method, p1, p2, p3)

#define SEND1(message, method, p1) \
send<CLASS>(message, &CLASS::method, p1)
#define SEND2(message, method, p1, p2) \
send<CLASS>(message, &CLASS::method, p1, p2)
#define SEND3(message, method, p1, p2, p3) \
send<CLASS>(message, &CLASS::method, p1, p2, p3)

#define SUBSCRIBE_CHANNEL1(message, method, p1) \
subscribe_channel<CLASS, message>(&CLASS::method, p1)
#define SUBSCRIBE_CHANNEL2(message, method, p1, p2) \
subscribe_channel<CLASS, message>(&CLASS::method, p1, p2)
#define SUBSCRIBE_CHANNEL3(message, method, p1, p2, p3) \
subscribe_channel<CLASS, message>(&CLASS::method, p1, p2, p3)
#define SUBSCRIBE_CHANNEL4(message, method, p1, p2, p3, p4) \
subscribe_channel<CLASS, message>(&CLASS::method, p1, p2, p3, p4)

////#define SUBSCRIBE_BROADCAST1(message, method, p1) \
//// subscribe_broadcast<CLASS, message>(&CLASS::method, p1)
////#define SUBSCRIBE_BROADCAST2(message, method, p1, p2) \
//// subscribe_broadcast<CLASS, message>(&CLASS::method, p1, p2)
#define SUBSCRIBE_BROADCAST3(message, method, p1, p2, p3) \
subscribe_broadcast<CLASS, message>(&CLASS::method, p1, p2, p3)
#define SUBSCRIBE_BROADCAST4(message, method, p1, p2, p3, p4) \
subscribe_broadcast<CLASS, message>(&CLASS::method, p1, p2, p3, p4)

#define SEND(message, method, ...) \
send<CLASS>(message, &CLASS::method, __VA_ARGS__)
#define SUBSCRIBE_CHANNEL(message, method, ...) \
subscribe_channel<CLASS, message>(&CLASS::method, __VA_ARGS__)
#define SUBSCRIBE_BROADCAST(message, method, ...) \
subscribe_broadcast<CLASS, message>(&CLASS::method, __VA_ARGS__)
#define BROADCAST(message, ptr) broadcast<message>(ptr)

} // namespace network
Expand Down
17 changes: 6 additions & 11 deletions include/bitcoin/network/sessions/session.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,10 @@ class BCT_API session

protected:
/// Bind a method in the base or derived class (use BIND#).
template <class Session, typename Method, typename... Args>
template <class Derived, typename Method, typename... Args>
auto bind(Method&& method, Args&&... args) NOEXCEPT
{
return std::bind(std::forward<Method>(method),
shared_from_base<Session>(), std::forward<Args>(args)...);
return BIND_SHARED(method, args);
}

private:
Expand Down Expand Up @@ -87,29 +86,25 @@ class BCT_API session
template <class Message, typename Handler = broadcaster::handler<Message>>
void subscribe(Handler&& handler, channel_id id) NOEXCEPT
{
// Handler is a bool function, causes problem with std::bind.
const auto bouncer =
[self = shared_from_this(), handler = std::move(handler), id]()
const auto bouncer = [self = shared_from_this(),
handler = std::move(handler), id]()
{
self->do_subscribe<Handler>(handler, id);
};

// Subscribe on network strand (protects broadcaster).
boost::asio::post(strand(), bouncer);
}

template <class Message>
void broadcast(const typename Message::cptr& message,
channel_id sender) NOEXCEPT
{
boost::asio::post(strand(),
BIND2(do_broadcast<Message>, message, sender));
BIND(do_broadcast<Message>, message, sender));
}

virtual void unsubscribe(channel_id subscriber) NOEXCEPT
{
boost::asio::post(strand(),
BIND1(do_unsubscribe, subscriber));
BIND(do_unsubscribe, subscriber));
}

/// Start/stop.
Expand Down
4 changes: 2 additions & 2 deletions src/protocols/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ size_t protocol::address_count() const NOEXCEPT
void protocol::fetch(address_handler&& handler) NOEXCEPT
{
session_.fetch(
BIND3(handle_fetch, _1, _2, std::move(handler)));
BIND(handle_fetch, _1, _2, std::move(handler)));
}

void protocol::handle_fetch(const code& ec, const address_cptr& message,
Expand All @@ -201,7 +201,7 @@ void protocol::save(const address_cptr& message,
count_handler&& handler) NOEXCEPT
{
session_.save(message,
BIND3(handle_save, _1, _2, std::move(handler)));
BIND(handle_save, _1, _2, std::move(handler)));
}

void protocol::handle_save(const code& ec, size_t accepted,
Expand Down
6 changes: 3 additions & 3 deletions src/protocols/protocol_address_in_31402.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ void protocol_address_in_31402::start() NOEXCEPT
return;

// Always allow a singleton unrequested address (advertisement).
SUBSCRIBE_CHANNEL2(address, handle_receive_address, _1, _2);
SUBSCRIBE_CHANNEL(address, handle_receive_address, _1, _2);

// Do not request addresses from inbound channels.
if (outbound_)
{
SEND1(get_address{}, handle_send, _1);
SEND(get_address{}, handle_send, _1);
}

protocol::start();
Expand Down Expand Up @@ -147,7 +147,7 @@ bool protocol_address_in_31402::handle_receive_address(const code& ec,

// This allows previously-rejected addresses.
save(filtered,
BIND4(handle_save_address, _1, _2, end_size, start_size));
BIND(handle_save_address, _1, _2, end_size, start_size));

return true;
}
Expand Down
12 changes: 6 additions & 6 deletions src/protocols/protocol_address_out_31402.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ void protocol_address_out_31402::start() NOEXCEPT
// Advertise self if configured for inbound and with self address(es).
if (settings().advertise_enabled())
{
SEND1(selfs(), handle_send, _1);
SEND(selfs(), handle_send, _1);
}

SUBSCRIBE_CHANNEL2(get_address, handle_receive_get_address, _1, _2);
SUBSCRIBE_CHANNEL(get_address, handle_receive_get_address, _1, _2);
protocol::start();
}

Expand All @@ -84,11 +84,11 @@ bool protocol_address_out_31402::handle_receive_get_address(const code& ec,
return true;
}

fetch(BIND2(handle_fetch_address, _1, _2));
fetch(BIND(handle_fetch_address, _1, _2));
sent_ = true;

LOGP("Relay start [" << authority() << "].");
SUBSCRIBE_BROADCAST3(address, handle_broadcast_address, _1, _2, _3);
SUBSCRIBE_BROADCAST(address, handle_broadcast_address, _1, _2, _3);
return true;
}

Expand All @@ -107,7 +107,7 @@ void protocol_address_out_31402::handle_fetch_address(const code& ec,
LOGP("Sending (" << message->addresses.size() << ") addresses to "
"[" << authority() << "]");

SEND1(*message, handle_send, _1);
SEND(*message, handle_send, _1);
}

// ----------------------------------------------------------------------------
Expand All @@ -132,7 +132,7 @@ bool protocol_address_out_31402::handle_broadcast_address(const code& ec,
LOGP("Relay (" << message->addresses.size() << ") addresses to ["
<< authority() << "].");

SEND1(*message, handle_send, _1);
SEND(*message, handle_send, _1);
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion src/protocols/protocol_alert_31402.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void protocol_alert_31402::start() NOEXCEPT
if (started())
return;

SUBSCRIBE_CHANNEL2(alert, handle_receive_alert, _1, _2);
SUBSCRIBE_CHANNEL(alert, handle_receive_alert, _1, _2);

protocol::start();
}
Expand Down
6 changes: 3 additions & 3 deletions src/protocols/protocol_ping_31402.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ void protocol_ping_31402::start() NOEXCEPT
if (started())
return;

SUBSCRIBE_CHANNEL2(ping, handle_receive_ping, _1, _2);
SUBSCRIBE_CHANNEL(ping, handle_receive_ping, _1, _2);
send_ping();

protocol::start();
Expand All @@ -71,7 +71,7 @@ void protocol_ping_31402::stopping(const code&) NOEXCEPT

void protocol_ping_31402::send_ping() NOEXCEPT
{
SEND1(ping{}, handle_send_ping, _1);
SEND(ping{}, handle_send_ping, _1);
}

// Also invoked by protocol_ping_31402.
Expand All @@ -82,7 +82,7 @@ void protocol_ping_31402::handle_send_ping(const code& ec) NOEXCEPT
if (stopped(ec))
return;

timer_->start(BIND1(handle_timer, _1));
timer_->start(BIND(handle_timer, _1));
protocol::handle_send(ec);
}

Expand Down
10 changes: 5 additions & 5 deletions src/protocols/protocol_ping_60001.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ void protocol_ping_60001::start() NOEXCEPT
if (started())
return;

SUBSCRIBE_CHANNEL2(pong, handle_receive_pong, _1, _2);
////SUBSCRIBE_CHANNEL2(ping, handle_receive_ping, _1, _2);
SUBSCRIBE_CHANNEL(pong, handle_receive_pong, _1, _2);
////SUBSCRIBE_CHANNEL(ping, handle_receive_ping, _1, _2);
////send_ping();

protocol_ping_31402::start();
Expand All @@ -79,7 +79,7 @@ void protocol_ping_60001::send_ping() NOEXCEPT

// The ping/pong nonce is arbitrary and distinct from the channel nonce.
nonce_ = pseudo_random::next<uint64_t>(add1(minimum_nonce), bc::max_int64);
SEND1(ping{ nonce_ }, handle_send, _1);
SEND(ping{ nonce_ }, handle_send, _1);
}

////void protocol_ping_31402::handle_send_ping(const code& ec) NOEXCEPT
Expand All @@ -89,7 +89,7 @@ void protocol_ping_60001::send_ping() NOEXCEPT
//// if (stopped(ec))
//// return;
////
//// timer_->start(BIND1(handle_timer, _1));
//// timer_->start(BIND(handle_timer, _1));
//// protocol::handle_send(ec);
////}

Expand Down Expand Up @@ -152,7 +152,7 @@ bool protocol_ping_60001::handle_receive_ping(const code& ec,
if (stopped(ec))
return false;

SEND1(pong{ message->nonce }, handle_send_pong, _1);
SEND(pong{ message->nonce }, handle_send_pong, _1);
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion src/protocols/protocol_reject_70002.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void protocol_reject_70002::start() NOEXCEPT
if (started())
return;

SUBSCRIBE_CHANNEL2(reject, handle_receive_reject, _1, _2);
SUBSCRIBE_CHANNEL(reject, handle_receive_reject, _1, _2);

protocol::start();
}
Expand Down
Loading

0 comments on commit 147da53

Please sign in to comment.