diff options
| author | moteus <mimir@newmail.ru> | 2013-12-26 15:34:58 +0400 |
|---|---|---|
| committer | moteus <mimir@newmail.ru> | 2013-12-26 15:34:58 +0400 |
| commit | 5982fd74baad6cdee2c536203afe6c435a2d02e9 (patch) | |
| tree | e8b7e667ab4160ad95e9409bc7bd826e69fbc9ff | |
| parent | 92ec624951de2d344b28eb5262a3534822f6d6a7 (diff) | |
| download | lua-llthreads2-5982fd74baad6cdee2c536203afe6c435a2d02e9.tar.gz lua-llthreads2-5982fd74baad6cdee2c536203afe6c435a2d02e9.tar.bz2 lua-llthreads2-5982fd74baad6cdee2c536203afe6c435a2d02e9.zip | |
Add. set_logger function allow logging errors (crash Lua VM) in current llthread's threads.
``` Lua
local llthreads = require "llthreads"
local LOG = require"log".new(
require "log.writer.net.zmq".new("tcp://127.0.0.1:5555")
)
llthread.set_logger(function(msg) LOG.error(msg) end)
```
| -rw-r--r-- | README.md | 20 | ||||
| -rw-r--r-- | src/llthread.c | 43 |
2 files changed, 54 insertions, 9 deletions
| @@ -15,6 +15,26 @@ This is full dropin replacement for [llthreads](https://github.com/Neopallium/lu | |||
| 15 | ##Additional | 15 | ##Additional |
| 16 | * thread:join() method support zero timeout to check if thread alive | 16 | * thread:join() method support zero timeout to check if thread alive |
| 17 | * thread:join() method support arbitrary timeout on Windows platform | 17 | * thread:join() method support arbitrary timeout on Windows platform |
| 18 | * set_logger function allow logging errors (crash Lua VM) in current llthread's threads | ||
| 18 | 19 | ||
| 19 | [](https://bitdeli.com/free "Bitdeli Badge") | 20 | [](https://bitdeli.com/free "Bitdeli Badge") |
| 20 | 21 | ||
| 22 | |||
| 23 | ##Usage | ||
| 24 | |||
| 25 | ### Use custom logger | ||
| 26 | In this example I use [lua-log](https://github.com/moteus/lua-log) library. | ||
| 27 | ``` Lua | ||
| 28 | -- This is child thread. | ||
| 29 | local llthreads = require "llthreads" | ||
| 30 | -- Send logs using ZMQ | ||
| 31 | local LOG = require"log".new( | ||
| 32 | require "log.writer.net.zmq".new("tcp://127.0.0.1:5555") | ||
| 33 | ) | ||
| 34 | llthread.set_logger(function(msg) LOG.error(msg) end) | ||
| 35 | |||
| 36 | ... | ||
| 37 | |||
| 38 | -- This error with traceback will be passed to logger | ||
| 39 | error("SOME ERROR") | ||
| 40 | ``` | ||
diff --git a/src/llthread.c b/src/llthread.c index 0f43e14..0596b2a 100644 --- a/src/llthread.c +++ b/src/llthread.c | |||
| @@ -62,6 +62,10 @@ typedef pthread_t os_thread_t; | |||
| 62 | 62 | ||
| 63 | LLTHREADS_EXPORT_API int luaopen_llthreads(lua_State *L); | 63 | LLTHREADS_EXPORT_API int luaopen_llthreads(lua_State *L); |
| 64 | 64 | ||
| 65 | #define LLTHREAD_T_NAME "LLThread" | ||
| 66 | static const char *LLTHREAD_T = LLTHREAD_T_NAME; | ||
| 67 | static const char *LLTHREAD_LOGGER_HOLDER = LLTHREAD_T_NAME " logger holder"; | ||
| 68 | |||
| 65 | //{ traceback | 69 | //{ traceback |
| 66 | 70 | ||
| 67 | #define ERROR_LEN 1024 | 71 | #define ERROR_LEN 1024 |
| @@ -308,6 +312,26 @@ typedef struct llthread_t { | |||
| 308 | flags_t flags; | 312 | flags_t flags; |
| 309 | } llthread_t; | 313 | } llthread_t; |
| 310 | 314 | ||
| 315 | //{ logger interface | ||
| 316 | void llthread_log(lua_State *L, const char *hdr, const char *msg){ | ||
| 317 | int top = lua_gettop(L); | ||
| 318 | lua_rawgetp(L, LUA_REGISTRYINDEX, LLTHREAD_LOGGER_HOLDER); | ||
| 319 | if(lua_isnil(L, -1)){ | ||
| 320 | lua_pop(L, 1); | ||
| 321 | fputs(hdr, stderr); | ||
| 322 | fputs(msg, stderr); | ||
| 323 | fputc('\n', stderr); | ||
| 324 | fflush(stderr); | ||
| 325 | return; | ||
| 326 | } | ||
| 327 | lua_pushstring(L, hdr); | ||
| 328 | lua_pushstring(L, msg); | ||
| 329 | lua_concat(L, 2); | ||
| 330 | lua_pcall(L, 1, 0, 0); | ||
| 331 | lua_settop(L, top); | ||
| 332 | } | ||
| 333 | //} | ||
| 334 | |||
| 311 | //{ llthread_child | 335 | //{ llthread_child |
| 312 | 336 | ||
| 313 | static void open_thread_libs(lua_State *L){ | 337 | static void open_thread_libs(lua_State *L){ |
| @@ -369,9 +393,7 @@ static OS_THREAD_RETURT llthread_child_thread_run(void *arg) { | |||
| 369 | 393 | ||
| 370 | /* alwasy print errors here, helps with debugging bad code. */ | 394 | /* alwasy print errors here, helps with debugging bad code. */ |
| 371 | if(this->status != 0) { | 395 | if(this->status != 0) { |
| 372 | const char *err_msg = lua_tostring(L, -1); | 396 | llthread_log(L, "Error from thread: ", lua_tostring(L, -1)); |
| 373 | fprintf(stderr, "Error from thread: %s\n", err_msg); | ||
| 374 | fflush(stderr); | ||
| 375 | } | 397 | } |
| 376 | 398 | ||
| 377 | /* if thread is detached, then destroy the child state. */ | 399 | /* if thread is detached, then destroy the child state. */ |
| @@ -543,9 +565,6 @@ static llthread_t *llthread_create(lua_State *L, const char *code, size_t code_l | |||
| 543 | 565 | ||
| 544 | //{ Lua interface to llthread | 566 | //{ Lua interface to llthread |
| 545 | 567 | ||
| 546 | #define LLTHREAD_T_NAME "LLThread" | ||
| 547 | static const char *LLTHREAD_T = LLTHREAD_T_NAME; | ||
| 548 | |||
| 549 | static llthread_t *l_llthread_at (lua_State *L, int i) { | 568 | static llthread_t *l_llthread_at (lua_State *L, int i) { |
| 550 | llthread_t **this = (llthread_t **)lutil_checkudatap (L, i, LLTHREAD_T); | 569 | llthread_t **this = (llthread_t **)lutil_checkudatap (L, i, LLTHREAD_T); |
| 551 | luaL_argcheck (L, this != NULL, i, "thread expected"); | 570 | luaL_argcheck (L, this != NULL, i, "thread expected"); |
| @@ -571,9 +590,7 @@ static int l_llthread_delete(lua_State *L) { | |||
| 571 | llthread_child_t *child = this->child; | 590 | llthread_child_t *child = this->child; |
| 572 | llthread_join(this, INFINITE_JOIN_TIMEOUT); | 591 | llthread_join(this, INFINITE_JOIN_TIMEOUT); |
| 573 | if(child && child->status != 0) { | 592 | if(child && child->status != 0) { |
| 574 | const char *err_msg = lua_tostring(child->L, -1); | 593 | llthread_log(child->L, "Error from non-joined thread: ", lua_tostring(child->L, -1)); |
| 575 | fprintf(stderr, "Error from non-joined thread: %s\n", err_msg); | ||
| 576 | fflush(stderr); | ||
| 577 | } | 594 | } |
| 578 | } | 595 | } |
| 579 | 596 | ||
| @@ -678,8 +695,16 @@ static const struct luaL_Reg l_llthread_meth[] = { | |||
| 678 | 695 | ||
| 679 | //} | 696 | //} |
| 680 | 697 | ||
| 698 | static int l_llthread_set_logger(lua_State *L){ | ||
| 699 | lua_settop(L, 1); | ||
| 700 | luaL_argcheck(L, lua_isfunction(L, 1), 1, "function expected"); | ||
| 701 | lua_rawsetp(L, LUA_REGISTRYINDEX, LLTHREAD_LOGGER_HOLDER); | ||
| 702 | return 0; | ||
| 703 | } | ||
| 704 | |||
| 681 | static const struct luaL_Reg l_llthreads_lib[] = { | 705 | static const struct luaL_Reg l_llthreads_lib[] = { |
| 682 | {"new", l_llthread_new }, | 706 | {"new", l_llthread_new }, |
| 707 | {"set_logger", l_llthread_set_logger }, | ||
| 683 | 708 | ||
| 684 | {NULL, NULL} | 709 | {NULL, NULL} |
| 685 | }; | 710 | }; |
