Skip to content

Add async support - #5

Open
alan-george-lk wants to merge 6 commits into
livekit/uniffi-0.31-cpp17from
livekit/uniffi-0.31-cpp17-async
Open

alan-george-lk wants to merge 6 commits into
livekit/uniffi-0.31-cpp17from
livekit/uniffi-0.31-cpp17-async

Conversation

@alan-george-lk

@alan-george-lk alan-george-lk commented Sep 15, 2026 •

Copy link
Copy Markdown
Collaborator

This PR adds initial Rust-to-C++ async support for UniFFI v0.31.

Async functions, constructors, and object methods now return a move-only uniffi::Future<T> supporting get(), wait(), wait_for(), and cancellation. Dropping an incomplete future also requests cancellation.

Poll, cancel, complete, and free operations are serialized on a dedicated worker thread per in-flight future, preventing re-entrant polling and cancellation/completion lifetime races.

Coverage is integrated through the repository’s existing test_case(futures) convention and includes:

  • Value and void returns
  • Records, optional objects, and object handles
  • Async constructors and methods
  • Typed errors and timeouts
  • Explicit and destructor-driven cancellation
  • Cancellation/completion races

Async callback interfaces, continuation APIs such as .then(), and a shared/global dispatcher are intentionally out of scope.

@alan-george-lk
alan-george-lk added this pull request to stack #4 September 15, 2026 03:44
@alan-george-lk
alan-george-lk force-pushed the livekit/uniffi-0.31-cpp17-async branch from b43f243 to bad762e Compare September 15, 2026 04:01
@alan-george-lk
alan-george-lk force-pushed the livekit/uniffi-0.31-cpp17 branch 2 times, most recently from 69dd556 to f18ea96 Compare September 15, 2026 04:30
@alan-george-lk
alan-george-lk force-pushed the livekit/uniffi-0.31-cpp17-async branch from bad762e to 8ca7832 Compare September 15, 2026 04:30
@alan-george-lk alan-george-lk changed the title Add Rust-to-C++ async function support Add async function support Sep 15, 2026
@alan-george-lk alan-george-lk changed the title Add async function support Add async support Sep 15, 2026
@alan-george-lk
alan-george-lk force-pushed the livekit/uniffi-0.31-cpp17 branch from f18ea96 to 0ed332d Compare September 15, 2026 15:35
@alan-george-lk
alan-george-lk force-pushed the livekit/uniffi-0.31-cpp17-async branch from 8ca7832 to ad3267c Compare September 15, 2026 15:35
@alan-george-lk
alan-george-lk force-pushed the livekit/uniffi-0.31-cpp17 branch from 0ed332d to 433eae1 Compare September 16, 2026 15:23
@alan-george-lk
alan-george-lk force-pushed the livekit/uniffi-0.31-cpp17-async branch 2 times, most recently from 100f2ea to f5cd234 Compare September 16, 2026 16:19
@@ -0,0 +1,102 @@
#include <test_common.hpp>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need some copyright headers for the new files that we add ?

promise_.set_value();
}
} else {
auto value = complete_(handle_, &status);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what will happen if the value from complete_(handle_, &status) is valid ?
That says, a race happened, and compete_() is done

wake_.notify_one();
}

void complete() noexcept {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, assert(handle_ != nullptr) ?

}
}

free_(handle_);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, should you set handle_ to nullptr after that ?

free_(handle_);
{
std::lock_guard<std::mutex> lock(mutex_);
finished_ = true;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curiously, do you need finished_ ? can we use handle_, and just check if it is nullptr?

void start() noexcept {
try {
auto state = this->shared_from_this();
std::thread([state = std::move(state)]() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is really worrying, one thread per in-flight future ?

can we do better ?

template <typename T>
class Future {
public:
Future(std::future<T> future, std::function<void()> cancel):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, curiously, from the c++ side, do you think we will need a default constructor, and allow c++ code to assign the future and cancel later ?

I am definitely OK if there is no needs for such things, just want to make sure.

)
{%- endmacro %}

{% macro rust_call_async_void_with_prefix(prefix, func) -%}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 4 macros look very similar with some small difference like a void return and a optional prefix.

Is there any chance to collapse them into one ? or 2 ?

@alan-george-lk
alan-george-lk force-pushed the livekit/uniffi-0.31-cpp17 branch from c396b3b to 2abac60 Compare September 18, 2026 00:28
@alan-george-lk
alan-george-lk force-pushed the livekit/uniffi-0.31-cpp17-async branch from f5cd234 to 26bfaa2 Compare September 18, 2026 00:32
@alan-george-lk
alan-george-lk force-pushed the livekit/uniffi-0.31-cpp17-async branch from 26bfaa2 to c4ad947 Compare September 22, 2026 18:43
@alan-george-lk
alan-george-lk removed this pull request from stack #4 September 22, 2026 19:04
@alan-george-lk
alan-george-lk force-pushed the livekit/uniffi-0.31-cpp17 branch from 7d04286 to 8509eb6 Compare September 22, 2026 19:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants