aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--docs/index.html10
-rw-r--r--src/lanes.c25
-rw-r--r--src/lanes.lua2
-rw-r--r--src/threading.c4
-rw-r--r--src/tools.c56
-rw-r--r--src/tools.h3
7 files changed, 72 insertions, 32 deletions
diff --git a/CHANGES b/CHANGES
index c196455..7fac3e3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,9 @@
1CHANGES: 1CHANGES:
2 2
3CHANGE 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
3CHANGE 87: BGe 20-Dec-13 7CHANGE 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 &copy; 2007-13 Asko Kauppi, Benoit Germain. All rights reserved.</i> 67 <i>Copyright &copy; 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
55char const* VERSION = "3.7.5"; 55char const* VERSION = "3.7.6";
56 56
57/* 57/*
58=============================================================================== 58===============================================================================
59 59
60Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> 60Copyright (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
63Permission is hereby granted, free of charge, to any person obtaining a copy 63Permission is hereby granted, free of charge, to any person obtaining a copy
64of this software and associated documentation files (the "Software"), to deal 64of 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*/
2728static void init_once_LOCKED( lua_State* L) 2727static 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
302end 302end
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
14Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com> 14Copyright (C) 2007-10 Asko Kauppi <akauppi@gmail.com>
15Copyright (C) 2009-13, Benoit Germain <bnt.germain@gmail.com> 15Copyright (C) 2009-14, Benoit Germain <bnt.germain@gmail.com>
16 16
17Permission is hereby granted, free of charge, to any person obtaining a copy 17Permission is hereby granted, free of charge, to any person obtaining a copy
18of this software and associated documentation files (the "Software"), to deal 18of 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
10Copyright (C) 2002-10 Asko Kauppi <akauppi@gmail.com> 10Copyright (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
13Permission is hereby granted, free of charge, to any person obtaining a copy 13Permission is hereby granted, free of charge, to any person obtaining a copy
14of this software and associated documentation files (the "Software"), to deal 14of 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
164static lua_CFunction s_on_state_create_func = NULL;
165int 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)
165void luaG_copy_one_time_settings( lua_State* L, lua_State* L2, char const* name_) 198void 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*/
572lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char const* libs) 605lua_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
99void luaG_dump( lua_State* L ); 99void luaG_dump( lua_State* L );
100 100
101lua_State* luaG_newstate( lua_State* _from, int const _on_state_create, char const* libs); 101lua_State* luaG_newstate( lua_State* _from, char const* libs);
102void luaG_copy_one_time_settings( lua_State* L, lua_State* L2, char const* name_); 102void luaG_copy_one_time_settings( lua_State* L, lua_State* L2, char const* name_);
103 103
104typedef struct { 104typedef struct {
@@ -129,6 +129,7 @@ extern MUTEX_T mtid_lock;
129 129
130void populate_func_lookup_table( lua_State* L, int _i, char const* _name); 130void populate_func_lookup_table( lua_State* L, int _i, char const* _name);
131void serialize_require( lua_State *L); 131void serialize_require( lua_State *L);
132int initialize_on_state_create( lua_State *L);
132extern MUTEX_T require_cs; 133extern MUTEX_T require_cs;
133 134
134// for verbose errors 135// for verbose errors