Skip to main content

GlContextExecutor

Trait GlContextExecutor 

Source
pub trait GlContextExecutor:
    Send
    + Sync
    + 'static {
    // Required method
    fn execute(
        &self,
        target_ctx: usize,
        task: Box<dyn FnOnce() + Send + 'static>,
    );
}
Expand description

Host-supplied scheduler that posts a closure onto the thread that owns a particular OpenGL context.

§Why this exists

GLuint deletion (glDeleteSemaphoresEXT, glDeleteTextures, etc.) MUST run on a thread where the owning GL context is current — the GL namespace is thread-local and a delete dispatched against a foreign or null context is rejected as GL_INVALID_OPERATION. An interop layer’s GL bridges produce GL-side objects whose Drop may run on arbitrary threads in finalizer-driven hosts (JNI / .NET / GC-managed wrappers): producer-side Arc<dyn SyncWaiter> keep-alives, retained imports and process-wide producer-identity caches all hold strong references that are routinely released by threads with no GL context current.

Without an executor, those Drops can only queue the GL name onto a pending-delete bucket that is drained when:

  • any thread that currently holds the matching GL context current reaches one of the GL-side bridge entry points (an opportunistic drain), or
  • the host explicitly asks the interop layer to prune its GL bridge objects from a thread that holds the matching context current.

Hosts whose pipeline cannot guarantee either path (e.g. a shutdown flow where the bridge layer has already stopped accepting work but the language-runtime GC keeps releasing the parked Arcs) should implement this trait and register an instance with the interop layer. Once registered, off-thread Drops for that context are routed through the executor and run on the GL-owning thread directly.

§Contract

execute(target_ctx, task) MUST eventually run task on a thread where the GL context identified by target_ctx is current. The implementation is allowed to:

  • drop the closure unrun if the GL context is being torn down (the namespace dies with the context, so any leaked GL name is reclaimed); the only consequence is a small bump in the deferred- delete bucket until the next bridge call drains it.
  • run the closure synchronously when the calling thread already holds the right context current. The closure does not depend on any state outside its capture.

target_ctx is the raw EGLContext / HGLRC / CGLContextObj cast to usize. Hosts running a single GL thread can ignore the argument and post unconditionally; multi-context hosts use it to route to the correct thread/queue.

Required Methods§

Source

fn execute(&self, target_ctx: usize, task: Box<dyn FnOnce() + Send + 'static>)

Schedule task to run on the GL-owning thread for the context identified by target_ctx. See trait docs for the contract.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§