diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | docs/index.html | 10 | ||||
-rw-r--r-- | src/lanes.c | 25 | ||||
-rw-r--r-- | src/lanes.lua | 2 | ||||
-rw-r--r-- | src/threading.c | 4 | ||||
-rw-r--r-- | src/tools.c | 56 | ||||
-rw-r--r-- | src/tools.h | 3 |
7 files changed, 72 insertions, 32 deletions
@@ -1,5 +1,9 @@ | |||
1 | CHANGES: | 1 | CHANGES: |
2 | 2 | ||
3 | CHANGE 88: BGe 06-Jan-14 | ||
4 | * version 3.7.6 | ||
5 | * if config.on_state_create() is a C function, call it by direct C closure reconstruction in newly created states | ||
6 | |||
3 | CHANGE 87: BGe 20-Dec-13 | 7 | CHANGE 87: BGe 20-Dec-13 |
4 | * version 3.7.5 | 8 | * version 3.7.5 |
5 | * fixed a crash that can occur at shutdown when an object stored inside a keeper state performs a linda operation on a linda making use of another keeper | 9 | * fixed a crash that can occur at shutdown when an object stored inside a keeper state performs a linda operation on a linda making use of another keeper |
diff --git a/docs/index.html b/docs/index.html index f25463d..931a961 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -64,13 +64,13 @@ | |||
64 | <font size="-1"> | 64 | <font size="-1"> |
65 | <p> | 65 | <p> |
66 | <br> | 66 | <br> |
67 | <i>Copyright © 2007-13 Asko Kauppi, Benoit Germain. All rights reserved.</i> | 67 | <i>Copyright © 2007-14 Asko Kauppi, Benoit Germain. All rights reserved.</i> |
68 | <br> | 68 | <br> |
69 | Lua Lanes is published under the same <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a> as Lua 5.1 and 5.2. | 69 | Lua Lanes is published under the same <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a> as Lua 5.1 and 5.2. |
70 | </p> | 70 | </p> |
71 | 71 | ||
72 | <p> | 72 | <p> |
73 | This document was revised on 20-Dec-13, and applies to version <tt>3.7.5</tt>. | 73 | This document was revised on 06-Jan-14, and applies to version <tt>3.7.6</tt>. |
74 | </p> | 74 | </p> |
75 | </font> | 75 | </font> |
76 | </center> | 76 | </center> |
@@ -356,13 +356,17 @@ | |||
356 | </td> | 356 | </td> |
357 | <td> | 357 | <td> |
358 | If provided, will be called in every created Lua state (keepers and lanes) right after initializing the base libraries. | 358 | If provided, will be called in every created Lua state (keepers and lanes) right after initializing the base libraries. |
359 | <br> | 359 | <br/> |
360 | Typical usage is twofold: | 360 | Typical usage is twofold: |
361 | <ul> | 361 | <ul> |
362 | <li>Tweak <tt>package.loaders</tt></li> | 362 | <li>Tweak <tt>package.loaders</tt></li> |
363 | <li>Load some additional C functions in the global space (of course only a C function will be able to do this).</li> | 363 | <li>Load some additional C functions in the global space (of course only a C function will be able to do this).</li> |
364 | </ul> | 364 | </ul> |
365 | That way, all changes in the state can be properly taken into account when building the function lookup database. Default is <tt>nil</tt>. | 365 | That way, all changes in the state can be properly taken into account when building the function lookup database. Default is <tt>nil</tt>. |
366 | <br/> | ||
367 | (Since version 3.7.6) If <tt>on_state_create()</tt> is a Lua function, it will be transfered normally before the call. | ||
368 | <br/> | ||
369 | If it is a C function, a C closure will be reconstructed in the created state from the C pointer. Lanes will raise an error if the function has upvalues. | ||
366 | </td> | 370 | </td> |
367 | </tr> | 371 | </tr> |
368 | 372 | ||
diff --git a/src/lanes.c b/src/lanes.c index e66342d..3ccf915 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * LANES.C Copyright (c) 2007-08, Asko Kauppi | 2 | * LANES.C Copyright (c) 2007-08, Asko Kauppi |
3 | * Copyright (C) 2009-13, Benoit Germain | 3 | * Copyright (C) 2009-14, Benoit Germain |
4 | * | 4 | * |
5 | * Multithreading in Lua. | 5 | * Multithreading in Lua. |
6 | * | 6 | * |
@@ -52,13 +52,13 @@ | |||
52 | * ... | 52 | * ... |
53 | */ | 53 | */ |
54 | 54 | ||
55 | char const* VERSION = "3.7.5"; | 55 | char const* VERSION = "3.7.6"; |
56 | 56 | ||
57 | /* | 57 | /* |
58 | =============================================================================== | 58 | =============================================================================== |
59 | 59 | ||
60 | Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> | 60 | Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> |
61 | 2011-13 Benoit Germain <bnt.germain@gmail.com> | 61 | 2011-14 Benoit Germain <bnt.germain@gmail.com> |
62 | 62 | ||
63 | Permission is hereby granted, free of charge, to any person obtaining a copy | 63 | Permission is hereby granted, free of charge, to any person obtaining a copy |
64 | of this software and associated documentation files (the "Software"), to deal | 64 | of this software and associated documentation files (the "Software"), to deal |
@@ -1987,14 +1987,13 @@ LUAG_FUNC( thread_new) | |||
1987 | struct s_lane** ud; | 1987 | struct s_lane** ud; |
1988 | 1988 | ||
1989 | char const* libs = lua_tostring( L, 2); | 1989 | char const* libs = lua_tostring( L, 2); |
1990 | int const on_state_create = lua_isfunction( L, 3) ? 3 : 0; | 1990 | uint_t cs = luaG_optunsigned( L, 3, 0); |
1991 | uint_t cs = luaG_optunsigned( L, 4, 0); | 1991 | int const prio = (int) luaL_optinteger( L, 4, 0); |
1992 | int const prio = (int) luaL_optinteger( L, 5, 0); | 1992 | uint_t glob = lua_isnoneornil( L, 5) ? 0 : 5; |
1993 | uint_t glob = lua_isnoneornil( L, 6) ? 0 : 6; | 1993 | uint_t package = lua_isnoneornil( L, 6) ? 0 : 6; |
1994 | uint_t package = lua_isnoneornil( L,7) ? 0 : 7; | 1994 | uint_t required = lua_isnoneornil( L, 7) ? 0 : 7; |
1995 | uint_t required = lua_isnoneornil( L, 8) ? 0 : 8; | 1995 | |
1996 | 1996 | #define FIXED_ARGS 7 | |
1997 | #define FIXED_ARGS 8 | ||
1998 | uint_t args = lua_gettop(L) - FIXED_ARGS; | 1997 | uint_t args = lua_gettop(L) - FIXED_ARGS; |
1999 | 1998 | ||
2000 | // public Lanes API accepts a generic range -3/+3 | 1999 | // public Lanes API accepts a generic range -3/+3 |
@@ -2011,7 +2010,7 @@ LUAG_FUNC( thread_new) | |||
2011 | 2010 | ||
2012 | // populate with selected libraries at the same time | 2011 | // populate with selected libraries at the same time |
2013 | // | 2012 | // |
2014 | L2 = luaG_newstate( L, on_state_create, libs); | 2013 | L2 = luaG_newstate( L, libs); |
2015 | 2014 | ||
2016 | STACK_GROW( L, 2); | 2015 | STACK_GROW( L, 2); |
2017 | STACK_GROW( L2, 3); | 2016 | STACK_GROW( L2, 3); |
@@ -2727,6 +2726,8 @@ static const struct luaL_Reg lanes_functions [] = { | |||
2727 | */ | 2726 | */ |
2728 | static void init_once_LOCKED( lua_State* L) | 2727 | static void init_once_LOCKED( lua_State* L) |
2729 | { | 2728 | { |
2729 | initialize_on_state_create( L); | ||
2730 | |||
2730 | STACK_CHECK( L); | 2731 | STACK_CHECK( L); |
2731 | 2732 | ||
2732 | lua_getfield( L, 1, "verbose_errors"); | 2733 | lua_getfield( L, 1, "verbose_errors"); |
diff --git a/src/lanes.lua b/src/lanes.lua index 4856a2d..0c544bb 100644 --- a/src/lanes.lua +++ b/src/lanes.lua | |||
@@ -297,7 +297,7 @@ local function gen( ... ) | |||
297 | -- Lane generator | 297 | -- Lane generator |
298 | -- | 298 | -- |
299 | return function(...) | 299 | return function(...) |
300 | return thread_new( func, libs, settings.on_state_create, cs, prio, g_tbl, package_tbl, required, ...) -- args | 300 | return thread_new( func, libs, cs, prio, g_tbl, package_tbl, required, ...) -- args |
301 | end | 301 | end |
302 | end | 302 | end |
303 | 303 | ||
diff --git a/src/threading.c b/src/threading.c index db9f734..3014136 100644 --- a/src/threading.c +++ b/src/threading.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * THREADING.C Copyright (c) 2007-08, Asko Kauppi | 2 | * THREADING.C Copyright (c) 2007-08, Asko Kauppi |
3 | * Copyright (C) 2009-13, Benoit Germain | 3 | * Copyright (C) 2009-14, Benoit Germain |
4 | * | 4 | * |
5 | * Lua Lanes OS threading specific code. | 5 | * Lua Lanes OS threading specific code. |
6 | * | 6 | * |
@@ -12,7 +12,7 @@ | |||
12 | =============================================================================== | 12 | =============================================================================== |
13 | 13 | ||
14 | Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> | 14 | Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> |
15 | Copyright (C) 2009-13, Benoit Germain <bnt.germain@gmail.com> | 15 | Copyright (C) 2009-14, Benoit Germain <bnt.germain@gmail.com> |
16 | 16 | ||
17 | Permission is hereby granted, free of charge, to any person obtaining a copy | 17 | Permission is hereby granted, free of charge, to any person obtaining a copy |
18 | of this software and associated documentation files (the "Software"), to deal | 18 | of this software and associated documentation files (the "Software"), to deal |
diff --git a/src/tools.c b/src/tools.c index 60f9012..9f36858 100644 --- a/src/tools.c +++ b/src/tools.c | |||
@@ -8,7 +8,7 @@ | |||
8 | =============================================================================== | 8 | =============================================================================== |
9 | 9 | ||
10 | Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com> | 10 | Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com> |
11 | 2011-13 benoit Germain <bnt.germain@gmail.com> | 11 | 2011-14 benoit Germain <bnt.germain@gmail.com> |
12 | 12 | ||
13 | Permission is hereby granted, free of charge, to any person obtaining a copy | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy |
14 | of this software and associated documentation files (the "Software"), to deal | 14 | of this software and associated documentation files (the "Software"), to deal |
@@ -161,6 +161,39 @@ void luaG_dump( lua_State* L ) { | |||
161 | fprintf( stderr, "\n" ); | 161 | fprintf( stderr, "\n" ); |
162 | } | 162 | } |
163 | 163 | ||
164 | static lua_CFunction s_on_state_create_func = NULL; | ||
165 | int initialize_on_state_create( lua_State* L) | ||
166 | { | ||
167 | STACK_CHECK( L); | ||
168 | lua_getfield( L, -1, "on_state_create"); // settings on_state_create|nil | ||
169 | if( !lua_isnil( L, -1)) | ||
170 | { | ||
171 | // store C function pointer in an internal variable | ||
172 | s_on_state_create_func = lua_tocfunction( L, -1); // settings on_state_create | ||
173 | if( s_on_state_create_func != NULL) | ||
174 | { | ||
175 | // make sure the function doesn't have upvalues | ||
176 | char const* upname = lua_getupvalue( L, -1, 1); // settings on_state_create upval? | ||
177 | if( upname != NULL) // should be "" for C functions with upvalues if any | ||
178 | { | ||
179 | luaL_error( L, "on_state_create shouldn't have upvalues"); | ||
180 | } | ||
181 | // remove this C function from the config table so that it doesn't cause problems | ||
182 | // when we transfer the config table in newly created Lua states | ||
183 | lua_pushnil( L); // settings on_state_create nil | ||
184 | lua_setfield( L, -3, "on_state_create"); // settings on_state_create | ||
185 | } | ||
186 | else | ||
187 | { | ||
188 | // optim: store marker saying we have such a function in the config table | ||
189 | s_on_state_create_func = initialize_on_state_create; | ||
190 | } | ||
191 | } | ||
192 | lua_pop( L, 1); // settings | ||
193 | STACK_END( L, 0); | ||
194 | return 0; | ||
195 | } | ||
196 | |||
164 | // just like lua_xmove, args are (from, to) | 197 | // just like lua_xmove, args are (from, to) |
165 | void luaG_copy_one_time_settings( lua_State* L, lua_State* L2, char const* name_) | 198 | void luaG_copy_one_time_settings( lua_State* L, lua_State* L2, char const* name_) |
166 | { | 199 | { |
@@ -569,7 +602,7 @@ void populate_func_lookup_table( lua_State* L, int _i, char const* name_) | |||
569 | * Base ("unpack", "print" etc.) is always added, unless 'libs' is NULL. | 602 | * Base ("unpack", "print" etc.) is always added, unless 'libs' is NULL. |
570 | * | 603 | * |
571 | */ | 604 | */ |
572 | lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char const* libs) | 605 | lua_State* luaG_newstate( lua_State* _from, char const* libs) |
573 | { | 606 | { |
574 | // reuse alloc function from the originating state | 607 | // reuse alloc function from the originating state |
575 | #if PROPAGATE_ALLOCF | 608 | #if PROPAGATE_ALLOCF |
@@ -587,7 +620,7 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con | |||
587 | lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); | 620 | lua_setfield( L, LUA_REGISTRYINDEX, LOOKUP_REGKEY); |
588 | 621 | ||
589 | // neither libs (not even 'base') nor special init func: we are done | 622 | // neither libs (not even 'base') nor special init func: we are done |
590 | if( libs == NULL && _on_state_create <= 0) | 623 | if( libs == NULL && s_on_state_create_func == NULL) |
591 | { | 624 | { |
592 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate(NULL)\n" INDENT_END)); | 625 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "luaG_newstate(NULL)\n" INDENT_END)); |
593 | return L; | 626 | return L; |
@@ -655,22 +688,19 @@ lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char con | |||
655 | 688 | ||
656 | STACK_CHECK( L); | 689 | STACK_CHECK( L); |
657 | // call this after the base libraries are loaded and GC is restarted | 690 | // call this after the base libraries are loaded and GC is restarted |
658 | if( _on_state_create > 0) | 691 | if( s_on_state_create_func != NULL) |
659 | { | 692 | { |
660 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); | 693 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "calling on_state_create()\n" INDENT_END)); |
661 | if( lua_iscfunction( _from, _on_state_create)) | 694 | if( s_on_state_create_func != initialize_on_state_create) |
662 | { | 695 | { |
663 | // C function: recreate a closure in the new state, bypassing the lookup scheme | 696 | // C function: recreate a closure in the new state, bypassing the lookup scheme |
664 | lua_CFunction osc = lua_tocfunction( _from, _on_state_create); | 697 | lua_pushcfunction( L, s_on_state_create_func); |
665 | lua_pushcfunction( L, osc); | ||
666 | } | 698 | } |
667 | else | 699 | else // Lua function located in the config table |
668 | { | 700 | { |
669 | STACK_CHECK( _from); | 701 | lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); |
670 | // Lua function: transfer as usual (should work as long as it only uses base libraries) | 702 | lua_getfield( L, -1, "on_state_create"); |
671 | lua_pushvalue( _from, _on_state_create); | 703 | lua_remove( L, -2); |
672 | luaG_inter_move( _from, L, 1, eLM_LaneBody); | ||
673 | STACK_END( _from, 0); | ||
674 | } | 704 | } |
675 | // capture error and forward it to main state | 705 | // capture error and forward it to main state |
676 | if( lua_pcall( L, 0, 0, 0) != LUA_OK) | 706 | if( lua_pcall( L, 0, 0, 0) != LUA_OK) |
diff --git a/src/tools.h b/src/tools.h index 19dca70..be358db 100644 --- a/src/tools.h +++ b/src/tools.h | |||
@@ -98,7 +98,7 @@ extern int debugspew_indent_depth; | |||
98 | 98 | ||
99 | void luaG_dump( lua_State* L ); | 99 | void luaG_dump( lua_State* L ); |
100 | 100 | ||
101 | lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char const* libs); | 101 | lua_State* luaG_newstate( lua_State* _from, char const* libs); |
102 | void luaG_copy_one_time_settings( lua_State* L, lua_State* L2, char const* name_); | 102 | void luaG_copy_one_time_settings( lua_State* L, lua_State* L2, char const* name_); |
103 | 103 | ||
104 | typedef struct { | 104 | typedef struct { |
@@ -129,6 +129,7 @@ extern MUTEX_T mtid_lock; | |||
129 | 129 | ||
130 | void populate_func_lookup_table( lua_State* L, int _i, char const* _name); | 130 | void populate_func_lookup_table( lua_State* L, int _i, char const* _name); |
131 | void serialize_require( lua_State *L); | 131 | void serialize_require( lua_State *L); |
132 | int initialize_on_state_create( lua_State *L); | ||
132 | extern MUTEX_T require_cs; | 133 | extern MUTEX_T require_cs; |
133 | 134 | ||
134 | // for verbose errors | 135 | // for verbose errors |