proxying.h
The Emscripten proxying.h API provides a mechanism for dispatching work to be executed by a target thread and optionally blocking until that work has been completed. This is particularly useful in a Web context where certain JS APIs can only be called on particular threads; any thread can access those APIs by proxying the API calls to the correct threads. Proxying is also useful for wrapping asynchronous JS tasks with a synchronous interface. The calling thread can proxy the asynchronous task to a dedicated worker thread and wait until the worker thread eventually marks the task as complete, possibly after returning multiple times to the JS event loop.
On the target thread, queued work can be executed in two ways. First, the user
may explicitly call emscripten_proxy_execute_queue to execute any tasks that
have been queued for the current thread. Alternatively, queued work will execute
automatically if the target thread returns to the JS event loop, for example via
emscripten_exit_with_live_runtime.
See test_pthread_proxying.c and test_pthread_proxying_cpp.cpp for examples of how to use the proxying API.
API Reference
Types
-
type em_proxying_queue
An opaque handle to a set of thread-local work queues (one per thread) to which work can be asynchronously or synchronously proxied from other threads.
Proxied work can only be completed on live thread runtimes, so users must ensure either that all proxied work is completed before a thread exits or that the thread exits with a live runtime, e.g. via
emscripten_exit_with_live_runtimeto avoid dropped work.
-
type em_proxying_ctx
An opaque handle to a currently-executing proxied task, used to signal the end of the task.
Functions
-
em_proxying_queue *em_proxying_queue_create()
Allocate a new proxying queue.
-
void em_proxying_queue_destroy(em_proxying_queue *q)
Free a proxying queue. The queue should not have any remaining queued work.
-
em_proxying_queue *emscripten_proxy_get_system_queue()
Get the queue used for proxying low-level runtime work. Work on this queue may be processed at any time inside system functions, so it must be nonblocking and safe to run at any time, similar to a native signal handler. User code should generally not use this function.
-
void emscripten_proxy_execute_queue(em_proxying_queue *q)
Execute all the tasks enqueued for the current thread on the given queue. New tasks that are enqueued concurrently with this execution will be executed as well. This function returns once it observes an empty queue.
-
void emscripten_proxy_finish(em_proxying_ctx *ctx)
Signal the end of a task proxied with
emscripten_proxy_sync_with_ctx.
-
int emscripten_proxy_async(em_proxying_queue *q, pthread_t target_thread, void (*func)(void*), void *arg)
Enqueue
functo be called with argumentargon the given queue and thread then return immediately without waiting forfuncto be executed. Returns 1 if the work was successfully enqueued or 0 otherwise.
-
int emscripten_proxy_sync(em_proxying_queue *q, pthread_t target_thread, void (*func)(void*), void *arg)
Enqueue
functo be called with argumentargon the given queue and thread then wait forfuncto be executed synchronously before returning. Returns 1 if thefuncwas successfully completed and 0 otherwise, including if the target thread is canceled or exits before the work is completed.
-
int emscripten_proxy_sync_with_ctx(em_proxying_queue *q, pthread_t target_thread, void (*func)(em_proxying_ctx*, void*), void *arg)
The same as
emscripten_proxy_syncexcept that instead of waiting for the proxied function to return, it waits for the proxied task to be explicitly marked finished withemscripten_proxy_finish.funcneed not callemscripten_proxy_finishitself; it could instead store the context pointer and callemscripten_proxy_finishat an arbitrary later time.
-
int emscripten_proxy_callback(em_proxying_queue *q, pthread_t target_thread, void (*func)(void*), void (*callback)(void*), void (*cancel)(void*), void *arg)
Enqueue
funcon the given queue and thread. Once (and if) it finishes executing, it will asynchronously proxycallbackback to the current thread on the same queue, or if the target thread dies before the work can be completed,cancelwill be proxied back instead. All three function will receive the same argument,arg. Returns 1 iffuncwas successfully enqueued and the target thread notified or 0 otherwise.
-
int emscripten_proxy_callback_with_ctx(em_proxying_queue *q, pthread_t target_thread, void (*func)(em_proxying_ctx*, void*), void (*callback)(void*), void (*cancel)(void*), void *arg)
Enqueue
funcon the given queue and thread. Once (and if) it finishes the task by callingemscripten_proxy_finishon the givenem_proxying_ctx, it will asynchronously proxycallbackback to the current thread on the same queue, or if the target thread dies before the work can be completed,cancelwill be proxied back instead. All three function will receive the same argument,arg. Returns 1 iffuncwas successfully enqueued and the target thread notified or 0 otherwise.
C++ API
This C++ API is provided by proxying.h when compiling with C++11 or later. It is
defined within namespace emscripten.
-
type ProxyingQueue
A thin C++ wrapper around an
em_proxying_queue*.-
type ProxyingCtx
A thin C++ wrapper around an
em_proxying_ctx*.-
void execute()
Calls
emscripten_proxy_execute_queueon the wrappedem_proxying_queue*.
-
bool proxyAsync(pthread_t target, std::function<void()> &&func)
Calls
emscripten_proxy_asyncto executefunc, returningtrueif the function was successfully enqueued andfalseotherwise.
-
bool proxySync(const pthread_t target, const std::function<void()> &func)
Calls
emscripten_proxy_syncto executefunc, returningtrueif the function was successfully completed orfalseotherwise.
-
bool proxySyncWithCtx(const pthread_t target, const std::function<void(ProxyingCtx)> &func)
Calls
emscripten_proxy_sync_with_ctxto executefunc, returningtrueif the function was successfully marked done withemscripten_proxy_finishorProxyingCtx::finishandfalseotherwise.
-
bool proxyCallback(pthread_t target, std::function<void()> &&func, std::function<void()> &&callback, std::function<void()> &&cancel)
Calls
emscripten_proxy_callbackto executefuncand schedule eithercallbackorcancel, returningtrueif the function was successfully enqueued andfalseotherwise.
-
bool proxyCallbackWithCtx(pthread_t target, std::function<void(ProxyingCtx)> &&func, std::function<void()> &&callback, std::function<void()> &&cancel)
Calls
emscripten_proxy_callback_with_ctxto executefuncand schedule eithercallbackorcancel, returningtrueif the function was successfully enqueued andfalseotherwise.
-
type ProxyingCtx
