in theory, std::result_of_t should have been removed in C++20. and
std::invoke_result_t is available since C++17. thanks to libstdc++,
the tree is compiling. but we should not rely on this.
so, in this change, we replace all `std::result_of_t` with
`std::invoke_result_t`. actually, clang + libstdc++ is already warning
us like:
```
In file included from /home/runner/work/scylladb/scylladb/multishard_mutation_query.cc:9:
In file included from /home/runner/work/scylladb/scylladb/schema/schema_registry.hh:11:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/unordered_map:38:
Warning: /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/type_traits:2624:5: warning: 'result_of<void (noop_compacted_fragments_consumer::*(noop_compacted_fragments_consumer &))()>' is deprecated: use 'std::invoke_result' instead [-Wdeprecated-declarations]
2624 | using result_of_t = typename result_of<_Tp>::type;
| ^
/home/runner/work/scylladb/scylladb/mutation/mutation_compactor.hh:518:43: note: in instantiation of template type alias 'result_of_t' requested here
518 | if constexpr (std::is_same_v<std::result_of_t<decltype(&GCConsumer::consume_end_of_stream)(GCConsumer&)>, void>) {
|
```
Signed-off-by: Kefu Chai <kefu.chai@scylladb.com>
Closes scylladb/scylladb#18835
85 lines
3.3 KiB
C++
85 lines
3.3 KiB
C++
/*
|
|
* Copyright 2016-present ScyllaDB
|
|
**/
|
|
|
|
/* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <boost/signals2.hpp>
|
|
#include <boost/signals2/dummy_mutex.hpp>
|
|
#include <type_traits>
|
|
#include <concepts>
|
|
|
|
#include <seastar/core/future.hh>
|
|
|
|
#include "seastarx.hh"
|
|
|
|
namespace bs2 = boost::signals2;
|
|
|
|
using disk_error_signal_type = bs2::signal_type<void (), bs2::keywords::mutex_type<bs2::dummy_mutex>>::type;
|
|
|
|
extern thread_local disk_error_signal_type commit_error;
|
|
extern thread_local disk_error_signal_type sstable_read_error;
|
|
extern thread_local disk_error_signal_type sstable_write_error;
|
|
extern thread_local disk_error_signal_type general_disk_error;
|
|
|
|
bool should_stop_on_system_error(const std::system_error& e);
|
|
|
|
using io_error_handler = std::function<void (std::exception_ptr)>;
|
|
// stores a function that generates a io handler for a given signal.
|
|
using io_error_handler_gen = std::function<io_error_handler (disk_error_signal_type&)>;
|
|
|
|
io_error_handler default_io_error_handler(disk_error_signal_type& signal);
|
|
// generates handler that handles exception for a given signal
|
|
io_error_handler_gen default_io_error_handler_gen();
|
|
|
|
extern thread_local io_error_handler commit_error_handler;
|
|
extern thread_local io_error_handler sstable_write_error_handler;
|
|
extern thread_local io_error_handler general_disk_error_handler;
|
|
|
|
template<typename Func, typename... Args>
|
|
requires std::invocable<Func, Args&&...>
|
|
&& (!is_future<std::invoke_result_t<Func, Args&&...>>::value)
|
|
std::invoke_result_t<Func, Args&&...>
|
|
do_io_check(const io_error_handler& error_handler, Func&& func, Args&&... args) {
|
|
try {
|
|
// calling function
|
|
return func(std::forward<Args>(args)...);
|
|
} catch (...) {
|
|
error_handler(std::current_exception());
|
|
throw;
|
|
}
|
|
}
|
|
|
|
template<typename Func, typename... Args>
|
|
requires std::invocable<Func, Args&&...>
|
|
&& is_future<std::invoke_result_t<Func, Args&&...>>::value
|
|
auto do_io_check(const io_error_handler& error_handler, Func&& func, Args&&... args) noexcept {
|
|
return futurize_invoke(func, std::forward<Args>(args)...).handle_exception([&error_handler] (auto ep) {
|
|
error_handler(ep);
|
|
return futurize<std::invoke_result_t<Func, Args&&...>>::make_exception_future(ep);
|
|
});
|
|
}
|
|
|
|
template<typename Func, typename... Args>
|
|
auto commit_io_check(Func&& func, Args&&... args) noexcept(is_future<std::invoke_result_t<Func, Args&&...>>::value) {
|
|
return do_io_check(commit_error_handler, std::forward<Func>(func), std::forward<Args>(args)...);
|
|
}
|
|
|
|
template<typename Func, typename... Args>
|
|
auto sstable_io_check(const io_error_handler& error_handler, Func&& func, Args&&... args) noexcept(is_future<std::invoke_result_t<Func, Args&&...>>::value) {
|
|
return do_io_check(error_handler, std::forward<Func>(func), std::forward<Args>(args)...);
|
|
}
|
|
|
|
template<typename Func, typename... Args>
|
|
auto io_check(const io_error_handler& error_handler, Func&& func, Args&&... args) noexcept(is_future<std::invoke_result_t<Func, Args&&...>>::value) {
|
|
return do_io_check(error_handler, general_disk_error, std::forward<Func>(func), std::forward<Args>(args)...);
|
|
}
|
|
|
|
template<typename Func, typename... Args>
|
|
auto io_check(Func&& func, Args&&... args) noexcept(is_future<std::invoke_result_t<Func, Args&&...>>::value) {
|
|
return do_io_check(general_disk_error_handler, std::forward<Func>(func), std::forward<Args>(args)...);
|
|
}
|