Skip to content

Make Lua generic over Send #539

Open
@coderedart

Description

@coderedart

Problem

most apps/games have the concept of a main-thread, where a lu it will often hold onto thread-local objects (which must be created and destroyed on main-thread) like opengl buffers/textures or skia-like library objects or UI objects like widgets/windows/event loop.

At the same time, off-thread lua scripts are often Send and can be used in async contexts (eg: loading assets from filesystem).

The current mlua feature send makes you choose one or the other. If you enable send, you can't use it for main-thread. If you don't enable send, you can't use it for async off-thread work.

Solution

It doesn't have to be done this way, but there's an obvious solution.

Just make Lua (and all associated objects like UserData) generic over MSend and only implement Lua: Send if MSend: Send.

// unit implements send. and most UserData would probably be send, so it's a good default. 
struct Lua<T = ()> {
  ..,
  _data: std::marker::PhantomData<T>
}
pub type LuaUnSend = Lua<*const ()>;
pub type UserDataUnSend = UserData<*const ()>;

// thread-unsafe objects will only impl UserDataUnSend 
impl UserDataUnSend for OpenGLTexture { }

// thread-safe objects will remain generic, as they can work in same thread or cross thread cases.
impl<T> UserData<T> for MyNormalObject {}

It will add some complexity, but, now, users can create thread-unsafe lua instances on main-thread (or render thread or whatever), as well as thread-safe lua instances for off-thread/async work.

WorkArounds

Just accept the unsoundness, and impl Send for thread-unsafe objects. Just pray that you don't accidentally send/share the main-thread lua instance with off-threads.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions