bool pure_poll_rx() const;
};
-class smp {
- struct qs_deleter {
- unsigned count;
- qs_deleter(unsigned n = 0) : count(n) {}
- qs_deleter(const qs_deleter& d) : count(d.count) {}
- void operator()(message_queue* qs) const;
- };
- using qs = std::unique_ptr<message_queue[], qs_deleter>;
+namespace internal {
+
+struct qs_deleter {
+ unsigned count;
+ qs_deleter(unsigned n = 0) : count(n) {}
+ qs_deleter(const qs_deleter& d) : count(d.count) {}
+ void operator()(message_queue* qs) const;
+};
+
+}
+
+/// Represents the Seastar system from alien's point of view. In a normal
+/// system, there is just one instance, but for in-process clustering testing
+/// there may be more than one. Function such as run_on() direct messages to
+/// and (instance, shard) tuple.
+class instance {
+ using qs = std::unique_ptr<message_queue[], internal::qs_deleter>;
public:
static qs create_qs(const std::vector<reactor*>& reactors);
- static qs _qs;
- static bool poll_queues();
- static bool pure_poll_queues();
+ qs _qs;
+ bool poll_queues();
+ bool pure_poll_queues();
};
+namespace internal {
+
+extern instance* default_instance;
+
+}
+
/// Runs a function on a remote shard from an alien thread where engine() is not available.
///
+/// \param instance designates the Seastar instance to process the message
/// \param shard designates the shard to run the function on
/// \param func a callable to run on shard \c t. If \c func is a temporary object,
/// its lifetime will be extended by moving it. If \c func is a reference,
/// interested to the return value. Please use \c submit_to() instead, if
/// \c func throws.
template <typename Func>
+void run_on(instance& instance, unsigned shard, Func func) {
+ instance._qs[shard].submit(std::move(func));
+}
+
+/// Runs a function on a remote shard from an alien thread where engine() is not available.
+///
+/// \param shard designates the shard to run the function on
+/// \param func a callable to run on shard \c t. If \c func is a temporary object,
+/// its lifetime will be extended by moving it. If \c func is a reference,
+/// the caller must guarantee that it will survive the call.
+/// \note the func must not throw and should return \c void. as we cannot identify the
+/// alien thread, hence we are not able to post the fulfilled promise to the
+/// message queue managed by the shard executing the alien thread which is
+/// interested to the return value. Please use \c submit_to() instead, if
+/// \c func throws.
+template <typename Func>
+[[deprecated("Use run_on(instance&, unsigned shard, Func) instead")]]
void run_on(unsigned shard, Func func) {
- smp::_qs[shard].submit(std::move(func));
+ run_on(*internal::default_instance, shard, std::move(func));
}
namespace internal {
/// Runs a function on a remote shard from an alien thread where engine() is not available.
///
+/// \param instance designates the Seastar instance to process the message
/// \param shard designates the shard to run the function on
/// \param func a callable to run on \c shard. If \c func is a temporary object,
/// its lifetime will be extended by moving it. If \c func is a reference,
/// \return whatever \c func returns, as a \c std::future<>
/// \note the caller must keep the returned future alive until \c func returns
template<typename Func, typename T = internal::return_type_t<Func>>
-std::future<T> submit_to(unsigned shard, Func func) {
+std::future<T> submit_to(instance& instance, unsigned shard, Func func) {
std::promise<T> pr;
auto fut = pr.get_future();
- run_on(shard, [pr = std::move(pr), func = std::move(func)] () mutable {
+ run_on(instance, shard, [pr = std::move(pr), func = std::move(func)] () mutable {
// std::future returned via std::promise above.
(void)func().then_wrapped([pr = std::move(pr)] (auto&& result) mutable {
try {
return fut;
}
+/// Runs a function on a remote shard from an alien thread where engine() is not available.
+///
+/// \param shard designates the shard to run the function on
+/// \param func a callable to run on \c shard. If \c func is a temporary object,
+/// its lifetime will be extended by moving it. If \c func is a reference,
+/// the caller must guarantee that it will survive the call.
+/// \return whatever \c func returns, as a \c std::future<>
+/// \note the caller must keep the returned future alive until \c func returns
+template<typename Func, typename T = internal::return_type_t<Func>>
+[[deprecated("Use submit_to(instance&, unsigned shard, Func) instead.")]]
+std::future<T> submit_to(unsigned shard, Func func) {
+ return submit_to(*internal::default_instance, shard, std::move(func));
+}
+
}
}