Home

Awesome

LuaJIT-Async

This is currently a work-in-progress.

lj-async is a library for creating LuaJIT callbacks capable of being called asynchronously. It does this by creating the callback in a different Lua state.

Callback Usage

The core component of lj-async is the callback class, exposed as lj-async.callback. It handles all the work of creating a Lua state for the callback and setting things up.

To use it, first require it by doing local CallbackFactory = require "lj-async.callback". This will return a type factory function, which will create ctypes from your function pointer types.

To create a callback ctype, call the function with the string ctype: local MyCallback_t = CallbackFactory("void(*)(int)"). Note: You MUST pass a string here; ctypes cannot be transferred between states.

Now that you've created the ctype, you can now create a callback.

function initcallback(...)
	-- can init things here
	print("init args are", ...)
	return function(n) 
		print(n) 
	end 
end
local MyCallback = MyCallback_t(initcallback,"some string",33)
local MyCallback_funcptr = MyCallback:funcptr() -- Get the actual callback
MyCallback_funcptr(123) -- Prints 123
MyCallback:free() -- Destroy the callback and the Lua state.

The passed function must be compatible with string.dump (ie. it can't have upvalues). Thus, this will not work:


local ffi = require "ffi"

...

local MyCallback = MyCallback_t(function() return function(userdata)
	userdata = ffi.cast("int[1]", userdata) -- BAD! ffi is an upvalue and not preserved by string.dump!
	...
end end)

You will have to re-require needed libraries in the function.


local ffi = require "ffi"

...

local MyCallback = MyCallback_t(function()
	local ffi = require "ffi" -- Import FFI in the new state
	return function(userdata)
	
	userdata = ffi.cast("int[1]", userdata) -- This will now work
	...
end)

Some other notes:

Threads

lj-async also provides threads, built on top of the callback objects. The module is lj-async.thread.

The API is:

Synchronization

local Mutex = require "lj-async.mutex" local mut = Mutex() mut:lock() mut:unlock()