lua-users home
lua-l archive

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


Hi Thijs,

I was in business try last few days and it will be worst next week.
So even if I can't reply in a fast way, I'm tacking a close look on your reply :)

> From what I understand; you have a C program, which embeds Lua, and the Paho
> library. The Paho library creates a separate background OS thread for
> the async handling of incoming data.

Right :)

> So you have two OS threads that might access the Lua states simultaneously,
> which requires synchronisation.

With the code I posted, I have 2 totally separated states :
1/ the main thread, it is created in main()
2/ for the message handling thread, I have created with this code :

     eclient->L = luaL_newstate();
     luaL_openlibs(eclient->L);

So here, they are living their own life totally separated and with no interaction at all.

> If you create multiple States, and sync between them using mechanism X,
> you might as well directly use mechanism X from the Paho callbacks
> and use a single Lua state. No?

With this design, I'm not synchronizing state, I'm only exchanging data b/w them and pthread's mutex avoid concurrent access.

Bye

Laurent
 
----
The misspelling master is on the Web.
  _________ 100 % Dictionnary Free !
/                    /(
/ Dico          / / Pleins d'autres fautes sur
/________ / /
(########( / http://destroyedlolo.info
Quoi, des fautes d'orthographe! Pas possible ;-D.



Le Mardi 9 juin 2015 16h19, Thijs Schreijer <thijs@thijsschreijer.nl> a écrit :




> -----Original Message-----
> From: lua-l-bounces@lists.lua.org [mailto:lua-l-bounces@lists.lua.org] On
> Behalf Of Laurent FAILLIE
> Sent: zondag 7 juni 2015 14:55
> To: Lua mailing list
> Subject: Re: Need some help to use TFUNCTION
>
> So here I am : the full source code can be found
> https://github.com/destroyedlolo/Selene/blob/master/src/MQTT.c
>
>
> 1/ Environment creation :
>
>
> struct enhanced_client {
>     MQTTClient client;
>     lua_State *L;
>     struct _topic *subscriptions;
> };
>
> ...
>
>
>         /* Creating Lua data */
>     eclient = (struct enhanced_client *)lua_newuserdata(L, sizeof(struct
> enhanced_client));
>     luaL_getmetatable(L, "SelMQTT");
>     lua_setmetatable(L, -2);
>     eclient->subscriptions = NULL;
>     eclient->L = luaL_newstate();
>     luaL_openlibs(eclient->L);
> ...
>
>
> 2/ registering the callback
>
> ...
>
>         lua_pushstring(L, "func");    /* Argument cames from a table */
>         lua_gettable(L, -2);
>         if( lua_type(L, -1) != LUA_TFUNCTION ){
>             lua_pop(L, 1);    /* Pop the result */
>             lua_pushnil(L);
>             lua_pushstring(L, "Subscribe() : topics needs associated
> function");
>             return 2;
>         }
>         lua_xmove( L, eclient->L, 1 );    /* Move the function to the
> callback's stack */
>         func = luaL_ref(eclient->L,LUA_REGISTRYINDEX);    /* Reference the
> function in callbacks' context */
> ...
>
>
> 3/ calling the callback function
>
>
>  int msgarrived(void *actx, char *topic, int tlen, MQTTClient_message *msg){
> /* handle message arrival and call associated function.
>  * NOTE : up to now, only textual topics & messages are
>  * correctly handled (lengths are simply ignored)
>  */
>     struct enhanced_client *ctx = actx;    /* To avoid numerous cast */
>     struct _topic *tp;
>
>     for(tp = ctx->subscriptions; tp; tp = tp->next){    /* Looks for the
> corresponding function */
>         if(!strcmp(tp->topic, topic)){    /* AF : wildcard to be done */
>             lua_rawgeti( ctx->L, LUA_REGISTRYINDEX, tp->func);    /*
> retrieves the function */
>             lua_pushstring( ctx->L, topic);
>             lua_pushstring( ctx->L, msg->payload);
>             lua_pcall( ctx->L, 2, 0, 0);    /* Call Lua callback function */
>         }
>     }
>
>     MQTTClient_freeMessage(&msg);
>     MQTTClient_free(topic);
>     return 1;
> }
>
> 4/ Finally, a Lua example :
> https://github.com/destroyedlolo/Selene/blob/master/Selenites/MQTT.sel
>
> print '\nTesting broker connection'
> print '--------------------------'
>
> -- Callbacks
> function handle_tata( topic, msg )
>     print("Lua received t:'" .. topic .."' m:'".. msg .. "'\n");
> end
>
>
> function handle_toto( topic, msg )
>     print("Lua received t:'" .. topic .."' m:'".. msg .. "'\n");
> end
>
> -- Connection, subscription and finally waiting for messages
> Brk, err = SelMQTT.connect( "tcp://localhost:1883", { reliable=false  } )
> if not Brk then
>     print( err )
>     return
> end
>
> _, err = Brk:subscribe( { { topic = "/tata/#", func=handle_tata,
> qos=SelMQTT.QoSConst("QoS0") }, { topic = "/toto",func=handle_toto } } )
> if err then
>     print( err )
>     return
> end
>
> print "Hit 'enter' key to exit"
> io.stdin:read'*l'    -- wait for enter
>
> And it seems it's working pretty well.
> If I enter in another shell :
> ---
> torchwood ~ # mosquitto_pub -h torchwood.local -t '/toto' -m 'Coucou'
> ---
>
> I got
> ---
> torchwood Selene # Selenites/MQTT.sel
> Testing broker connection
> --------------------------
> Hit 'enter' key to exit
> Lua received t:'/toto' m:'Coucou'
> ---
>
> Can someone having a look and tell me if I made a mistake ?

After a quick glance; it's just single state code. If you mix (preemptive os) threads in this state, it will fail sooner or later.

From what I understand; you have a C program, which embeds Lua, and the Paho library. The Paho library creates a separate background OS thread for the async handling of incoming data. So you have two OS threads that might access the Lua states simultaneously, which requires synchronisation.

>
> Now, I'll have to work data shared b/w threads :)

Yes you have to, see remark above...

If you create multiple States, and sync between them using mechanism X, you might as well directly use mechanism X from the Paho callbacks and use a single Lua state. No?

Thijs


>
> Thanks for all.
>
> Laurent
>
> ---
> The misspelling master is on the Web.
>   _________ 100 % Dictionnary Free !
> /                 /(
> / Dico        / / Pleins d'autres fautes sur
> /________ / /
> (########( / http://destroyedlolo.info
> Quoi, des fautes d'orthographe! Pas possible ;-D.
>
>
> Le Dimanche 7 juin 2015 12h01, Laurent FAILLIE <l_faillie@yahoo.com> a écrit
> :
>
> Le Dimanche 7 juin 2015 11h15, Thijs Schreijer <thijs@thijsschreijer.nl> a
> écrit :
>
>
> > The naming of some elements in the C api is a bit misleading. Personally I
> wish that all wording with "thread"
> > would be changed to "coroutine", and the lua_State would be renamed to
> "executionstack" or something
> > more appropriate.
>
> Yes, I totally second that, it's a bit confusing, especially because Lua's
> thread aren't preemptive.
>
> Thanks for the links, I'll check them if I can't succeed with my current
> thinking;
>
> > I'm not familiar with Paho, but how is is used? Is the main loop on the C
> side and are messages passed to Lua
> > to be handled with scripting, or is the main loop on the Lua side? Does
> Paho create the new os threads?
> > Do you have control over that behaviour? Does it also generate new Lua
> states?
>
> Paho ( https://eclipse.org/paho/ ) is a messaging library implementing MQTT
> protocol, mostly associated with IoT stuffs.
> It supports several implementations : Java, C, C++ and even a native Lua
> library which is not finished up to now.
> I'm using the C implementation, which has nothing to do with Lua at all.
>
> My project is the following :
>
> - I have several daemons running in my basement server to do "smart
> housing", and monitoring several figures of my home : electricity
> consumption and production, temperature in rooms, pool, health of my
> Internet connection, and so on and so forth ...
> https://github.com/destroyedlolo/TeleInfod and
> https://github.com/destroyedlolo/Marcel are some example of such daemon.
> - Daemons and my supervision tool are exchanging data using MQTT messaging :
> the big advantage is it runs in pub/sub model so I can add / remove / modify
> any part of my network without touching the remaining.
>
> Now, I'm working now on the "home dashboard" part which will plug-in on this
> network and will display some valuables informations on a screen on my
> living room.
>
> - The main work is done in C and takes in charge all the dirty / low level
> work. This technical layer is https://github.com/destroyedlolo/Selene
> - Selene embeds Lua as end user scripting language, which will be used to
> build the final dashboard (has to be done). And to respond to your question,
> yes, messages are handled in C then passed to Lua part for end user oriented
> processing.
>
> The main advantage is a clear separation b/w the technical layers and the
> end user interface itself.
>
> - Laurent
>
>