lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Sat, Jun 6, 2015 at 10:55 PM, Laurent FAILLIE <l_faillie@yahoo.com> wrote:
> Le Samedi 6 juin 2015 22h22, Nagaev Boris <bnagaev@gmail.com> a écrit :
>
>
>
> Thanks Boris for your reply. Searching for additional information on ideas
> you provided, I found this interesting page :
> http://lua-users.org/wiki/ThreadsTutorial
>
> First of all, but if I rewrite entirely the MQTT stack, I have to keep my
> current implementation where Paho library spawn a new C thread to handle
> incoming messages. The question now is how to get the new Lua_stat ?

Why to spawn new OS thread per incoming message? The most appealing
advantage of asynchronous networking is that you don't have to spawn
new OS thread per each incoming message. Start from this point: single
OS thread, single Lua state, multiple Lua threads. Maybe you don't
need OS threads at all.

If you should use multiple OS threads, then you can move to multiple
OS threads, multiple Lua states model. Single Lua state allows to use
global variables. For multiple Lua states you have to implement global
variables replacement yourself. See nginx's ngx.shared.DICT.

See also luajit.io [1], it looks like nginx rewritten in LuaJIT.

[1] https://github.com/kingluo/luajit.io


> - I rejected the use of lua_open() as I need access to global variables and
> I don't want to reopen each and every libraries.

To open or not to open libraries is a separate issue.

> - so let's go with lua_newthread() : as per my understanding (let me know if
> I missed anything), it will not spawn really a new thread (in system point
> of view) but "only" create a kind of forked Lua stat allowing my thread to
> live its local life but still being able to interact with global
> environment.
>
> But, as per this wiki, I'll have to create my own locking function, right ?

lua_newthread creates Lua thread (aka coroutine, green thread). Lua
thread is a part of Lua state so it can access global variables.
Remember that Lua state itself is not thread-safe, that is why
multiple Lua threads started from same Lua state must not be touched
by multiple OS threads at the same moment.

Actually, you have to implement lua_lock and lua_unlock if you really
want this, but it is bad idea, because such locking would nullify
performance advantage of multiple threads - most time is spent inside
Lua API calls which are mutually exclusive locked. In practice this
scheme can work even slower than one thread program.


> - I noticed also lua_newstate() but I wasn't able to determine if global
> variables are still accessible or not.

Global variables are not accessible.

luaL_newstate / lua_newstate create independent Lua state. Global
variables are not inherited. Nothing is inherited. They are completely
independent!


>
>
> So, all in all, my new code may looks like something like :
>
> struct _context {
>     lua_State *L;
>     ... other context stuffs, bla bla ...
> };
>
> int msgarrived(void *actx, char *topic, int tlen, MQTTClient_message *msg){
>     struct _context *ctx = (struct _context *)actx;    // to avoid zillion
> of casting
>
>     ...
>
>     lua_pushnil(ctx->L);    // push nil in the alternate Lua stack
>
>     ...
> }
>
> void myinit( lua_State *L){
>     struct _context ctx;     // in fact, it will not be a stack object, but
> it's only an example
>
>     ctx.L = lua_newthread( L);
>
>     MQTTClient_setCallbacks( client, &ctx, connlost, msgarrived, NULL);
> }
>
> Best regards,
>
> Laurent
>



-- 


Best regards,
Boris Nagaev