From 4f7d3205f502db5942ae18732f7aa634a72d72b2 Mon Sep 17 00:00:00 2001 From: David Walter Seikel Date: Sat, 25 Feb 2012 06:13:18 +1000 Subject: Partial rewrite of the luaproc messages. Still not fixed yet. --- LuaSL/src/LuaSL.h | 9 +++++--- LuaSL/src/LuaSL_main.c | 10 ++++----- LuaSL/src/LuaSL_test.c | 5 +++-- LuaSL/src/LuaSL_threads.c | 52 +++++++++++++++++++++++++++++++++++++---------- LuaSL/src/LuaSL_threads.h | 2 +- 5 files changed, 56 insertions(+), 22 deletions(-) (limited to 'LuaSL/src') diff --git a/LuaSL/src/LuaSL.h b/LuaSL/src/LuaSL.h index 936477f..057788b 100644 --- a/LuaSL/src/LuaSL.h +++ b/LuaSL/src/LuaSL.h @@ -19,7 +19,8 @@ #include #include -typedef struct _script script; // Define this here, so LuaSL_threads.h can use it. +typedef struct _script script; // Define this here, so LuaSL_threads.h can use it. +typedef struct _gameGlobals gameGlobals; // Define this here, so LuaSL_threads.h can use it. #include "LuaSL_threads.h" @@ -56,7 +57,7 @@ typedef enum } boolean; #endif -typedef struct +struct _gameGlobals { Ecore_Evas *ee; // Our window. Evas *canvas; // The canvas for drawing directly onto. @@ -68,7 +69,7 @@ typedef struct const char *address; int port; boolean ui; // Wether we actually start up the UI. -} gameGlobals; +}; struct _script { @@ -84,12 +85,14 @@ struct _script int status; int args; channel chan; + Eina_Clist messages; Ecore_Con_Client *client; Ecore_Timer *timer; }; typedef struct { + Eina_Clist node; script *script; const char message[PATH_MAX]; } scriptMessage; diff --git a/LuaSL/src/LuaSL_main.c b/LuaSL/src/LuaSL_main.c index 759995b..c03a827 100644 --- a/LuaSL/src/LuaSL_main.c +++ b/LuaSL/src/LuaSL_main.c @@ -12,7 +12,7 @@ static Eina_Bool _sleep_timer_cb(void *data) gameGlobals *game = script->game; PD("Waking up %s", script->SID); - sendToChannel(script->SID, "return 0.0", NULL, NULL); + sendToChannel(game, script->SID, "return 0.0", NULL, NULL); return ECORE_CALLBACK_CANCEL; } @@ -22,7 +22,7 @@ static Eina_Bool _timer_timer_cb(void *data) gameGlobals *game = script->game; PD("Timer for %s", script->SID); - sendToChannel(script->SID, "events.timer()", NULL, NULL); + sendToChannel(game, script->SID, "events.timer()", NULL, NULL); return ECORE_CALLBACK_RENEW; } @@ -82,9 +82,9 @@ void scriptSendBack(void * data) while (isspace(*temp)) temp++; if ('1' == *temp) - sendToChannel(them->SID, "start()", NULL, NULL); + sendToChannel(game, them->SID, "start()", NULL, NULL); else - sendToChannel(them->SID, "stop()", NULL, NULL); + sendToChannel(game, them->SID, "stop()", NULL, NULL); PD("Stopped %s", them->fileName); } else @@ -191,7 +191,7 @@ static Eina_Bool _data(void *data, int type __UNUSED__, Ecore_Con_Event_Client_D { const char *status = NULL; - status = sendToChannel(SID, command, NULL, NULL); + status = sendToChannel(game, SID, command, NULL, NULL); if (status) PE("Error sending command %s to script %s : %s", command, SID, status); } diff --git a/LuaSL/src/LuaSL_test.c b/LuaSL/src/LuaSL_test.c index 1008e8f..ec76a32 100644 --- a/LuaSL/src/LuaSL_test.c +++ b/LuaSL/src/LuaSL_test.c @@ -114,16 +114,17 @@ static Eina_Bool _timer_cb(void *data) { // TODO - do it as one line, coz sendToChannel() locks up if I do them one at a time too quickly. sendForth(game, me->SID, "events.detectedKeys({\"%s\"}); events.detectedNames({\"%s\"}); events.touch_start(1)", ownerKey, ownerName); +// sendForth(game, me->SID, "events.detectedKeys({\"%s\"})", ownerKey); // sendForth(game, me->SID, "events.detectedNames({\"%s\"})", ownerName); // sendForth(game, me->SID, "events.touch_start(1)"); break; } - case 9 : + case 9+3 : { sendForth(game, me->SID, "quit()"); break; } - case 11 : + case 11+3 : { exit = TRUE; break; diff --git a/LuaSL/src/LuaSL_threads.c b/LuaSL/src/LuaSL_threads.c index d24f224..4a7397e 100644 --- a/LuaSL/src/LuaSL_threads.c +++ b/LuaSL/src/LuaSL_threads.c @@ -410,6 +410,7 @@ void newProc(const char *code, int file, script *lp) lp->args = 0; lp->chan = NULL; eina_clist_element_init(&(lp->node)); + eina_clist_init(&(lp->messages)); /* load process' code */ if (file) @@ -454,6 +455,7 @@ static void luaproc_movevalues( lua_State *Lfrom, lua_State *Lto ) { static script *luaproc_getself(lua_State *L) { script *lp; + lua_getfield(L, LUA_REGISTRYINDEX, "_SELF"); lp = (script *) lua_touserdata(L, -1); lua_pop(L, 1); @@ -503,7 +505,7 @@ static int luaproc_create_channel(lua_State *L) return 1; } -/* send a message to a lua process */ +/* send a message to the client process */ static int luaproc_send_back( lua_State *L ) { script *self; @@ -516,6 +518,7 @@ static int luaproc_send_back( lua_State *L ) { if (sm) { + eina_clist_element_init(&(sm->node)); sm->script = self; strcpy((char *) sm->message, message); ecore_main_loop_thread_safe_call_async(scriptSendBack, sm); @@ -532,18 +535,28 @@ const char *sendToChannelErrors[] = "error scheduling process" }; -// TODO - If these come in too quick, then messages might get lost. Also, in at least one case, it locked up this thread I think. - /* send a message to a lua process */ -const char *sendToChannel(const char *chname, const char *message, script **dst, channel *chn) +const char *sendToChannel(gameGlobals *game, const char *chname, const char *message, script **dst, channel *chn) { const char *result = NULL; channel chan; script *dstlp; + scriptMessage *sm = NULL; /* get exclusive access to operate on channels */ pthread_mutex_lock(&mutex_channel); + // Add the message to the queue. + if ((dstlp = eina_hash_find(game->scripts, chname))) + { + if ((sm = malloc(sizeof(scriptMessage)))) + { + sm->script = dstlp; + strcpy((char *) sm->message, message); + eina_clist_add_tail(&(sm->script->messages), &(sm->node)); + } + } + /* wait until channel is not in use */ while( ((chan = eina_hash_find(channels, chname)) != NULL) && (pthread_mutex_trylock(chan->mutex) != 0 )) { @@ -563,10 +576,19 @@ const char *sendToChannel(const char *chname, const char *message, script **dst, /* if a match is found, send the message to it and (queue) wake it */ if (dstlp != NULL) { - /* push the message onto the receivers stack */ - lua_pushstring( dstlp->L, message); + scriptMessage *msg = (scriptMessage *) eina_clist_head(&(dstlp->messages)); + // See if there's a message on the queue. Note, this may not be the same as the incoming message, if there was already a queue. + if (msg) + { + eina_clist_remove(&(msg->node)); + message = msg->message; + } + /* push the message onto the receivers stack */ + lua_pushstring(dstlp->L, message); dstlp->args = lua_gettop(dstlp->L) - 1; + if (msg) + free(msg); if (sched_queue_proc(dstlp) != LUAPROC_SCHED_QUEUE_PROC_OK) { @@ -596,10 +618,10 @@ const char *sendToChannel(const char *chname, const char *message, script **dst, static int luaproc_send( lua_State *L ) { channel chan; - script *dstlp, *self; + script *dstlp, *self = luaproc_getself(L); const char *chname = luaL_checkstring( L, 1 ); const char *message = luaL_checkstring( L, 2 ); - const char *result = sendToChannel(chname, message, &dstlp, &chan); + const char *result = sendToChannel(self->game, chname, message, &dstlp, &chan); if (result) { lua_pushnil( L ); @@ -609,8 +631,6 @@ static int luaproc_send( lua_State *L ) { if ( dstlp == NULL ) { - self = luaproc_getself( L ); - if ( self != NULL ) { self->status = LUAPROC_STAT_BLOCKED_SEND; self->chan = chan; @@ -630,6 +650,17 @@ static int luaproc_receive( lua_State *L ) { channel chan; script *srclp, *self; const char *chname = luaL_checkstring( L, 1 ); + scriptMessage *msg; + + // First check if there are queued messages, and grab one. + self = luaproc_getself(L); + if ((msg = (scriptMessage *) eina_clist_head(&(self->messages)))) + { + eina_clist_remove(&(msg->node)); + lua_pushstring(L, msg->message); + free(msg); + return lua_gettop(L) - 1; + } /* get exclusive access to operate on channels */ pthread_mutex_lock( &mutex_channel ); @@ -698,7 +729,6 @@ static int luaproc_receive( lua_State *L ) { /* otherwise (synchronous receive) simply block process */ else { - self = luaproc_getself( L ); if ( self != NULL ) { self->status = LUAPROC_STAT_BLOCKED_RECV; diff --git a/LuaSL/src/LuaSL_threads.h b/LuaSL/src/LuaSL_threads.h index b5f019b..b7f6449 100644 --- a/LuaSL/src/LuaSL_threads.h +++ b/LuaSL/src/LuaSL_threads.h @@ -53,7 +53,7 @@ void luaprocInit(void); int sched_create_worker(void); void newProc(const char *code, int file, script *lp); -const char *sendToChannel(const char *chname, const char *message, script **dst, channel *chn); +const char *sendToChannel(gameGlobals *game, const char *chname, const char *message, script **dst, channel *chn); /* join all worker threads and exit */ void sched_join_workerthreads(void); -- cgit v1.1