Skip to content

Commit

Permalink
read/write same thread local storage
Browse files Browse the repository at this point in the history
  • Loading branch information
nicola-cab committed Dec 8, 2023
1 parent 27d40dc commit f23c120
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 6 deletions.
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

0 comments on commit f23c120

Please sign in to comment.