Приветствую! (далее длинный пост)
Есть некоторая тестовая утилита, которая расширяется луашечкой. В луа импортируются нужные функции/таблицы и далее есть определенная функция уже в самом скрипте, которая запускается после загрузки этого скрипта.
то есть что-то типа
function main(args)
--- тут все, что нужно
end
Все просто сделали load скрипту и выполнили main.
Так же есть события, которые приходят из другого потока и несут нужную инфу.
Хочу протянуть возможность регистрации/обработки этих событий.
Совершенно понятно, что дернуть какой-то вызов из другого потока в том же lua_State, в котором исполняется вызов main я не могу. Поэтому я создаю другой lua_State, от главного event_state = lua_newthread(main_state)
и, делаю вызовы уже в нем. Пример скрипта
function handler( data )
--- тут обработка события
end
function main( args )
client.subscribe("on_data_ready", handler) -- тут подписка на событие
end
И это работает! Событие приходит, исполняется в своем lua_State и, казалось бы, ничего не падает. Но что-то тут не так, потому как main_state и event_state делят глобальные объекты и, стало быть должны как-то это разруливать.
Второй момент - это передача параметров с подпиской на событие. Например
function handler( data, param ) -- param тут {"Hello!", "blabla"}
--- тут обработка события
end
function main( args )
-- тут подписка на событие с доп параметром
client.subscribe("on_data_ready", handler, {"Hello!", "blabla"})
end
параметры я сохраняю как референсы через LUA_REGISTRYINDEX и потом передаю их при вызове обработчика в назначенную функцию. И снова вопрос в том, что LUA_REGISTRYINDEX это одна таблица, и стало быть, ее нужно как-то лочить.
+ у меня есть есть возможность отследить наступление события в event_state из main_state и прочитать, что вернула function handler
, опять же через референсы. Стало быть если я в событии делаю return reslut1, reslut2, reslut3
и потом сохраняю их в LUA_REGISTRYINDEX, а в этот момент main_state делает подписку на другое событие и параметры тоже сохраняет в LUA_REGISTRYINDEX, то будет не весело и все навернется.
Собственно в этом вопрос. Как такое c lua делать правильно? И можно ли вообще такое делать с lua? Если нужно как-то лочить таблицы, то нужно ли это делать в _каждом вызове_, который потенциально может быть дернут из 2 разных потоков?