I'm not sure if this works properly, but it appears to. I haven't tested it extremely thoroughly.
[i]Azuisleet has enlightened me and I realize now this will crash eventually if the timing is right. Read his posts below. You can still view the source code because I think it's interesting anyway.[/i]
LuaThreadLib is an extremely small library of functions that lets you operate on lua from threads other than the main one. It works by manually suspending the main Garrysmod thread (yeah I know) so that it doesn't corrupt the stack. As long as you leave the stack the way it was, there should (theoretically) be no problems.
LuaThreadLib.h : [url]http://pastebin.com/cxtkSaqL[/url]
LuaThreadLib.cpp : [url]http://pastebin.com/iLwbN5TN[/url]
Example:
[cpp]
#include <GMLuaModule.h>
#include "LuaThreadLib.h"
#include "time.h"
GMOD_MODULE(Init, Shutdown);
ILuaInterface* gLua;
DWORD WINAPI tp(LPVOID param) {
while (true) {
Sleep(rand() % 4000);
LuaThreadLib::AcquireLock();
gLua->Push(gLua->GetGlobal("print"));
gLua->Push("hi");
gLua->Call(1, 0);
LuaThreadLib::ReleaseLock();
}
return 0;
}
int Init(lua_State* L) {
gLua = Lua();
srand(time(0));
LuaThreadLib::UpdateThread();
for (int i = 0; i < 5; i++) {
DWORD ThreadID;
CreateThread(NULL, NULL, &tp, NULL, NULL, &ThreadID);
}
return 0;
}
int Shutdown(lua_State* L) {
LuaThreadLib::Cleanup();
return 0;
}
[/cpp]
This will print "hi" in the console from a different thread every [random number between 0 and 3999] milliseconds in 5 different threads. If anybody sees any problems, please say so, and like I said, this is not proven to work perfectly; it might or might not work, so I submit it to your inspection and experimentation.
[editline]2nd December 2010[/editline]
Actually I already see a flaw in this when many threads are waiting to get the lock (two see that the bool is false at the same time) so I'll post the new code when (if) I fix it.
[editline]2nd December 2010[/editline]
Should be fixed now. Also note that this example will crash when you disconnect because the threads are still running, but this is just a proof of concept.
i have done something likewise a while ago for a scriptenforcer bypass a while ago, but it seemed to crash 20% of the time for me.
We've discussed this a bit, and it's pretty clear this isn't safe at all. Just suspending the main thread isn't helpful, because of the fact that lua isn't thread safe to begin with. The main thread can be suspended on any number of lua_ functions or another function manipulating ILuaInterface. When your outside function operates on the state, it can unbalance the stack etc, and the main thread will resume with the unbalanced stack and crash.
That's why it's necessary to have a hook in the main thread, whether it's a per-frame hook or something, so you can either notify the thread that it can operate, or poll a result from the other thread.
You of course know far more than me and I will agree with you that it won't work simply because you are Azuisleet, and therefore have a very high probability of being right about this type of thing. However, I will ask a few questions so that I can further understand why it won't work.
I always thought thread safe meant that multiple threads could operate on something without messing it up. And since lua is not thread safe, I assume that inside gmod, only one thread will ever use the lua interface, which is the thread that will be executing the module's init function.
If the above is incorrect then this next part is erroneous, but, if you halt the main thread and operate on lua from a different thread, this means that only one at a time is doing something with lua. Won't this be fine?
Also as for the stack, if you happen to pause the main thread in the middle of pushing arguments or something and you push something on the stack, but afterwards remove it so that the stack is left as it was before, would the main thread have any idea that you did anything?
I'm not well versed in the internals of lua, forgive my ignorance.
When you say "we discussed this a bit" was that you and garry, and did you already think of this?
Posted from my phone, so may contain auto-incorrect errors.
[QUOTE=yakahughes;26453769]When you say "we discussed this a bit" was that you and garry, and did you already think of this?[/QUOTE]
Secret Luahelp.
[QUOTE=yakahughes;26453769]I assume that inside gmod, only one thread will ever use the lua interface, which is the thread that will be executing the module's init function.[/quote]
To better explain this, I'll go over in general what the CPU does. Each thread will execute a bunch of instructions, and then yield when the thread's time span is up, allowing other threads to execute on the CPU. Say we have two threads "Main" and "LuaHack." The main thread is in the middle of pushing an argument onto the stack, it's not an atomic operation, and so if it's halted in the middle, it isn't safe for LuaHack to touch the lua_State.
This has a lot to do with atomic operations and mutexes, which I don't feel like explaining, so you should probably look into them. The proper way to serialize access to the lua state is with locks around functions that access it.
Ah, so being a non-atomic operation, it is possible for things to be "half pushed" so to speak (I assume). And pushing something when something else is half pushed will result in a corruption. Ok thanks, I'll update the OP later to reflect the non-safety of it.
Do not try and multi thread something that is shared with other threads unless you have access to make it multithreadable through atomics and mutexes. If you multithread a shared piece of memory without protection, you will get data races and shit will go down.
Also using multiple lua states will have no benefit if all you are doing is calling engine functions. You could however get a significant boost on doing lua only algorithms that are expensive.
[QUOTE=haza55;26469559] lua only algorithms that are expensive.[/QUOTE]
If you wanted to test that, you could use my GML-based Simplex Noise module, that was expensive as hell.
Link: [url]http://www.facepunch.com/threads/834088-Simplex-Noise-Module?highlight=[/url]
Sorry, you need to Log In to post a reply to this thread.