aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/LuaSL/LuaSL_main.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2014-05-23 13:22:36 +1000
committerDavid Walter Seikel2014-05-23 13:22:36 +1000
commitf97c73bd1e43a0eb32ad8dc43fc28f6e40b28f38 (patch)
treedf45770acc4a26d56e45bc7ae3420cddb6522d15 /src/LuaSL/LuaSL_main.c
parentTODO-- (diff)
downloadSledjHamr-f97c73bd1e43a0eb32ad8dc43fc28f6e40b28f38.zip
SledjHamr-f97c73bd1e43a0eb32ad8dc43fc28f6e40b28f38.tar.gz
SledjHamr-f97c73bd1e43a0eb32ad8dc43fc28f6e40b28f38.tar.bz2
SledjHamr-f97c73bd1e43a0eb32ad8dc43fc28f6e40b28f38.tar.xz
Rewrite the LuaSL script running stuff (twice lol), plus much related tweakage and cleanups.
Diffstat (limited to 'src/LuaSL/LuaSL_main.c')
-rw-r--r--src/LuaSL/LuaSL_main.c248
1 files changed, 103 insertions, 145 deletions
diff --git a/src/LuaSL/LuaSL_main.c b/src/LuaSL/LuaSL_main.c
index 2c40348..e60278f 100644
--- a/src/LuaSL/LuaSL_main.c
+++ b/src/LuaSL/LuaSL_main.c
@@ -1,31 +1,27 @@
1 1
2#include "LuaSL.h" 2#include "LuaSL.h"
3#include "Runnr.h"
4#include "SledjHamr.h" 3#include "SledjHamr.h"
5 4
6 5
7int logDom = -1; // Our logging domain. 6int logDom = -1; // Our logging domain.
8static int CPUs = 4;
9static Eina_Strbuf *clientStream; 7static Eina_Strbuf *clientStream;
10 8
11 9
12static Eina_Bool _sleep_timer_cb(void *data) 10static Eina_Bool _sleep_timer_cb(void *data)
13{ 11{
14 script *script = data; 12 script *script = data;
15 gameGlobals *ourGlobals = script->game;
16 13
17// PD("Waking up %s", script->name); 14// PD("Waking up %s", script->name);
18 sendToChannel(ourGlobals, script->SID, "return 0.0"); 15 send2script(script->SID, "return 0.0");
19 return ECORE_CALLBACK_CANCEL; 16 return ECORE_CALLBACK_CANCEL;
20} 17}
21 18
22static Eina_Bool _timer_timer_cb(void *data) 19static Eina_Bool _timer_timer_cb(void *data)
23{ 20{
24 script *script = data; 21 script *script = data;
25 gameGlobals *ourGlobals = script->game;
26 22
27 PD("Timer for %s", script->name); 23// PD("Timer for %s", script->name);
28 sendToChannel(ourGlobals, script->SID, "events.timer()"); 24 send2script(script->SID, "events.timer()");
29 return ECORE_CALLBACK_RENEW; 25 return ECORE_CALLBACK_RENEW;
30} 26}
31 27
@@ -44,88 +40,63 @@ static script *findThem(gameGlobals *ourGlobals, const char *base, const char *t
44 return eina_hash_find(ourGlobals->names, name); 40 return eina_hash_find(ourGlobals->names, name);
45} 41}
46 42
47static void resetScript(script *victim) 43void send2server(script *me, const char *message)
48{ 44{
49 gameGlobals *ourGlobals = victim->game; 45 gameGlobals *ourGlobals = me->data;
50 script *me;
51 char buf[PATH_MAX];
52
53// PD("RESETTING %s", victim->name);
54 sendToChannel(ourGlobals, victim->SID, "quit()");
55
56 eina_hash_del(ourGlobals->scripts, victim->SID, NULL);
57 eina_hash_del(ourGlobals->names, victim->fileName, NULL);
58
59 // The old one will eventually die, create a new one.
60 me = calloc(1, sizeof(script));
61 gettimeofday(&me->startTime, NULL);
62 strncpy(me->SID, victim->SID, sizeof(me->SID));
63 strncpy(me->fileName, victim->fileName, sizeof(me->fileName));
64 me->name = &me->fileName[strlen(prefix_data_get())];
65 me->game = ourGlobals;
66 me->client = victim->client;
67 eina_hash_add(ourGlobals->scripts, me->SID, me);
68 eina_hash_add(ourGlobals->names, me->fileName, me);
69 sprintf(buf, "%s.lua.out", me->fileName);
70 newProc(buf, TRUE, me);
71}
72
73void scriptSendBack(void * data)
74{
75 scriptMessage *message = data;
76 gameGlobals *ourGlobals = message->script->game;
77 46
78 if (!message->script) 47//printf("GOT MESSAGE from script %s - '%s'\n", me->name, message);
79 {
80 PE("scriptSendBack script is NULL");
81 return;
82 }
83 48
84 if (0 == strncmp(message->message, "llSleep(", 8)) 49 if (0 == strncmp(message, "llSleep(", 8))
85 ecore_timer_add(atof(&(message->message)[8]), _sleep_timer_cb, message->script); 50 ecore_timer_add(atof(&(message)[8]), _sleep_timer_cb, me);
86 else if (0 == strncmp(message->message, "llResetTime(", 12)) 51 else if (0 == strncmp(message, "llResetTime(", 12))
87 { 52 {
88 gettimeofday(&message->script->startTime, NULL); 53 takeScript(me);
54 gettimeofday(&me->startTime, NULL);
55 releaseScript(me);
89 } 56 }
90 else if (0 == strncmp(message->message, "llGetTime(", 10)) 57 else if (0 == strncmp(message, "llGetTime(", 10))
91 { 58 {
92 struct timeval now; 59 struct timeval now;
93 float time = timeDiff(&now, &message->script->startTime); 60 float time = timeDiff(&now, &me->startTime);
94 char result[128]; 61 char result[128];
95 62
96 snprintf(result, sizeof(result), "return %f", time); 63 snprintf(result, sizeof(result), "return %f", time);
97 sendToChannel(ourGlobals, message->script->SID, result); 64 send2script(me->SID, result);
98 } 65 }
99 else if (0 == strncmp(message->message, "llGetAndResetTime(", 18)) 66 else if (0 == strncmp(message, "llGetAndResetTime(", 18))
100 { 67 {
101 struct timeval now; 68 struct timeval now;
102 float time = timeDiff(&now, &message->script->startTime); 69 float time = timeDiff(&now, &me->startTime);
103 char result[128]; 70 char result[128];
104 71
72 takeScript(me);
105 // Reset it before doing anything else once the result is known. 73 // Reset it before doing anything else once the result is known.
106 gettimeofday(&message->script->startTime, NULL); 74 gettimeofday(&me->startTime, NULL);
75 releaseScript(me);
107 snprintf(result, sizeof(result), "return %f", time); 76 snprintf(result, sizeof(result), "return %f", time);
108 sendToChannel(ourGlobals, message->script->SID, result); 77 send2script(me->SID, result);
109 } 78 }
110 else if (0 == strncmp(message->message, "llSetTimerEvent(", 16)) 79 else if (0 == strncmp(message, "llSetTimerEvent(", 16))
111 { 80 {
112 message->script->timerTime = atof(&(message->message)[16]); 81 takeScript(me);
113 if (0.0 == message->script->timerTime) 82 me->timerTime = atof(&(message)[16]);
83 if (0.0 == me->timerTime)
114 { 84 {
115 if (message->script->timer) 85 if (me->timer)
116 ecore_timer_del(message->script->timer); 86 ecore_timer_del(me->timer);
117 message->script->timer = NULL; 87 me->timer = NULL;
118 } 88 }
119 else 89 else
120 message->script->timer = ecore_timer_add(message->script->timerTime, _timer_timer_cb, message->script); 90 me->timer = ecore_timer_add(me->timerTime, _timer_timer_cb, me);
91 releaseScript(me);
121 } 92 }
122 else if (0 == strncmp(message->message, "llSetScriptState(", 17)) 93 else if (0 == strncmp(message, "llSetScriptState(", 17))
123 { 94 {
124 script *them; 95 script *them;
125 96
126 if ((them = findThem(ourGlobals, message->script->fileName, &(message->message[18])))) 97 if ((them = findThem(ourGlobals, me->fileName, &(message[18]))))
127 { 98 {
128 char *temp = rindex(&(message->message[18]), ','); 99 char *temp = rindex(&(message[18]), ',');
129 100
130 if (temp) 101 if (temp)
131 { 102 {
@@ -133,9 +104,9 @@ void scriptSendBack(void * data)
133 while (isspace(*temp)) 104 while (isspace(*temp))
134 temp++; 105 temp++;
135 if ('1' == *temp) 106 if ('1' == *temp)
136 sendToChannel(ourGlobals, them->SID, "start()"); 107 send2script(them->SID, "start()");
137 else 108 else
138 sendToChannel(ourGlobals, them->SID, "stop()"); 109 send2script(them->SID, "stop()");
139// PD("Stopped %s", them->name); 110// PD("Stopped %s", them->name);
140 } 111 }
141 else 112 else
@@ -143,25 +114,34 @@ void scriptSendBack(void * data)
143 } 114 }
144 else 115 else
145 { 116 {
146 char *temp = rindex(&(message->message[18]), '"'); 117 char *temp = rindex(&(message[18]), '"');
147 118
148 if (temp) 119 if (temp)
149 *temp = '\0'; 120 *temp = '\0';
150 PE("Can't stop script, can't find %s", &(message->message[18])); 121 PE("Can't stop script, can't find %s", &(message[18]));
151 } 122 }
152 } 123 }
153 else if (0 == strncmp(message->message, "llResetOtherScript(", 19)) 124 else if (0 == strncmp(message, "llResetOtherScript(", 19))
154 { 125 {
155 script *them; 126 script *them;
156 127
157 if ((them = findThem(ourGlobals, message->script->fileName, &(message->message[20])))) 128 if ((them = findThem(ourGlobals, me->fileName, &(message[20]))))
129 {
130 PD("RESETTING OTHER %s", them->name);
158 resetScript(them); 131 resetScript(them);
132 }
133 }
134 else if (0 == strncmp(message, "llResetScript(", 14))
135 {
136 PD("RESETTING %s", me->name);
137 resetScript(me);
159 } 138 }
160 else if (0 == strncmp(message->message, "llResetScript(", 14))
161 resetScript(message->script);
162 else 139 else
163 sendBack(message->script->client, message->script->SID, message->message); 140 {
164 free(message); 141 takeScript(me);
142 sendBack(me->client, me->SID, message);
143 releaseScript(me);
144 }
165} 145}
166 146
167static Eina_Bool _add(void *data, int type __UNUSED__, Ecore_Con_Event_Client_Add *ev) 147static Eina_Bool _add(void *data, int type __UNUSED__, Ecore_Con_Event_Client_Add *ev)
@@ -170,6 +150,25 @@ static Eina_Bool _add(void *data, int type __UNUSED__, Ecore_Con_Event_Client_Ad
170 return ECORE_CALLBACK_RENEW; 150 return ECORE_CALLBACK_RENEW;
171} 151}
172 152
153static void _compileCb(LuaCompiler *compiler)
154{
155 if (0 == compiler->bugCount)
156 {
157 gameGlobals *ourGlobals = compiler->data;
158 script *me = scriptAdd(compiler->file, compiler->SID, send2server, ourGlobals);
159
160 me->client = compiler->client;
161 eina_hash_add(ourGlobals->names, me->fileName, me);
162 sendBack(compiler->client, compiler->SID, "compiled(true)");
163 }
164 else
165 sendBack(compiler->client, compiler->SID, "compiled(false)");
166 free(compiler->luaName);
167 free(compiler->SID);
168 free(compiler->file);
169 free(compiler);
170}
171
173static Eina_Bool _data(void *data, int type __UNUSED__, Ecore_Con_Event_Client_Data *ev) 172static Eina_Bool _data(void *data, int type __UNUSED__, Ecore_Con_Event_Client_Data *ev)
174{ 173{
175 gameGlobals *ourGlobals = data; 174 gameGlobals *ourGlobals = data;
@@ -197,6 +196,7 @@ static Eina_Bool _data(void *data, int type __UNUSED__, Ecore_Con_Event_Client_D
197 char *temp; 196 char *temp;
198 char *file; 197 char *file;
199 char *name; 198 char *name;
199 LuaCompiler *compiler = calloc(1, sizeof(LuaCompiler));
200 200
201 strcpy(buf, &command[8]); 201 strcpy(buf, &command[8]);
202 temp = buf; 202 temp = buf;
@@ -207,34 +207,27 @@ static Eina_Bool _data(void *data, int type __UNUSED__, Ecore_Con_Event_Client_D
207 207
208 name = &file[strlen(prefix_data_get())]; 208 name = &file[strlen(prefix_data_get())];
209 PD("Compiling %s, %s.", SID, name); 209 PD("Compiling %s, %s.", SID, name);
210 if (compileLSL(ourGlobals, ev->client, SID, file, FALSE)) 210 compiler->file = strdup(file);
211 compiler->SID = strdup(SID);
212 compiler->client = ev->client;
213 compiler->data = ourGlobals;
214 compiler->cb = _compileCb;
215 if (!compileLSL(compiler, ourGlobals, ev->client, SID, file, FALSE))
211 { 216 {
212 script *me = calloc(1, sizeof(script)); 217 compiler->bugCount++;
213 218 PE("Compile of %s failed in a mysterious way.", file);
214 gettimeofday(&me->startTime, NULL); 219 _compileCb(compiler);
215 strncpy(me->SID, SID, sizeof(me->SID));
216 strncpy(me->fileName, file, sizeof(me->fileName));
217 me->name = &me->fileName[strlen(prefix_data_get())];
218 me->game = ourGlobals;
219 me->client = ev->client;
220 eina_hash_add(ourGlobals->scripts, me->SID, me);
221 eina_hash_add(ourGlobals->names, me->fileName, me);
222 sendBack(ev->client, SID, "compiled(true)");
223 } 220 }
224 else
225 sendBack(ev->client, SID, "compiled(false)");
226 } 221 }
227 else if (0 == strcmp(command, "run()")) 222 else if (0 == strcmp(command, "run()"))
228 { 223 {
229 script *me; 224 script *me;
230 char buf[PATH_MAX];
231 225
232 me = eina_hash_find(ourGlobals->scripts, SID); 226 me = getScript(SID);
233 if (me) 227 if (me)
234 { 228 {
235 sprintf(buf, "%s.lua.out", me->fileName); 229 runScript(me);
236 gettimeofday(&me->startTime, NULL); 230 releaseScript(me);
237 newProc(buf, TRUE, me);
238 } 231 }
239 } 232 }
240 else if (0 == strcmp(command, "exit()")) 233 else if (0 == strcmp(command, "exit()"))
@@ -243,13 +236,7 @@ static Eina_Bool _data(void *data, int type __UNUSED__, Ecore_Con_Event_Client_D
243 ecore_main_loop_quit(); 236 ecore_main_loop_quit();
244 } 237 }
245 else 238 else
246 { 239 send2script(SID, command);
247 const char *status = NULL;
248
249 status = sendToChannel(ourGlobals, SID, command);
250 if (status)
251 PE("Error sending command %s to script %s : %s", command, SID, status);
252 }
253 } 240 }
254 241
255 // Get the next blob to check it. 242 // Get the next blob to check it.
@@ -272,6 +259,12 @@ static Eina_Bool _del(void *data, int type __UNUSED__, Ecore_Con_Event_Client_De
272 return ECORE_CALLBACK_RENEW; 259 return ECORE_CALLBACK_RENEW;
273} 260}
274 261
262//static Eina_Bool _statusTimer(void *data)
263//{
264// printScriptsStatus();
265// return ECORE_CALLBACK_RENEW;
266//}
267
275int main(int argc, char **argv) 268int main(int argc, char **argv)
276{ 269{
277 gameGlobals ourGlobals; 270 gameGlobals ourGlobals;
@@ -284,7 +277,6 @@ int main(int argc, char **argv)
284 if (eina_init()) 277 if (eina_init())
285 { 278 {
286 logDom = HamrTime(argv[0], main, logDom); 279 logDom = HamrTime(argv[0], main, logDom);
287 ourGlobals.scripts = eina_hash_string_superfast_new(NULL);
288 ourGlobals.names = eina_hash_string_superfast_new(NULL); 280 ourGlobals.names = eina_hash_string_superfast_new(NULL);
289 if (ecore_init()) 281 if (ecore_init())
290 { 282 {
@@ -292,7 +284,7 @@ int main(int argc, char **argv)
292 { 284 {
293 if ((ourGlobals.server = ecore_con_server_add(ECORE_CON_REMOTE_TCP, ourGlobals.address, ourGlobals.port, &ourGlobals))) 285 if ((ourGlobals.server = ecore_con_server_add(ECORE_CON_REMOTE_TCP, ourGlobals.address, ourGlobals.port, &ourGlobals)))
294 { 286 {
295 int i; 287// int i;
296 Eina_Iterator *scripts; 288 Eina_Iterator *scripts;
297 script *me; 289 script *me;
298 290
@@ -307,29 +299,20 @@ int main(int argc, char **argv)
307 299
308 result = 0; 300 result = 0;
309 compilerSetup(&ourGlobals); 301 compilerSetup(&ourGlobals);
310 luaprocInit(); 302
311 for (i = 0; i < CPUs; i++) 303// ecore_timer_add(3.0, _statusTimer, &ourGlobals);
312 { 304
313 if ( sched_create_worker( ) != LUAPROC_SCHED_OK )
314 PE("Error creating luaproc worker thread.");
315 }
316 ecore_main_loop_begin(); 305 ecore_main_loop_begin();
317 PD("Fell out of the main loop."); 306 PD("Fell out of the main loop.");
318 307
319 scripts = eina_hash_iterator_data_new(ourGlobals.scripts); 308 scripts = eina_hash_iterator_data_new(ourGlobals.names);
320 while(eina_iterator_next(scripts, (void **) &me)) 309 while(eina_iterator_next(scripts, (void **) &me))
321 { 310 {
322 const char *status = NULL; 311 if (me->SID[0])
323 312 send2script(me->SID, "quit()");
324 status = sendToChannel(&ourGlobals, me->SID, "quit()");
325 if (status)
326 PE("Error sending command quit() to script %s : %s", me->SID, status);
327 } 313 }
328 314
329 PD("Finished quitting scripts."); 315 PD("Finished quitting scripts.");
330 // TODO - This is what hangs the system, should change from raw pthreads to ecore threads.
331 // Or perhaps just run the main loop for a bit longer so all the scripts can quit?
332 sched_join_workerthreads();
333 } 316 }
334 else 317 else
335 PC("Failed to add server!"); 318 PC("Failed to add server!");
@@ -424,33 +407,6 @@ _elua_custom_panic(lua_State *L) // Stack usage [-0, +0, m]
424 return 0; 407 return 0;
425} 408}
426 409
427static void
428_edje_lua2_error_full(const char *file, const char *fnc, int line,
429 lua_State *L, int err_code) // Stack usage [-0, +0, m]
430{
431 const char *err_type;
432
433 switch (err_code)
434 {
435 case LUA_ERRRUN:
436 err_type = "runtime";
437 break;
438 case LUA_ERRSYNTAX:
439 err_type = "syntax";
440 break;
441 case LUA_ERRMEM:
442 err_type = "memory allocation";
443 break;
444 case LUA_ERRERR:
445 err_type = "error handler";
446 break;
447 default:
448 err_type = "unknown";
449 break;
450 }
451 printf("Lua %s error: %s\n", err_type, lua_tostring(L, -1)); // Stack usage [-0, +0, m]
452}
453
454static int errFunc(lua_State *L) 410static int errFunc(lua_State *L)
455{ 411{
456 int i = 0; 412 int i = 0;
@@ -510,7 +466,8 @@ void runLuaFile(gameGlobals *ourGlobals, const char *filename)
510 * Watchdog thread. 466 * Watchdog thread.
511 * 467 *
512 * It's easy enough to have a watchdog thread wake up every now and then to check if any given Lua state has been hogging it's CPU for too long. 468 * It's easy enough to have a watchdog thread wake up every now and then to check if any given Lua state has been hogging it's CPU for too long.
513 * The hard part is forcing Lua states to yield cleanly, without slowing performance too much. 469 * The hard part is forcing Lua states to yield cleanly, without slowing performance too much. On the other hand, it might be valid to just
470 * kill CPU hogs and tell the user.
514 * 471 *
515 * Identifying scripts. - OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs 472 * Identifying scripts. - OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
516 * 473 *
@@ -650,7 +607,8 @@ void runLuaFile(gameGlobals *ourGlobals, const char *filename)
650 * Oops, names can have directory slashes in them. lol 607 * Oops, names can have directory slashes in them. lol
651 * On the other hand, sim objects CAN have the same name. 608 * On the other hand, sim objects CAN have the same name.
652 * 609 *
653 * So we got sim directories, with an objects directory inside it, with object directories inside that. The object directories have object files in them. This is all like the test setup that is here. 610 * So we got sim directories, with an objects directory inside it, with object directories inside that. The object directories have object files in them.
611 * This is all like the test setup that is here.
654 * We need metadata. Sim metadata, object metadata, and object contents metadata. That can be done with a "foo.omg" file at each level. 612 * We need metadata. Sim metadata, object metadata, and object contents metadata. That can be done with a "foo.omg" file at each level.
655 * sim/index.omg - the list of object name.UUIDs, their X,Y,Z location, size, and rotation. 613 * sim/index.omg - the list of object name.UUIDs, their X,Y,Z location, size, and rotation.
656 * sim/objects/objectName_UUID/index.omg - the list of contents names, item UUIDs, asset UUIDs, and types. 614 * sim/objects/objectName_UUID/index.omg - the list of contents names, item UUIDs, asset UUIDs, and types.
@@ -763,7 +721,7 @@ void runLuaFile(gameGlobals *ourGlobals, const char *filename)
763 * 721 *
764 * Serialise the script state, send it somewhere. 722 * Serialise the script state, send it somewhere.
765 * 723 *
766 * Lua can generally serialise itself as as a string of code to be executed at the destination. There might be some C side state that needs to be take care of as well. We shall see. 724 * Lua can generally serialise itself as a string of code to be executed at the destination. There might be some C side state that needs to be take care of as well. We shall see.
767 * 725 *
768 * Email, HTTP, XML-RPC? 726 * Email, HTTP, XML-RPC?
769 * 727 *