Depends on the implementation. In our implementation threads are limited to 1 and there is 1 state. This way all of that is avoided.
However I am sure you are more interested on a multihreading model.
And as discussed in the other thread, there came up some models like state per map or thread etc.
It has been said that state per thread (at least) is the only sane way of handling multiple threads with lua.
With the current model of having the object pool it is per state.
This is problematic in a multithreaded situation if the invalidation model is kept the same, as multiple objects try to delete themselves from all lua states at random times.
The cure for that would be the second model I told earlier in this thread where we would invalidate all pointers on every top level hook call ending.
The way I have been imagining a threaded environment is a state per map, one global state.
States can send messages to eachother through locked queue with functions implemented. it would trigger the messages when the map updates are halted, when world update runs.
The data model would be as we use now, having an object pool of pushed objects in lua (this seems to be preferred, memory saving way among implementations and posts I have seen & read)
However, instead of invalidating objects when they are deleted, the earlier posted model of data invalidation at top level hook would be used to make pointers not crash. This will ofcourse force reinstanting the userdata on every hook call.
It would be better in my mind not to worry about invalid pointers and instead worry about invalid code as I noted in my earlier post.
In that model states can communicate safely, there is GC of lua userdatas, safety of pointers is as decided, the threads wont mess up eachother’s environments.
However. It does, for safety, limit all global functions and hooks, that for example get a player from another map, to the global state.
And it most likely requires certain functions to be coded to help maintain thread safety.
Lets say you want to send a message to everyone in the world, instantly.
There could be a function that calls a function for all players, in a locked loop.
local function printname(player)
print(player:GetName())
end
DoForPlayers(printname)
While this could be unsafe if abused, it could be alright in my mind so there is not much disabled functionality.
However I would also consider maybe for starters forcing global loops like that to be fired on the global state, which is always safe to use.
In that case there could be a function coded for the state messaging that allows functions to be called on the global state like this:
– global state code
function on_state_message(mapid, instanceid, msg)
dostring(msg)
end
RegisterServerEvent(ON_STATE_MESSAGE, on_state_message)
– some other state code
local msg = [[
for k,v in ipairs(GetPlayersInWorld()) do
print(v:GetName())
end
]]
SendStateMessage(-1, -1, msg)
With lua it is possible to pass around any value basically (number, string, table, function) from a lua state to lua state.
I coded that in an addon of mine, however as Eluna was using lua 5.2, I was not able to get the functions working and not sure if that is ultimately possible yet.
https://github.com/Rochet2/AIO
Yes, it is. Im unsure how they exactly intended it to be used. We dont use that though.
It has been said that implementing locks there is not enough. There are some, maybe obvious, problems in using a single lua state in a multithreaded environment even with locks implemented.
Thanks for that.
This is exactly why I agree with dfighter on the pointer management.
And why I would consider of not having a system at all to handle dead pointers.
Probably need to remove the current system in that light then : /
Might try to work on the other model.
ps. So long. Just so long …