| .. _proxying-h: |
| |
| ========== |
| 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 |
| ----- |
| |
| .. c: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_runtime`` to avoid dropped work. |
| |
| .. c:type:: em_proxying_ctx |
| |
| An opaque handle to a currently-executing proxied task, used to signal the end |
| of the task. |
| |
| Functions |
| --------- |
| |
| .. c:function:: em_proxying_queue* em_proxying_queue_create() |
| |
| Allocate a new proxying queue. |
| |
| .. c:function:: void em_proxying_queue_destroy(em_proxying_queue* q) |
| |
| Free a proxying queue. The queue should not have any remaining queued work. |
| |
| .. c:function:: 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. |
| |
| .. c: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. |
| |
| .. c:function:: void emscripten_proxy_finish(em_proxying_ctx* ctx) |
| |
| Signal the end of a task proxied with ``emscripten_proxy_sync_with_ctx``. |
| |
| .. c:function:: bool emscripten_proxy_async(em_proxying_queue* q, pthread_t target_thread, void (*func)(void*), void* arg) |
| |
| Enqueue ``func`` to be called with argument ``arg`` on the given queue and |
| thread then return immediately without waiting for ``func`` to be executed. |
| Returns true if the work was successfully enqueued or false otherwise. |
| |
| .. c:function:: bool emscripten_proxy_sync(em_proxying_queue* q, pthread_t target_thread, void (*func)(void*), void* arg) |
| |
| Enqueue ``func`` to be called with argument ``arg`` on the given queue and |
| thread then wait for ``func`` to be executed synchronously before returning. |
| Returns true if the ``func`` was successfully completed and false otherwise, |
| including if the target thread is canceled or exits before the work is |
| completed. |
| |
| .. c:function:: bool 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_sync`` except that instead of waiting for the |
| proxied function to return, it waits for the proxied task to be explicitly |
| marked finished with ``emscripten_proxy_finish``. ``func`` need not call |
| ``emscripten_proxy_finish`` itself; it could instead store the context pointer |
| and call ``emscripten_proxy_finish`` at an arbitrary later time. |
| |
| .. c:function:: bool emscripten_proxy_callback(em_proxying_queue* q, pthread_t target_thread, void (*func)(void*), void (*callback)(void*), void (*cancel)(void*), void* arg) |
| |
| Enqueue ``func`` on the given queue and thread. Once (and if) it finishes |
| executing, it will asynchronously proxy ``callback`` back to the current |
| thread on the same queue, or if the target thread dies before the work can be |
| completed, ``cancel`` will be proxied back instead. All three function will |
| receive the same argument, ``arg``. Returns true if ``func`` was successfully |
| enqueued and the target thread notified or false otherwise. |
| |
| .. c:function:: bool 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 ``func`` on the given queue and thread. Once (and if) it finishes the |
| task by calling ``emscripten_proxy_finish`` on the given ``em_proxying_ctx``, |
| it will asynchronously proxy ``callback`` back to the current thread on the |
| same queue, or if the target thread dies before the work can be completed, |
| ``cancel`` will be proxied back instead. All three function will receive the |
| same argument, ``arg``. Returns true if ``func`` was successfully enqueued and |
| the target thread notified or false otherwise. |
| |
| C++ API |
| ------- |
| |
| This C++ API is provided by proxying.h when compiling with C++11 or later. It is |
| defined within namespace ``emscripten``. |
| |
| .. cpp:type:: ProxyingQueue |
| |
| A thin C++ wrapper around an ``em_proxying_queue*``. |
| |
| .. cpp:type:: ProxyingCtx |
| |
| A thin C++ wrapper around an ``em_proxying_ctx*``. |
| |
| .. cpp:member:: em_proxying_ctx* ctx |
| |
| The wrapped ``em_proxying_ctx*``. |
| |
| .. cpp:member:: void finish() |
| |
| Calls ``emscripten_proxy_finish`` on the wrapped ``em_proxying_ctx*``. |
| |
| .. cpp:member:: void execute() |
| |
| Calls ``emscripten_proxy_execute_queue`` on the wrapped ``em_proxying_queue*``. |
| |
| .. cpp:member:: bool proxyAsync(pthread_t target, std::function<void()>&& func) |
| |
| Calls ``emscripten_proxy_async`` to execute ``func``, returning ``true`` if the |
| function was successfully enqueued and ``false`` otherwise. |
| |
| .. cpp:member:: bool proxySync(const pthread_t target, const std::function<void()>& func) |
| |
| Calls ``emscripten_proxy_sync`` to execute ``func``, returning ``true`` if the |
| function was successfully completed or ``false`` otherwise. |
| |
| .. cpp:member:: bool proxySyncWithCtx(const pthread_t target, const std::function<void(ProxyingCtx)>& func) |
| |
| Calls ``emscripten_proxy_sync_with_ctx`` to execute ``func``, returning |
| ``true`` if the function was successfully marked done with |
| ``emscripten_proxy_finish`` or ``ProxyingCtx::finish`` and ``false`` |
| otherwise. |
| |
| .. cpp:member:: bool proxyCallback(pthread_t target, std::function<void()>&& func, std::function<void()>&& callback, std::function<void()>&& cancel) |
| |
| Calls ``emscripten_proxy_callback`` to execute ``func`` and schedule either |
| ``callback`` or ``cancel``, returning ``true`` if the function was |
| successfully enqueued and ``false`` otherwise. |
| |
| .. cpp:member:: bool proxyCallbackWithCtx(pthread_t target, std::function<void(ProxyingCtx)>&& func, std::function<void()>&& callback, std::function<void()>&& cancel) |
| |
| Calls ``emscripten_proxy_callback_with_ctx`` to execute ``func`` and |
| schedule either ``callback`` or ``cancel``, returning ``true`` if the |
| function was successfully enqueued and ``false`` otherwise. |
| |
| .. _proxying.h: https://github.com/emscripten-core/emscripten/blob/main/system/include/emscripten/proxying.h |
| .. _test_pthread_proxying.c: https://github.com/emscripten-core/emscripten/blob/main/test/pthread/test_pthread_proxying.c |
| .. _test_pthread_proxying_cpp.cpp: https://github.com/emscripten-core/emscripten/blob/main/test/pthread/test_pthread_proxying_cpp.cpp |