Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read/write same thread local storage #7195

Closed
Closed
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
9 changes: 9 additions & 0 deletions src/realm/exceptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ struct RuntimeError : Exception {
~RuntimeError() noexcept override;
};

struct UserCodeCallbackError : RuntimeError {
void* user_code_error = nullptr;
UserCodeCallbackError(ErrorCodes::Error code, std::string_view msg)
: RuntimeError(code, msg)
{
}
~UserCodeCallbackError() noexcept override = default;
};

/// Thrown when creating references that are too large to be contained in our ref_type (size_t)
struct MaximumFileSizeExceeded : RuntimeError {
MaximumFileSizeExceeded(std::string_view msg)
Expand Down
7 changes: 4 additions & 3 deletions src/realm/object-store/c_api/sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,8 @@ RLM_API void realm_sync_config_set_error_handler(realm_sync_config_t* config, re
c_error.server_requests_action = static_cast<realm_sync_error_action_e>(error.server_requests_action);
c_error.c_original_file_path_key = error.c_original_file_path_key;
c_error.c_recovery_file_path_key = error.c_recovery_file_path_key;
c_error.user_code_error = ErrorStorage::get_thread_local()->get_and_clear_user_code_error();
c_error.user_code_error = error.user_code_error;
// ErrorStorage::get_thread_local()->get_and_clear_user_code_error();

std::vector<realm_sync_error_user_info_t> c_user_info;
c_user_info.reserve(error.user_info.size());
Expand Down Expand Up @@ -389,7 +390,7 @@ RLM_API void realm_sync_config_set_before_client_reset_handler(realm_sync_config
auto cb = [callback, userdata = SharedUserdata(userdata, FreeUserdata(userdata_free))](SharedRealm before_realm) {
realm_t r1{before_realm};
if (!callback(userdata.get(), &r1)) {
throw CallbackFailed{};
throw CallbackFailed{ErrorStorage::get_thread_local()->get_and_clear_user_code_error()};
}
};
config->notify_before_client_reset = std::move(cb);
Expand All @@ -405,7 +406,7 @@ RLM_API void realm_sync_config_set_after_client_reset_handler(realm_sync_config_
realm_t r1{before_realm};
auto tsr = realm_t::thread_safe_reference(std::move(after_realm));
if (!callback(userdata.get(), &r1, &tsr, did_recover)) {
throw CallbackFailed{};
throw CallbackFailed{ErrorStorage::get_thread_local()->get_and_clear_user_code_error()};
}
};
config->notify_after_client_reset = std::move(cb);
Expand Down
5 changes: 2 additions & 3 deletions src/realm/object-store/c_api/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,13 @@ class NotClonable : public RuntimeError {
}
};

class CallbackFailed : public RuntimeError {
class CallbackFailed : public UserCodeCallbackError {
public:
// SDK-provided opaque error value when error == RLM_ERR_CALLBACK with a callout to
// realm_register_user_code_callback_error()
void* user_code_error{nullptr};

CallbackFailed()
: RuntimeError(ErrorCodes::CallbackFailed, "User-provided callback failed")
: UserCodeCallbackError(ErrorCodes::CallbackFailed, "User-provided callback failed")
{
}

Expand Down
1 change: 1 addition & 0 deletions src/realm/object-store/sync/sync_session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,7 @@ void SyncSession::handle_error(sync::SessionErrorInfo error)
// `action` is used over `shouldClientReset` and `isRecoveryModeDisabled`.
sync_error.server_requests_action = error.server_requests_action;
sync_error.is_unrecognized_by_client = unrecognized_by_client;
sync_error.user_code_error = error.user_code_error;

if (delete_file)
update_error_and_mark_file_for_deletion(sync_error, *delete_file);
Expand Down
1 change: 1 addition & 0 deletions src/realm/sync/client_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ struct SessionErrorInfo : public ProtocolErrorInfo {
}

Status status;
void* user_code_error = nullptr;
};

enum class ConnectionState { disconnected, connecting, connected };
Expand Down
2 changes: 2 additions & 0 deletions src/realm/sync/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ struct SyncError {

/// The error indicates a client reset situation.
bool is_client_reset_requested() const;

void* user_code_error = nullptr;
};

using SyncSessionErrorHandler = void(std::shared_ptr<SyncSession>, SyncError);
Expand Down
8 changes: 8 additions & 0 deletions src/realm/sync/noinst/client_impl_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2294,6 +2294,14 @@ Status Session::receive_ident_message(SaltedFileIdent client_file_ident)
try {
did_client_reset = client_reset_if_needed();
}
catch (const UserCodeCallbackError& e) {
auto err_msg = util::format("A fatal error occurred during client reset: '%1'", e.what());
logger.error(err_msg.c_str());
SessionErrorInfo err_info(Status{ErrorCodes::AutoClientResetFailed, err_msg}, IsFatal{true});
err_info.user_code_error = e.user_code_error;
suspend(err_info);
return Status::OK();
}
catch (const std::exception& e) {
auto err_msg = util::format("A fatal error occurred during client reset: '%1'", e.what());
logger.error(err_msg.c_str());
Expand Down
Loading