Emscripten proxying.h API 提供了一种机制,用于调度要由目标线程执行的工作,并可以选择性地阻塞,直到该工作完成。这在 Web 上下文中特别有用,在该上下文中,某些 JS API 只能在特定线程上调用;任何线程都可以通过将 API 调用代理到正确的线程来访问这些 API。代理对于用同步接口包装异步 JS 任务也很有用。调用线程可以将异步任务代理到专用的工作线程,并在工作线程最终将任务标记为完成之前等待,这可能在多次返回 JS 事件循环后。
在目标线程上,排队的作业可以通过两种方式执行。首先,用户可以显式调用 emscripten_proxy_execute_queue
来执行为当前线程排队的任何任务。或者,如果目标线程返回 JS 事件循环(例如通过 emscripten_exit_with_live_runtime
),排队的作业将自动执行。
请参阅 test_pthread_proxying.c 和 test_pthread_proxying_cpp.cpp 以了解如何使用代理 API 的示例。
em_proxying_queue
¶一组线程局部工作队列(每个线程一个)的不透明句柄,可以从其他线程异步或同步地代理工作到这些队列。
代理工作只能在活动的线程运行时完成,因此用户必须确保在线程退出之前所有代理工作都已完成,或者线程退出时使用活动运行时,例如通过 emscripten_exit_with_live_runtime
,以避免丢失工作。
em_proxying_ctx
¶当前正在执行的代理任务的不透明句柄,用于发出任务结束的信号。
em_proxying_queue_create
()¶分配一个新的代理队列。
em_proxying_queue_destroy
(em_proxying_queue* q)¶释放一个代理队列。队列不应有任何剩余的排队作业。
emscripten_proxy_get_system_queue
()¶获取用于代理低级运行时工作的队列。此队列上的工作可以在系统函数内部随时处理,因此它必须是非阻塞的,并且可以随时安全运行,类似于本机信号处理程序。用户代码通常不应使用此函数。
emscripten_proxy_execute_queue
(em_proxying_queue* q)¶在给定队列上执行为当前线程排队的全部任务。与执行同时排队的全新任务也会被执行。该函数返回,此时它观测到一个空队列。
emscripten_proxy_finish
(em_proxying_ctx* ctx)¶发出使用 emscripten_proxy_sync_with_ctx
代理的任务结束的信号。
emscripten_proxy_async
(em_proxying_queue* q, pthread_t target_thread, void (*func)(void*), void* arg)¶在给定队列和线程上排队 func
以使用参数 arg
调用,然后立即返回,而不等待执行 func
。如果工作成功排队,则返回 1,否则返回 0。
emscripten_proxy_sync
(em_proxying_queue* q, pthread_t target_thread, void (*func)(void*), void* arg)¶在给定队列和线程上排队 func
以使用参数 arg
调用,然后在返回之前同步等待执行 func
。如果 func
成功完成,则返回 1,否则返回 0,包括如果目标线程在工作完成之前被取消或退出。
emscripten_proxy_sync_with_ctx
(em_proxying_queue* q, pthread_t target_thread, void (*func)(em_proxying_ctx*, void*), void* arg)¶与 emscripten_proxy_sync
相同,除了它不等待代理函数返回,而是等待使用 emscripten_proxy_finish
显式标记完成的代理任务。 func
本身不需要调用 emscripten_proxy_finish
;它可以改为存储上下文指针,并在任意时间调用 emscripten_proxy_finish
。
emscripten_proxy_callback
(em_proxying_queue* q, pthread_t target_thread, void (*func)(void*), void (*callback)(void*), void (*cancel)(void*), void* arg)¶在给定队列和线程上排队 func
。一旦(以及如果)它完成执行,它将异步代理 callback
回到同一队列上的当前线程,或者如果目标线程在工作完成之前死亡,则将代理 cancel
回来。所有三个函数都将接收相同的参数 arg
。如果 func
成功排队且目标线程收到通知,则返回 1,否则返回 0。
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)¶在给定队列和线程上排队 func
。一旦(以及如果)它通过在给定的 em_proxying_ctx
上调用 emscripten_proxy_finish
完成任务,它将异步代理 callback
回到同一队列上的当前线程,或者如果目标线程在工作完成之前死亡,则将代理 cancel
回来。所有三个函数都将接收相同的参数 arg
。如果 func
成功排队且目标线程收到通知,则返回 1,否则返回 0。
此 C++ API 由 proxying.h 在使用 C++11 或更高版本编译时提供。它在命名空间 emscripten
中定义。
ProxyingQueue
¶一个围绕 em_proxying_queue*
的 C++ 薄包装器。
ProxyingCtx
¶一个围绕 em_proxying_ctx*
的 C++ 薄包装器。
execute
()¶在包装的 em_proxying_queue*
上调用 emscripten_proxy_execute_queue
。
proxyAsync
(pthread_t target, std::function<void()> &&func)¶调用 emscripten_proxy_async
来执行 func
,如果函数成功入队则返回 true
,否则返回 false
。
proxySync
(const pthread_t target, const std::function<void()> &func)¶调用 emscripten_proxy_sync
来执行 func
,如果函数成功完成则返回 true
,否则返回 false
。
proxySyncWithCtx
(const pthread_t target, const std::function<void(ProxyingCtx)> &func)¶调用 emscripten_proxy_sync_with_ctx
来执行 func
,如果函数已成功使用 emscripten_proxy_finish
或 ProxyingCtx::finish
标记完成,则返回 true
,否则返回 false
。
proxyCallback
(pthread_t target, std::function<void()> &&funcstd::function<void()> &&callbackstd::function<void()> &&cancel)¶调用 emscripten_proxy_callback
来执行 func
并调度 callback
或 cancel
,如果函数成功入队则返回 true
,否则返回 false
。
proxyCallbackWithCtx
(pthread_t target, std::function<void(ProxyingCtx)> &&func, std::function<void()> &&callbackstd::function<void()> &&cancel)¶调用 emscripten_proxy_callback_with_ctx
来执行 func
并调度 callback
或 cancel
,如果函数成功入队则返回 true
,否则返回 false
。