aboutsummaryrefslogtreecommitdiff
path: root/src/tools.h
diff options
context:
space:
mode:
authorBenoit Germain <b n t DOT g e r m a i n AT g m a i l DOT c o m>2017-08-01 09:40:44 +0200
committerBenoit Germain <b n t DOT g e r m a i n AT g m a i l DOT c o m>2017-08-01 09:40:44 +0200
commite0dbd33c2d4776d6b2213dd82f344166eafde438 (patch)
treebab4483f9f5b0d802bdbfc8641fe44ff9649382f /src/tools.h
parentfcd08030b6b6af81a8aa2672082a55f602006f78 (diff)
downloadlanes-e0dbd33c2d4776d6b2213dd82f344166eafde438.tar.gz
lanes-e0dbd33c2d4776d6b2213dd82f344166eafde438.tar.bz2
lanes-e0dbd33c2d4776d6b2213dd82f344166eafde438.zip
Fix for deep-aware modules
Don't crash when using a module that creates Lanes-compatible deep userdata. Added a sample deep-aware module.
Diffstat (limited to 'src/tools.h')
-rw-r--r--src/tools.h118
1 files changed, 4 insertions, 114 deletions
diff --git a/src/tools.h b/src/tools.h
index b869a16..9155747 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -11,131 +11,21 @@
11 11
12#include <assert.h> 12#include <assert.h>
13 13
14// M$ compiler doesn't support 'inline' keyword in C files... 14#include "macros_and_utils.h"
15#if defined( _MSC_VER)
16#define inline __inline
17#endif
18
19// For some reason, LuaJIT 64bits doesn't support lua_newstate()
20#if defined(LUA_JITLIBNAME) && (defined(__x86_64__) || defined(_M_X64))
21//#pragma message( "LuaJIT 64 bits detected: don't propagate allocf")
22#define PROPAGATE_ALLOCF 0
23#else // LuaJIT x64
24//#pragma message( "PUC-Lua detected: propagate allocf")
25#define PROPAGATE_ALLOCF 1
26#endif // LuaJIT x64
27#if PROPAGATE_ALLOCF
28#define PROPAGATE_ALLOCF_PREP( L) void* allocUD; lua_Alloc allocF = lua_getallocf( L, &allocUD)
29#define PROPAGATE_ALLOCF_ALLOC() lua_newstate( allocF, allocUD)
30#else // PROPAGATE_ALLOCF
31#define PROPAGATE_ALLOCF_PREP( L)
32#define PROPAGATE_ALLOCF_ALLOC() luaL_newstate()
33#endif // PROPAGATE_ALLOCF
34
35#define USE_DEBUG_SPEW 0
36#if USE_DEBUG_SPEW
37extern char const* debugspew_indent;
38#define INDENT_BEGIN "%.*s "
39#define INDENT_END , (U ? U->debugspew_indent_depth : 0), debugspew_indent
40#define DEBUGSPEW_CODE(_code) _code
41#else // USE_DEBUG_SPEW
42#define DEBUGSPEW_CODE(_code)
43#endif // USE_DEBUG_SPEW
44
45// ################################################################################################
46
47/*
48 * Do we want to activate full lane tracking feature? (EXPERIMENTAL)
49 */
50#define HAVE_LANE_TRACKING 1
51 15
52// ################################################################################################ 16// ################################################################################################
53 17
54// this is pointed to by full userdata proxies, and allocated with malloc() to survive any lua_State lifetime 18// this is pointed to by full userdata proxies, and allocated with malloc() to survive any lua_State lifetime
55typedef struct 19struct DEEP_PRELUDE
56{ 20{
57 volatile int refcount; 21 volatile int refcount;
58 void* deep; 22 void* deep;
59 // when stored in a keeper state, the full userdata doesn't have a metatable, so we need direct access to the idfunc 23 // when stored in a keeper state, the full userdata doesn't have a metatable, so we need direct access to the idfunc
60 luaG_IdFunction idfunc; 24 luaG_IdFunction idfunc;
61} DEEP_PRELUDE;
62
63// ################################################################################################
64
65// everything regarding the a Lanes universe is stored in that global structure
66// held as a full userdata in the master Lua state that required it for the first time
67// don't forget to initialize all members in LG_configure()
68struct s_Universe
69{
70 // for verbose errors
71 bool_t verboseErrors;
72
73 lua_CFunction on_state_create_func;
74
75 struct s_Keepers* keepers;
76
77 // Initialized by 'init_once_LOCKED()': the deep userdata Linda object
78 // used for timers (each lane will get a proxy to this)
79 volatile DEEP_PRELUDE* timer_deep; // = NULL
80
81#if HAVE_LANE_TRACKING
82 MUTEX_T tracking_cs;
83 struct s_lane* volatile tracking_first; // will change to TRACKING_END if we want to activate tracking
84#endif // HAVE_LANE_TRACKING
85
86 MUTEX_T selfdestruct_cs;
87
88 // require() serialization
89 MUTEX_T require_cs;
90
91 // Lock for reference counter inc/dec locks (to be initialized by outside code) TODO: get rid of this and use atomics instead!
92 MUTEX_T deep_lock;
93 MUTEX_T mtid_lock;
94
95 int last_mt_id;
96
97#if USE_DEBUG_SPEW
98 int debugspew_indent_depth;
99#endif // USE_DEBUG_SPEW
100
101 struct s_lane* volatile selfdestruct_first;
102 // After a lane has removed itself from the chain, it still performs some processing.
103 // The terminal desinit sequence should wait for all such processing to terminate before force-killing threads
104 int volatile selfdestructing_count;
105}; 25};
106 26
107struct s_Universe* get_universe( lua_State* L);
108extern void* const UNIVERSE_REGKEY;
109
110// ################################################################################################ 27// ################################################################################################
111 28
112#ifdef NDEBUG
113 #define _ASSERT_L(lua,c) /*nothing*/
114 #define STACK_CHECK(L) /*nothing*/
115 #define STACK_MID(L,c) /*nothing*/
116 #define STACK_END(L,c) /*nothing*/
117 #define STACK_DUMP(L) /*nothing*/
118#else
119 void ASSERT_IMPL( lua_State* L, bool_t cond_, char const* file_, int const line_, char const* text_);
120 #define _ASSERT_L(lua,c) ASSERT_IMPL( lua, (c) != 0, __FILE__, __LINE__, #c)
121 //
122 #define STACK_CHECK(L) { int const _oldtop_##L = lua_gettop( L)
123 #define STACK_MID(L,change) \
124 do \
125 { \
126 int a = lua_gettop( L) - _oldtop_##L; \
127 int b = (change); \
128 if( a != b) \
129 luaL_error( L, "STACK ASSERT failed (%d not %d): %s:%d", a, b, __FILE__, __LINE__ ); \
130 } while( 0)
131 #define STACK_END(L,change) STACK_MID(L,change); }
132
133 #define STACK_DUMP( L) luaG_dump( L)
134#endif
135#define ASSERT_L(c) _ASSERT_L(L,c)
136
137#define STACK_GROW( L, n) do { if (!lua_checkstack(L,(int)(n))) luaL_error( L, "Cannot grow stack!" ); } while( 0)
138
139#define LUAG_FUNC( func_name ) static int LG_##func_name( lua_State* L) 29#define LUAG_FUNC( func_name ) static int LG_##func_name( lua_State* L)
140 30
141#define luaG_optunsigned(L,i,d) ((uint_t) luaL_optinteger(L,i,d)) 31#define luaG_optunsigned(L,i,d) ((uint_t) luaL_optinteger(L,i,d))
@@ -155,8 +45,8 @@ enum eLookupMode
155 eLM_FromKeeper // send a function from a keeper state to a lane 45 eLM_FromKeeper // send a function from a keeper state to a lane
156}; 46};
157 47
158char const* push_deep_proxy( struct s_Universe* U, lua_State* L, DEEP_PRELUDE* prelude, enum eLookupMode mode_); 48char const* push_deep_proxy( struct s_Universe* U, lua_State* L, struct DEEP_PRELUDE* prelude, enum eLookupMode mode_);
159void free_deep_prelude( lua_State* L, DEEP_PRELUDE* prelude_); 49void free_deep_prelude( lua_State* L, struct DEEP_PRELUDE* prelude_);
160 50
161int luaG_inter_copy_package( struct s_Universe* U, lua_State* L, lua_State* L2, int package_idx_, enum eLookupMode mode_); 51int luaG_inter_copy_package( struct s_Universe* U, lua_State* L, lua_State* L2, int package_idx_, enum eLookupMode mode_);
162 52