Skip to content

Replace FFI raw Arc ownership with an opaque, destructible handle #667

Description

@RyanKung

Problem

crates/node/src/provider/ffi.rs exposes ProviderPtr as two raw pointers and reconstructs Arc<Provider> / Arc<Runtime> with Arc::from_raw on every FFI call. A raw Arc ownership token must be converted back exactly once; repeated conversion is not a sound ownership model. The current check_arc threshold also adds strong references without matching decrements.

The C API additionally returns CString::into_raw() from request(), but crates/node/include/rings.h has no matching string-free function or provider-destroy function. The global FFI E2E inbox registry consequently has no explicit cleanup path.

Proposed direction

Replace ProviderPtr with an opaque *mut ProviderHandle allocated as Box<ProviderHandle>. The handle should own ordinary Arc<Provider>, Arc<Runtime>, and its FFI inbox state directly. Do not expose or reconstruct raw Arc pointers across the boundary.

Add explicit C ABI cleanup functions, e.g.:

  • provider_destroy(ProviderHandle *)
  • provider_string_free(char *)

Remove check_arc, increase_provider_count, and increase_runtime_count. Ensure destroy removes the handle's inbox/associated state.

Acceptance criteria

  • Every raw allocation has one documented corresponding free API.
  • Repeated create/listen/request/take-events/destroy cycles are covered by an automated FFI integration test.
  • Returned request strings are freed by the caller through the documented API.
  • No FFI call uses Arc::from_raw or manual Arc::increment_strong_count for handle lifetime.
  • The public header documents ownership and invalid-handle behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions