root/src/modules/lua.c

Revision fda4621228eace5666578fde08eceae320d9100b, 20.2 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 6 years ago)

maybe? refs #47. This won't trigger on Linux for me, so valgrind is no help.

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  */
5
6 #include "noit_defines.h"
7
8 #include "noit_conf.h"
9 #include "noit_module.h"
10 #include "noit_check.h"
11 #include "noit_check_tools.h"
12 #include "utils/noit_log.h"
13 #include "lua_noit.h"
14
15 #ifdef HAVE_ALLOCA_H
16 #include <alloca.h>
17 #endif
18 #include <assert.h>
19
20 static noit_log_stream_t nlerr = NULL;
21 static noit_log_stream_t nldeb = NULL;
22 static noit_hash_table noit_coros = NOIT_HASH_EMPTY;
23
24 struct loader_conf {
25   char *script_dir;
26 };
27 static struct loader_conf *__get_loader_conf(noit_module_loader_t *self) {
28   struct loader_conf *c;
29   c = noit_image_get_userdata(&self->hdr);
30   if(!c) {
31     c = calloc(1, sizeof(*c));
32     noit_image_set_userdata(&self->hdr, c);
33   }
34   return c;
35 }
36 static void
37 noit_lua_loader_set_directory(noit_module_loader_t *self, char *dir) {
38   struct loader_conf *c = __get_loader_conf(self);
39   if(c->script_dir) free(c->script_dir);
40   c->script_dir = strdup(dir);
41 }
42 static const char *
43 noit_lua_loader_get_directory(noit_module_loader_t *self) {
44   struct loader_conf *c = __get_loader_conf(self);
45   return c->script_dir;
46 }
47
48 noit_lua_check_info_t *
49 get_ci(lua_State *L) {
50   noit_lua_check_info_t *v = NULL;
51   if(noit_hash_retrieve(&noit_coros, (const char *)&L, sizeof(L), (void **)&v)) {
52     return v;
53   }
54   return NULL;
55 }
56 static void
57 int_cl_free(void *vcl) {
58   free(vcl);
59 }
60
61 static void
62 noit_event_dispose(void *ev) {
63   int mask;
64   eventer_t *value = ev;
65   eventer_t removed, e = *value;
66   noitL(nldeb, "lua check cleanup: dropping (%p)->fd (%d)\n", e, e->fd);
67   if(e->mask & (EVENTER_READ|EVENTER_WRITE|EVENTER_EXCEPTION)) {
68     noitL(nldeb, "    closing down fd %d\n", e->fd);
69     e->opset->close(e->fd, &mask, e);
70   }
71   removed = eventer_remove(e);
72   noitL(nldeb, "    remove from eventer system %s\n",
73         removed ? "succeeded" : "failed");
74   if(e->closure) {
75     struct nl_generic_cl *cl;
76     cl = e->closure;
77     if(cl->free) cl->free(cl);
78   }
79   eventer_free(e);
80   free(ev);
81 }
82 void
83 noit_lua_check_register_event(noit_lua_check_info_t *ci, eventer_t e) {
84   eventer_t *eptr;
85   eptr = calloc(1, sizeof(*eptr));
86   memcpy(eptr, &e, sizeof(*eptr));
87   if(!ci->events) ci->events = calloc(1, sizeof(*ci->events));
88   assert(noit_hash_store(ci->events, (const char *)eptr, sizeof(*eptr), eptr));
89 }
90 void
91 noit_lua_check_deregister_event(noit_lua_check_info_t *ci, eventer_t e,
92                                 int tofree) {
93   assert(ci->events);
94   assert(noit_hash_delete(ci->events, (const char *)&e, sizeof(e),
95                           NULL, tofree ? noit_event_dispose : free));
96 }
97 void
98 noit_lua_check_clean_events(noit_lua_check_info_t *ci) {
99   noit_hash_destroy(ci->events, NULL, noit_event_dispose);
100   free(ci->events);
101   ci->events = NULL;
102 }
103
104 static void
105 noit_lua_pushmodule(lua_State *L, const char *m) {
106   int stack_pos = LUA_GLOBALSINDEX;
107   char *copy, *part, *brkt;
108   copy = alloca(strlen(m)+1);
109   assert(copy);
110   memcpy(copy,m,strlen(m)+1);
111
112   for(part = strtok_r(copy, ".", &brkt);
113       part;
114       part = strtok_r(NULL, ".", &brkt)) {
115     lua_getfield(L, stack_pos, part);
116     if(stack_pos == -1) lua_remove(L, -2);
117     else stack_pos = -1;
118   }
119 }
120 static void
121 noit_lua_hash_to_table(lua_State *L,
122                        noit_hash_table *t) {
123   noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
124   const char *key, *value;
125   int klen;
126   lua_createtable(L, 0, t ? t->size : 0);
127   if(t) {
128     while(noit_hash_next(t, &iter, &key, &klen, (void **)&value)) {
129       lua_pushlstring(L, value, strlen(value));
130       lua_setfield(L, -2, key);
131     }
132   }
133   return;
134 }
135 static int
136 noit_module_index_func(lua_State *L) {
137   int n;
138   n = lua_gettop(L);    /* number of arguments */
139   assert(n == 2);
140   if(!luaL_checkudata(L, 1, "noit_module_t")) {
141     luaL_error(L, "metatable error, arg1 not a noit_module_t!");
142   }
143   return 0;
144 }
145 static int
146 noit_lua_set_available(lua_State *L) {
147   noit_check_t *check;
148   noit_lua_check_info_t *ci;
149   if(lua_gettop(L)) luaL_error(L, "wrong number of arguments");
150   check = lua_touserdata(L, lua_upvalueindex(1));
151   ci = check->closure;
152   ci->current.available = lua_tointeger(L, lua_upvalueindex(2));
153   return 0;
154 }
155 static int
156 noit_lua_set_state(lua_State *L) {
157   noit_check_t *check;
158   noit_lua_check_info_t *ci;
159   if(lua_gettop(L)) luaL_error(L, "wrong number of arguments");
160   check = lua_touserdata(L, lua_upvalueindex(1));
161   ci = check->closure;
162   ci->current.state = lua_tointeger(L, lua_upvalueindex(2));
163   return 0;
164 }
165 static int
166 noit_lua_set_status(lua_State *L) {
167   noit_check_t *check;
168   noit_lua_check_info_t *ci;
169   if(lua_gettop(L) != 1) luaL_error(L, "wrong number of arguments");
170   check = lua_touserdata(L, lua_upvalueindex(1));
171   ci = check->closure;
172   /* strdup here... but free later */
173   if(ci->current.status) free(ci->current.status);
174   ci->current.status = strdup(lua_tostring(L, 1));
175   return 0;
176 }
177 static int
178 noit_lua_set_metric(lua_State *L) {
179   noit_check_t *check;
180   noit_lua_check_info_t *ci;
181   const char *metric_name;
182   metric_type_t metric_type;
183
184   double __n;
185   int32_t __i;
186   u_int32_t __I;
187   int64_t __l;
188   u_int64_t __L;
189
190   if(lua_gettop(L) != 2) luaL_error(L, "wrong number of arguments");
191   check = lua_touserdata(L, lua_upvalueindex(1));
192   ci = check->closure;
193   if(!lua_isstring(L, 1)) luaL_error(L, "argument #1 must be a string");
194   metric_name = lua_tostring(L, 1);
195   metric_type = lua_tointeger(L, lua_upvalueindex(2));
196   if(lua_isnil(L, 2)) {
197     noit_stats_set_metric(&ci->current, metric_name, metric_type, NULL);
198     return 0;
199   }
200   switch(metric_type) {
201     case METRIC_GUESS:
202     case METRIC_STRING:
203       noit_stats_set_metric(&ci->current, metric_name, metric_type,
204                             (void *)lua_tostring(L, 2));
205       break;
206     case METRIC_INT32:
207       __i = luaL_optinteger(L, 2, 0);
208       noit_stats_set_metric(&ci->current, metric_name, metric_type, &__i);
209       break;
210     case METRIC_UINT32:
211       __I = luaL_optinteger(L, 2, 0);
212       noit_stats_set_metric(&ci->current, metric_name, metric_type, &__I);
213       break;
214     case METRIC_INT64:
215       __l = luaL_optinteger(L, 2, 0);
216       noit_stats_set_metric(&ci->current, metric_name, metric_type, &__l);
217       break;
218     case METRIC_UINT64:
219       __L = luaL_optinteger(L, 2, 0);
220       noit_stats_set_metric(&ci->current, metric_name, metric_type, &__L);
221       break;
222     case METRIC_DOUBLE:
223       __n = luaL_optnumber(L, 2, 0);
224       noit_stats_set_metric(&ci->current, metric_name, metric_type, &__n);
225       break;
226   }
227   return 0;
228 }
229 static int
230 noit_check_index_func(lua_State *L) {
231   int n;
232   const char *k;
233   noit_check_t **udata, *check;
234   n = lua_gettop(L);    /* number of arguments */
235   assert(n == 2);
236   if(!luaL_checkudata(L, 1, "noit_check_t")) {
237     luaL_error(L, "metatable error, arg1 not a noit_check_t!");
238   }
239   udata = lua_touserdata(L, 1);
240   check = *udata;
241   if(!lua_isstring(L, 2)) {
242     luaL_error(L, "metatable error, arg2 not a string!");
243   }
244   k = lua_tostring(L, 2);
245   switch(*k) {
246     case 'a':
247       if(!strcmp(k, "available")) {
248         lua_pushlightuserdata(L, check);
249         lua_pushinteger(L, NP_AVAILABLE);
250         lua_pushcclosure(L, noit_lua_set_available, 2);
251       }
252       else break;
253       return 1;
254     case 'b':
255       if(!strcmp(k, "bad")) {
256         lua_pushlightuserdata(L, check);
257         lua_pushinteger(L, NP_BAD);
258         lua_pushcclosure(L, noit_lua_set_state, 2);
259       }
260       else break;
261       return 1;
262     case 'c':
263       if(!strcmp(k, "config")) noit_lua_hash_to_table(L, check->config);
264       else break;
265       return 1;
266     case 'g':
267       if(!strcmp(k, "good")) {
268         lua_pushlightuserdata(L, check);
269         lua_pushinteger(L, NP_GOOD);
270         lua_pushcclosure(L, noit_lua_set_state, 2);
271       }
272       else break;
273       return 1;
274     case 'm':
275       if(!strcmp(k, "module")) lua_pushstring(L, check->module);
276
277 #define IF_METRIC_BLOCK(name,type) \
278       if(!strcmp(k, name)) { \
279         lua_pushlightuserdata(L, check); \
280         lua_pushinteger(L, type); \
281         lua_pushcclosure(L, noit_lua_set_metric, 2); \
282       }
283
284       else IF_METRIC_BLOCK("metric", METRIC_GUESS)
285       else IF_METRIC_BLOCK("metric_string", METRIC_STRING)
286       else IF_METRIC_BLOCK("metric_int32", METRIC_INT32)
287       else IF_METRIC_BLOCK("metric_uint32", METRIC_UINT32)
288       else IF_METRIC_BLOCK("metric_int64", METRIC_INT64)
289       else IF_METRIC_BLOCK("metric_uint64", METRIC_UINT64)
290       else IF_METRIC_BLOCK("metric_double", METRIC_DOUBLE)
291       else break;
292       return 1;
293     case 'n':
294       if(!strcmp(k, "name")) lua_pushstring(L, check->name);
295       else break;
296       return 1;
297     case 'p':
298       if(!strcmp(k, "period")) lua_pushinteger(L, check->period);
299       else break;
300       return 1;
301     case 's':
302       if(!strcmp(k, "status")) {
303         lua_pushlightuserdata(L, check);
304         lua_pushcclosure(L, noit_lua_set_status, 1);
305       }
306       else break;
307       return 1;
308     case 't':
309       if(!strcmp(k, "target")) lua_pushstring(L, check->target);
310       else if(!strcmp(k, "timeout")) lua_pushinteger(L, check->timeout);
311       else break;
312       return 1;
313     case 'u':
314       if(!strcmp(k, "unavailable")) {
315         lua_pushlightuserdata(L, check);
316         lua_pushinteger(L, NP_UNAVAILABLE);
317         lua_pushcclosure(L, noit_lua_set_available, 2);
318       }
319       else break;
320       return 1;
321     default:
322       break;
323   }
324   luaL_error(L, "noit_check_t no such element: %s", k);
325   return 0;
326 }
327 static void
328 noit_lua_setup_module(lua_State *L,
329                       noit_module_t *mod) {
330   noit_module_t **addr;
331   addr = (noit_module_t **)lua_newuserdata(L, sizeof(mod));
332   *addr = mod;
333   if(luaL_newmetatable(L, "noit_module_t") == 1) {
334     lua_pushcclosure(L, noit_module_index_func, 0);
335     lua_setfield(L, -2, "__index");
336   }
337   lua_setmetatable(L, -2);
338 }
339 static void
340 noit_lua_setup_check(lua_State *L,
341                      noit_check_t *check) {
342   noit_check_t **addr;
343   addr = (noit_check_t **)lua_newuserdata(L, sizeof(check));
344   *addr = check;
345   if(luaL_newmetatable(L, "noit_check_t") == 1) {
346     lua_pushcclosure(L, noit_check_index_func, 0);
347     lua_setfield(L, -2, "__index");
348   }
349   lua_setmetatable(L, -2);
350 }
351 static int
352 noit_lua_module_onload(noit_image_t *i) {
353   int rv;
354   lua_State *L;
355   lua_module_closure_t *lmc;
356
357   lmc = noit_image_get_userdata(i);
358   L = lmc->lua_state;
359   lua_getglobal(L, "require");
360   lua_pushstring(L, lmc->object);
361   rv = lua_pcall(L, 1, 1, 0);
362   if(rv) {
363     int i;
364     noitL(nlerr, "lua: %s.onload failed\n", lmc->object);
365     i = lua_gettop(L);
366     if(i>0) {
367       if(lua_isstring(L, i)) {
368         const char *err;
369         size_t len;
370         err = lua_tolstring(L, i, &len);
371         noitL(nlerr, "lua: %s\n", err);
372       }
373     }
374     lua_pop(L,i);
375     return -1;
376   }
377   lua_pop(L, lua_gettop(L));
378
379   noit_lua_pushmodule(L, lmc->object);
380   if(lua_isnil(L, -1)) {
381     lua_pop(L, 1);
382     noitL(nlerr, "lua: no such object %s\n", lmc->object);
383     return -1;
384   }
385   lua_getfield(L, -1, "onload");
386   lua_remove(L, -2);
387   if(!lua_isfunction(L, -1)) {
388     lua_pop(L, 1);
389     /* No onload */
390     return 0;
391   }
392   noit_lua_setup_module(L, (noit_module_t *)i);
393   lua_pcall(L, 1, 1, 0);
394   if(lua_isnumber(L, -1)) {
395     int rv;
396     rv = lua_tointeger(L, -1);
397     lua_pop(L, 1);
398     return rv;
399   }
400   lua_pop(L,1);
401   noitL(nlerr, "%s.onload must return a integer\n", lmc->object);
402   return -1;
403 }
404 #define LMC_DECL(L, mod) \
405   lua_State *L; \
406   lua_module_closure_t *lmc; \
407   lmc = noit_module_get_userdata(mod); \
408   L = lmc->lua_state
409 #define SETUP_CALL(L, func, failure) do { \
410   noit_lua_pushmodule(L, lmc->object); \
411   lua_getfield(L, -1, func); \
412   lua_remove(L, -2); \
413   if(!lua_isfunction(L, -1)) { \
414     lua_pop(L, 1); \
415     failure; \
416   } \
417 } while(0)
418 #define RETURN_INT(L, func) do { \
419   int base = lua_gettop(L); \
420   assert(base == 1); \
421   if(lua_isnumber(L, -1)) { \
422     int rv; \
423     rv = lua_tointeger(L, -1); \
424     lua_pop(L, 1); \
425     return rv; \
426   } \
427   lua_pop(L,1); \
428   noitL(nlerr, "%s.%s must return a integer\n", lmc->object, func); \
429 } while(0)
430
431 static int
432 noit_lua_module_config(noit_module_t *mod,
433                        noit_hash_table *options) {
434   LMC_DECL(L, mod);
435   SETUP_CALL(L, "config", return 0);
436
437   noit_lua_setup_module(L, mod);
438   noit_lua_hash_to_table(L, options);
439   lua_pcall(L, 2, 1, 0);
440
441   RETURN_INT(L, "config");
442   return -1;
443 }
444 static int
445 noit_lua_module_init(noit_module_t *mod) {
446   LMC_DECL(L, mod);
447   SETUP_CALL(L, "init", return 0);
448
449   noit_lua_setup_module(L, mod);
450   lua_pcall(L, 1, 1, 0);
451
452   RETURN_INT(L, "init");
453   return -1;
454 }
455 static void
456 noit_lua_module_cleanup(noit_module_t *mod, noit_check_t *check) {
457   noit_lua_check_info_t *ci = check->closure;
458   LMC_DECL(L, mod);
459   SETUP_CALL(L, "cleanup", goto clean);
460
461   noit_lua_setup_module(L, mod);
462   noit_lua_setup_check(L, check);
463   lua_pcall(L, 2, 0, 0);
464
465  clean:
466   if(ci) {
467     noit_lua_check_clean_events(ci);
468     free(ci);
469     check->closure = NULL;
470   }
471 }
472
473 /* Here is where the magic starts */
474 static void
475 noit_lua_log_results(noit_module_t *self, noit_check_t *check) {
476   noit_lua_check_info_t *ci = check->closure;
477   struct timeval duration;
478   u_int32_t duration_ms;
479
480   gettimeofday(&ci->finish_time, NULL);
481   sub_timeval(ci->finish_time, check->last_fire_time, &duration);
482
483   memcpy(&ci->current.whence, &ci->finish_time, sizeof(ci->current.whence));
484   ci->current.duration = duration.tv_sec * 1000 + duration.tv_usec / 1000;
485   duration_ms = ci->current.duration;
486
487   noit_check_set_stats(self, check, &ci->current);
488   free(ci->current.status);
489 }
490 int
491 noit_lua_yield(noit_lua_check_info_t *ci, int nargs) {
492   noitL(nldeb, "lua: %p yielding\n", ci->coro_state);
493   return lua_yield(ci->coro_state, nargs);
494 }
495 int
496 noit_lua_resume(noit_lua_check_info_t *ci, int nargs) {
497   int result, base;
498   noit_check_t *check;
499   check = ci->check;
500
501   noitL(nldeb, "lua: %p resuming\n", ci->coro_state);
502   result = lua_resume(ci->coro_state, nargs);
503   switch(result) {
504     case 0: /* success */
505       break;
506     case LUA_YIELD: /* The complicated case */
507       /* The person yielding had better setup an event
508        * to wake up the coro...
509        */
510       lua_gc(ci->lmc->lua_state, LUA_GCCOLLECT, 0);
511       goto done;
512     default: /* Errors */
513       noitL(nlerr, "lua resume returned: %d\n", result);
514       ci->current.status = strdup(ci->timed_out ? "timeout" : "unknown error");
515       ci->current.available = NP_UNAVAILABLE;
516       ci->current.state = NP_BAD;
517       base = lua_gettop(ci->coro_state);
518       if(base>0) {
519         if(lua_isstring(ci->coro_state, base)) {
520           const char *err;
521           err = lua_tostring(ci->coro_state, base);
522           if(err) {
523             free(ci->current.status);
524             ci->current.status = (char *)err;
525           }
526         }
527       }
528       break;
529   }
530   lua_getglobal(ci->lmc->lua_state, "noit_coros");
531   luaL_unref(ci->lmc->lua_state, -1, ci->coro_state_ref);
532   lua_pop(ci->lmc->lua_state, 1);
533   lua_gc(ci->lmc->lua_state, LUA_GCCOLLECT, 0);
534
535   noit_lua_log_results(ci->self, ci->check);
536   noit_lua_module_cleanup(ci->self, ci->check);
537   ci = NULL; /* we freed it... explode if someone uses it before we return */
538   check->flags &= ~NP_RUNNING;
539
540  done:
541   return result;
542 }
543 static int
544 noit_lua_check_timeout(eventer_t e, int mask, void *closure,
545                        struct timeval *now) {
546   noit_check_t *check;
547   struct nl_intcl *int_cl = closure;
548   noit_lua_check_info_t *ci = int_cl->ci;
549   check = ci->check;
550   noitL(nldeb, "lua: %p ->check_timeout\n", ci->coro_state);
551   ci->timed_out = 1;
552   noit_lua_check_deregister_event(ci, e, 0);
553   if(ci->coro_state) {
554     /* Our coro is still "in-flight". To fix this we will unreference
555      * it, garbage collect it and then ensure that it failes a resume
556      */
557     lua_getglobal(ci->lmc->lua_state, "noit_coros");
558     luaL_unref(ci->lmc->lua_state, -1, ci->coro_state_ref);
559     lua_pop(ci->lmc->lua_state, 1);
560     lua_gc(ci->lmc->lua_state, LUA_GCCOLLECT, 0);
561     assert(2 == noit_lua_resume(ci, 0));
562   } else {
563     noit_lua_log_results(ci->self, ci->check);
564     noit_lua_module_cleanup(ci->self, ci->check);
565     check->flags &= ~NP_RUNNING;
566   }
567   if(int_cl->free) int_cl->free(int_cl);
568   return 0;
569 }
570 static int
571 noit_lua_initiate(noit_module_t *self, noit_check_t *check) {
572   lua_State **coro_state_copy;
573   LMC_DECL(L, self);
574   struct nl_intcl *int_cl;
575   noit_lua_check_info_t *ci;
576   struct timeval p_int, __now;
577   eventer_t e;
578
579   if(!check->closure) check->closure = calloc(1, sizeof(noit_lua_check_info_t));
580   ci = check->closure;
581
582   /* We cannot be running */
583   assert(!(check->flags & NP_RUNNING));
584   check->flags |= NP_RUNNING;
585
586   ci->self = self;
587   ci->check = check;
588   noit_check_stats_clear(&ci->current);
589
590   gettimeofday(&__now, NULL);
591   memcpy(&check->last_fire_time, &__now, sizeof(__now));
592
593   e = eventer_alloc();
594   e->mask = EVENTER_TIMER;
595   e->callback = noit_lua_check_timeout;
596   /* We wrap this in an alloc so we can blindly free it later */
597   int_cl = calloc(1, sizeof(*int_cl));
598   int_cl->ci = ci;
599   int_cl->free = int_cl_free;
600   e->closure = int_cl;
601   memcpy(&e->whence, &__now, sizeof(__now));
602   p_int.tv_sec = check->timeout / 1000;
603   p_int.tv_usec = (check->timeout % 1000) * 1000;
604   add_timeval(e->whence, p_int, &e->whence);
605   noit_lua_check_register_event(ci, e);
606   eventer_add(e);
607
608   noitL(nldeb, "initiate gettop => %d\n", lua_gettop(L));
609   ci->lmc = lmc;
610   lua_getglobal(L, "noit_coros");
611   ci->coro_state = lua_newthread(L);
612   ci->coro_state_ref = luaL_ref(L, -2);
613   lua_pop(L, 1); /* pops noit_coros */
614
615   coro_state_copy = malloc(sizeof(*coro_state_copy));
616   *coro_state_copy = ci->coro_state;
617   noit_hash_replace(&noit_coros,
618                   (const char *)coro_state_copy, sizeof(*coro_state_copy),
619                   ci, free, NULL);
620
621   SETUP_CALL(ci->coro_state, "initiate", goto fail);
622   noit_lua_setup_module(ci->coro_state, ci->self);
623   noit_lua_setup_check(ci->coro_state, ci->check);
624   noit_lua_resume(ci, 2);
625
626   return 0;
627
628  fail:
629   noit_lua_log_results(ci->self, ci->check);
630   noit_lua_module_cleanup(ci->self, ci->check);
631   check->flags &= ~NP_RUNNING;
632   return -1;
633 }
634 /* This is the standard wrapper */
635 static int
636 noit_lua_module_initiate_check(noit_module_t *self, noit_check_t *check,
637                                int once, noit_check_t *cause) {
638   if(!check->closure) check->closure = calloc(1, sizeof(noit_lua_check_info_t));
639   INITIATE_CHECK(noit_lua_initiate, self, check);
640   return 0;
641 }
642 static noit_module_t *
643 noit_lua_loader_load(noit_module_loader_t *loader,
644                      char *module_name,
645                      noit_conf_section_t section) {
646   noit_module_t *m;
647   lua_State *L;
648   lua_module_closure_t *lmc;
649   char *object;
650  
651   noitL(nldeb, "Loading lua module: %s\n", module_name);
652   if(noit_conf_get_string(section, "@object", &object) == 0) {
653     noitL(nlerr, "Lua module %s require object attribute.\n", module_name);
654     return NULL;
655   }
656
657   m = noit_blank_module();
658   m->hdr.magic = NOIT_MODULE_MAGIC;
659   m->hdr.version = NOIT_MODULE_ABI_VERSION;
660   m->hdr.name = strdup(module_name);
661   m->hdr.description = strdup("Lua module");
662   m->hdr.onload = noit_lua_module_onload;
663   lmc = calloc(1, sizeof(*lmc));
664   lmc->object = object;
665
666   L = lmc->lua_state = lua_open();
667
668
669   lua_gc(L, LUA_GCSTOP, 0);  /* stop collector during initialization */
670   luaL_openlibs(L);  /* open libraries */
671   luaopen_noit(L);
672   lua_newtable(L);
673   lua_setglobal(L, "noit_coros");
674
675   lua_getfield(L, LUA_GLOBALSINDEX, "package");
676   lua_pushfstring(L, "%s", noit_lua_loader_get_directory(loader));
677   lua_setfield(L, -2, "path");
678   lua_pop(L, 1);
679
680   lua_gc(L, LUA_GCRESTART, 0);
681
682   noit_image_set_userdata(&m->hdr, lmc);
683   if(m->hdr.onload(&m->hdr) == -1) {
684     free(m->hdr.name);
685     free(m->hdr.description);
686     free(lmc->object);
687     free(lmc);
688     /* FIXME: We leak the opaque_handler in the module here... */
689     free(m);
690     return NULL;
691   }
692
693   m->config = noit_lua_module_config;
694   m->init = noit_lua_module_init;
695   m->initiate_check = noit_lua_module_initiate_check;
696   m->cleanup = noit_lua_module_cleanup;
697
698   noit_register_module(m);
699   return m;
700 }
701
702 static int
703 noit_lua_loader_config(noit_module_loader_t *self, noit_hash_table *o) {
704   char *dir = ".";
705   noit_hash_retrieve(o, "directory", strlen("directory"), (void **)&dir);
706   noit_lua_loader_set_directory(self, dir);
707   return 0;
708 }
709 static int
710 noit_lua_loader_onload(noit_image_t *self) {
711   nlerr = noit_log_stream_find("error/serf");
712   nldeb = noit_log_stream_find("debug/serf");
713   if(!nlerr) nlerr = noit_stderr;
714   if(!nldeb) nldeb = noit_debug;
715   return 0;
716 }
717
718 noit_module_loader_t lua = {
719   {
720     NOIT_LOADER_MAGIC,
721     NOIT_LOADER_ABI_VERSION,
722     "lua",
723     "Lua check loader",
724     noit_lua_loader_onload,
725   },
726   noit_lua_loader_config,
727   NULL,
728   noit_lua_loader_load
729 };
Note: See TracBrowser for help on using the browser.