Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#ifndef SPACETIMEDB_RUNTIME_REGISTRATION_H
#define SPACETIMEDB_RUNTIME_REGISTRATION_H

#include <atomic>
#include <functional>
#include <optional>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "../abi/opaque_types.h"
#include "autogen/Lifecycle.g.h"
Expand Down Expand Up @@ -33,6 +36,18 @@ std::vector<uint8_t> ConsumeBytes(BytesSource source);
void SetMultiplePrimaryKeyError(const std::string& table_name);
void SetConstraintRegistrationError(const std::string& code, const std::string& details);

template <typename F>
__attribute__((noinline)) decltype(auto) __spacetimedb_begin_short_backtrace(F&& f) {
if constexpr (std::is_void_v<std::invoke_result_t<F>>) {
std::forward<F>(f)();
std::atomic_signal_fence(std::memory_order_seq_cst);
} else {
decltype(auto) result = std::forward<F>(f)();
std::atomic_signal_fence(std::memory_order_seq_cst);
return result;
}
}

} // namespace Internal
} // namespace SpacetimeDB

Expand Down
36 changes: 26 additions & 10 deletions crates/bindings-cpp/include/spacetimedb/internal/v10_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,9 @@ class V10Builder {
std::function<void(ReducerContext&, BytesSource)> handler;
if constexpr (traits::arity == 1) {
handler = [func](ReducerContext& ctx, BytesSource) {
auto result = func(ctx);
auto result = __spacetimedb_begin_short_backtrace([&] {
return func(ctx);
});
if (result.is_err()) {
::SpacetimeDB::fail_reducer(result.error());
}
Expand All @@ -349,7 +351,9 @@ class V10Builder {
bsatn::Reader reader(bytes.data(), bytes.size());
auto args = std::make_tuple(bsatn::deserialize<typename traits::template arg_t<Js + 1>>(reader)...);
std::apply([&ctx_inner, fn](auto&&... unpacked) {
auto result = fn(ctx_inner, std::forward<decltype(unpacked)>(unpacked)...);
auto result = __spacetimedb_begin_short_backtrace([&] {
return fn(ctx_inner, std::forward<decltype(unpacked)>(unpacked)...);
});
if (result.is_err()) {
::SpacetimeDB::fail_reducer(result.error());
}
Expand Down Expand Up @@ -406,7 +410,9 @@ class V10Builder {
std::function<void(ReducerContext&, BytesSource)> handler;
if constexpr (traits::arity == 1) {
handler = [func](ReducerContext& ctx, BytesSource) {
auto result = func(ctx);
auto result = __spacetimedb_begin_short_backtrace([&] {
return func(ctx);
});
if (result.is_err()) {
::SpacetimeDB::fail_reducer(result.error());
}
Expand All @@ -418,7 +424,9 @@ class V10Builder {
bsatn::Reader reader(bytes.data(), bytes.size());
auto args = std::make_tuple(bsatn::deserialize<typename traits::template arg_t<Js + 1>>(reader)...);
std::apply([&ctx_inner, fn](auto&&... unpacked) {
auto result = fn(ctx_inner, std::forward<decltype(unpacked)>(unpacked)...);
auto result = __spacetimedb_begin_short_backtrace([&] {
return fn(ctx_inner, std::forward<decltype(unpacked)>(unpacked)...);
});
if (result.is_err()) {
::SpacetimeDB::fail_reducer(result.error());
}
Expand Down Expand Up @@ -461,7 +469,9 @@ class V10Builder {
std::function<std::vector<uint8_t>(ViewContext&, BytesSource)> handler =
[func](ViewContext& ctx, BytesSource args_source) -> std::vector<uint8_t> {
(void)args_source;
auto result = func(ctx);
auto result = __spacetimedb_begin_short_backtrace([&] {
return func(ctx);
});
auto result_vec = view_result_to_vec(std::move(result));
IterBuf buf = IterBuf::take();
{
Expand All @@ -475,7 +485,9 @@ class V10Builder {
std::function<std::vector<uint8_t>(AnonymousViewContext&, BytesSource)> handler =
[func](AnonymousViewContext& ctx, BytesSource args_source) -> std::vector<uint8_t> {
(void)args_source;
auto result = func(ctx);
auto result = __spacetimedb_begin_short_backtrace([&] {
return func(ctx);
});
auto result_vec = view_result_to_vec(std::move(result));
IterBuf buf = IterBuf::take();
{
Expand Down Expand Up @@ -525,7 +537,9 @@ class V10Builder {
std::function<std::vector<uint8_t>(ProcedureContext&, BytesSource)> handler;
if constexpr (traits::arity == 1) {
handler = [func](ProcedureContext& ctx, BytesSource) -> std::vector<uint8_t> {
auto result = func(ctx);
auto result = __spacetimedb_begin_short_backtrace([&] {
return func(ctx);
});
IterBuf buf = IterBuf::take();
{
bsatn::Writer writer(buf.get());
Expand All @@ -539,9 +553,11 @@ class V10Builder {
return []<std::size_t... Js>(std::index_sequence<Js...>, Func fn, ProcedureContext& ctx_inner, const std::vector<uint8_t>& bytes) -> std::vector<uint8_t> {
bsatn::Reader reader(bytes.data(), bytes.size());
auto args = std::make_tuple(bsatn::deserialize<typename traits::template arg_t<Js + 1>>(reader)...);
auto result = std::apply([&ctx_inner, fn](auto&&... unpacked) {
return fn(ctx_inner, std::forward<decltype(unpacked)>(unpacked)...);
}, args);
auto result = __spacetimedb_begin_short_backtrace([&] {
return std::apply([&ctx_inner, fn](auto&&... unpacked) {
return fn(ctx_inner, std::forward<decltype(unpacked)>(unpacked)...);
}, args);
});
IterBuf buf = IterBuf::take();
{
bsatn::Writer writer(buf.get());
Expand Down
5 changes: 3 additions & 2 deletions crates/bindings-cpp/include/spacetimedb/procedure_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ struct is_valid_procedure_return_type : std::integral_constant<bool, bsatn::Seri
} \
\
/* The actual procedure function definition */ \
return_type procedure_name(ctx_param __VA_OPT__(,) __VA_ARGS__)
/* noinline ensures this function appears as a named frame in backtraces */ \
__attribute__((noinline)) return_type procedure_name(ctx_param __VA_OPT__(,) __VA_ARGS__)

#define SPACETIMEDB_PROCEDURE_NAMED(return_type, procedure_name, canonical_name, ctx_param, ...) \
static_assert(::SpacetimeDB::Internal::is_valid_procedure_return_type<return_type>::value, \
Expand All @@ -120,4 +121,4 @@ struct is_valid_procedure_return_type : std::integral_constant<bool, bsatn::Seri
#procedure_name, procedure_name, param_names); \
SpacetimeDB::Module::RegisterExplicitFunctionName(#procedure_name, canonical_name); \
} \
return_type procedure_name(ctx_param __VA_OPT__(,) __VA_ARGS__)
__attribute__((noinline)) return_type procedure_name(ctx_param __VA_OPT__(,) __VA_ARGS__)
11 changes: 6 additions & 5 deletions crates/bindings-cpp/include/spacetimedb/reducer_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@
} \
\
/* The actual reducer function definition - returns ReducerResult */ \
SpacetimeDB::ReducerResult name(ctx_param __VA_OPT__(,) __VA_ARGS__)
/* noinline ensures this function appears as a named frame in backtraces */ \
__attribute__((noinline)) SpacetimeDB::ReducerResult name(ctx_param __VA_OPT__(,) __VA_ARGS__)

#define SPACETIMEDB_REDUCER_NAMED(name, canonical_name, ctx_param, ...) \
SpacetimeDB::ReducerResult name(ctx_param __VA_OPT__(,) __VA_ARGS__); \
Expand All @@ -84,7 +85,7 @@
SpacetimeDB::Internal::getV10Builder().RegisterReducer(#name, name, param_names); \
SpacetimeDB::Module::RegisterExplicitFunctionName(#name, canonical_name); \
} \
SpacetimeDB::ReducerResult name(ctx_param __VA_OPT__(,) __VA_ARGS__)
__attribute__((noinline)) SpacetimeDB::ReducerResult name(ctx_param __VA_OPT__(,) __VA_ARGS__)

// -----------------------------------------------------------------------------
// Lifecycle Reducer Macros
Expand Down Expand Up @@ -115,7 +116,7 @@
extern "C" void CONCAT(_preinit_register_init_reducer_, function_name)() { \
::SpacetimeDB::Internal::getV10Builder().RegisterLifecycleReducer(#function_name, function_name, ::SpacetimeDB::Internal::Lifecycle::Init); \
} \
SpacetimeDB::ReducerResult function_name(ctx_param)
__attribute__((noinline)) SpacetimeDB::ReducerResult function_name(ctx_param)

/**
* @brief Macro for defining a client_connected reducer
Expand All @@ -139,7 +140,7 @@
extern "C" void CONCAT(_preinit_register_client_connected_, function_name)() { \
::SpacetimeDB::Internal::getV10Builder().RegisterLifecycleReducer(#function_name, function_name, ::SpacetimeDB::Internal::Lifecycle::OnConnect); \
} \
SpacetimeDB::ReducerResult function_name(ctx_param)
__attribute__((noinline)) SpacetimeDB::ReducerResult function_name(ctx_param)

/**
* @brief Macro for defining a client_disconnected reducer
Expand All @@ -163,4 +164,4 @@
extern "C" void CONCAT(_preinit_register_client_disconnected_, function_name)() { \
::SpacetimeDB::Internal::getV10Builder().RegisterLifecycleReducer(#function_name, function_name, ::SpacetimeDB::Internal::Lifecycle::OnDisconnect); \
} \
SpacetimeDB::ReducerResult function_name(ctx_param)
__attribute__((noinline)) SpacetimeDB::ReducerResult function_name(ctx_param)
5 changes: 3 additions & 2 deletions crates/bindings-cpp/include/spacetimedb/view_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ struct is_valid_view_return_type<std::optional<T>>
\
/* TODO: When parameters are supported, function definition becomes: */ \
/* return_type view_name(ctx_param, __VA_ARGS__) */ \
return_type view_name(ctx_param)
/* noinline ensures this function appears as a named frame in backtraces */ \
__attribute__((noinline)) return_type view_name(ctx_param)

#define SPACETIMEDB_VIEW_NAMED(return_type, view_name, canonical_name, access_enum, ctx_param) \
static_assert(access_enum == SpacetimeDB::Internal::TableAccess::Public, \
Expand All @@ -130,4 +131,4 @@ struct is_valid_view_return_type<std::optional<T>>
#view_name, view_name, is_public, param_names); \
SpacetimeDB::Module::RegisterExplicitFunctionName(#view_name, canonical_name); \
} \
return_type view_name(ctx_param)
__attribute__((noinline)) return_type view_name(ctx_param)
Loading
Loading