Seastar since
c4516f564197da409c1e5a012bd24c35457a9a40 provides
two variants of `seastar::with_lock`:
- generic, friendly towards throwing move constructors of
the passed callable,
- specialized for `noexcept`.
Unfortunately, the former has a limitation: the return value of
callable must be compatible with `current_exception_as_future()`
which boils down to returning `seastar::future<void>`. Therefore
we need to use the latter. The obstacle is `boost::intrusive_ptr`
we use for `CollectionRef` as it has the move constructor defined
without `noexcept`:
```cpp
emplate<class T> class intrusive_ptr
{
//
BOOST_CONSTEXPR intrusive_ptr() BOOST_SP_NOEXCEPT : px( 0 )
{
}
// ...
template<class U>
intrusive_ptr( intrusive_ptr<U> const & rhs, typename boost::detail::sp_enable_if_convertible<U,T>::type = boost::detail::sp_empty() )
intrusive_ptr( intrusive_ptr<U> const & rhs )
: px( rhs.get() )
{
if( px != 0 ) intrusive_ptr_add_ref( px );
}
// ...
intrusive_ptr(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT : px( rhs.px )
{
rhs.px = 0;
}
intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT
{
this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this);
return *this;
}
```
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
template <typename Func, typename Result = std::invoke_result_t<Func>>
seastar::futurize_t<Result> with_lock(Func&& func) {
+ // newer versions of Seastar provide two variants of `with_lock`
+ // - generic, friendly towards throwing move constructors of Func,
+ // - specialized for `noexcept`.
+ // unfortunately, the former has a limitation: the return value
+ // of `Func` must be compatible with `current_exception_as_future()`
+ // which boils down to returning `seastar::future<void>`.
+ static_assert(std::is_nothrow_move_constructible_v<Func>);
return seastar::with_lock(mutex, std::forward<Func>(func));
}
[this, ch, id] (auto &txn, auto &done) {
return seastar::with_gate(transaction_gate, [this, ch, id, &txn, &done] {
AlienCollection* alien_coll = static_cast<AlienCollection*>(ch.get());
- return alien_coll->with_lock([this, ch, id, &txn, &done] {
+ // moving the `ch` is crucial for buildability on newer S* versions.
+ return alien_coll->with_lock([this, ch=std::move(ch), id, &txn, &done] {
Context *crimson_wrapper =
ceph::os::Transaction::collect_all_contexts(txn);
assert(tp);