aboutsummaryrefslogtreecommitdiff
path: root/src/keeper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/keeper.c')
-rw-r--r--src/keeper.c94
1 files changed, 77 insertions, 17 deletions
diff --git a/src/keeper.c b/src/keeper.c
index 338f794..83ec8f3 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -128,20 +128,31 @@ static void fifo_peek( lua_State* L, keeper_fifo* fifo, int _count)
128} 128}
129 129
130// in: fifo 130// in: fifo
131// out: pushes as many items as required on the stack (function assumes they exist in sufficient number) 131// out: remove the fifo from the stack, push as many items as required on the stack (function assumes they exist in sufficient number)
132static void fifo_pop( lua_State* L, keeper_fifo* fifo, int _count) 132static void fifo_pop( lua_State* L, keeper_fifo* fifo, int _count)
133{ 133{
134 int fifo_idx = lua_gettop( L); // ... fifo 134 int fifo_idx = lua_gettop( L); // ... fifo
135 int i; 135 int i;
136 // each iteration pushes a value on the stack! 136 // each iteration pushes a value on the stack!
137 STACK_GROW( L, _count + 1); 137 STACK_GROW( L, _count + 2);
138 for( i = 0; i < _count; ++ i) 138 // skip first item, we will push it last
139 for( i = 1; i < _count; ++ i)
139 { 140 {
140 int at = fifo->first + i; 141 int const at = fifo->first + i;
142 // push item on the stack
141 lua_rawgeti( L, fifo_idx, at); // ... fifo val 143 lua_rawgeti( L, fifo_idx, at); // ... fifo val
144 // remove item from the fifo
142 lua_pushnil( L); // ... fifo val nil 145 lua_pushnil( L); // ... fifo val nil
143 lua_rawseti( L, fifo_idx, at); // ... fifo val 146 lua_rawseti( L, fifo_idx, at); // ... fifo val
144 } 147 }
148 // now process first item
149 {
150 int const at = fifo->first;
151 lua_rawgeti( L, fifo_idx, at); // ... fifo vals val
152 lua_pushnil( L); // ... fifo vals val nil
153 lua_rawseti( L, fifo_idx, at); // ... fifo vals val
154 lua_replace( L, fifo_idx); // ... vals
155 }
145 fifo->first += _count; 156 fifo->first += _count;
146 fifo->count -= _count; 157 fifo->count -= _count;
147} 158}
@@ -172,6 +183,47 @@ static void push_table( lua_State* L, int idx)
172 STACK_END( L, 1); 183 STACK_END( L, 1);
173} 184}
174 185
186int keeper_push_linda_storage( lua_State* L, void* ptr)
187{
188 struct s_Keeper* K = keeper_acquire( ptr);
189 STACK_CHECK( K->L)
190 lua_pushlightuserdata( K->L, fifos_key); // fifos_key
191 lua_rawget( K->L, LUA_REGISTRYINDEX); // fifos
192 lua_pushlightuserdata( K->L, ptr); // fifos ud
193 lua_rawget( K->L, -2); // fifos storage
194 lua_remove( K->L, -2); // storage
195 if( !lua_istable( K->L, -1))
196 {
197 lua_pop( K->L, 1); //
198 STACK_MID( K->L, 0);
199 return 0;
200 }
201 lua_pushnil( K->L); // storage nil
202 lua_newtable( L); // out
203 while( lua_next( K->L, -2)) // storage key fifo
204 {
205 keeper_fifo* fifo = prepare_fifo_access( K->L, -1); // storage key fifo
206 lua_pushvalue( K->L, -2); // storage key fifo key
207 luaG_inter_move( K->L, L, 1); // storage key fifo // out key
208 STACK_CHECK( L)
209 lua_newtable( L); // out key keyout
210 luaG_inter_move( K->L, L, 1); // storage key // out key keyout fifo
211 lua_pushinteger( L, fifo->first); // out key keyout fifo first
212 lua_setfield( L, -3, "first"); // out key keyout fifo
213 lua_pushinteger( L, fifo->count); // out key keyout fifo count
214 lua_setfield( L, -3, "count"); // out key keyout fifo
215 lua_pushinteger( L, fifo->limit); // out key keyout fifo limit
216 lua_setfield( L, -3, "limit"); // out key keyout fifo
217 lua_setfield( L, -2, "fifo"); // out key keyout
218 lua_rawset( L, -3); // out
219 STACK_END( L, 0)
220 }
221 lua_pop( K->L, 1); //
222 STACK_END( K->L, 0)
223 keeper_release( K);
224 return 1;
225}
226
175// in: linda_ud 227// in: linda_ud
176int keepercall_clear( lua_State* L) 228int keepercall_clear( lua_State* L)
177{ 229{
@@ -223,7 +275,7 @@ int keepercall_send( lua_State* L)
223} 275}
224 276
225// in: linda_ud, key [, key]? 277// in: linda_ud, key [, key]?
226// out: (val, key) or nothing 278// out: (key, val) or nothing
227int keepercall_receive( lua_State* L) 279int keepercall_receive( lua_State* L)
228{ 280{
229 int top = lua_gettop( L); 281 int top = lua_gettop( L);
@@ -238,16 +290,17 @@ int keepercall_receive( lua_State* L)
238 fifo = prepare_fifo_access( L, -1); // fifos keys fifo 290 fifo = prepare_fifo_access( L, -1); // fifos keys fifo
239 if( fifo && fifo->count > 0) 291 if( fifo && fifo->count > 0)
240 { 292 {
241 fifo_pop( L, fifo, 1); // fifos keys fifo val 293 fifo_pop( L, fifo, 1); // fifos keys val
242 if( !lua_isnil( L, -1)) 294 if( !lua_isnil( L, -1))
243 { 295 {
244 lua_replace( L, 1); // val keys fifo 296 lua_replace( L, 1); // val keys
297 lua_settop( L, i); // val keys key[i]
245 if( i != 2) 298 if( i != 2)
246 { 299 {
247 lua_pushvalue( L, i); // val keys fifo key[i] 300 lua_replace( L, 2); // val key keys
248 lua_replace( L, 2); // val key keys fifo 301 lua_settop( L, 2); // val key
249 } 302 }
250 lua_settop( L, 2); // val key 303 lua_insert( L, 1); // key, val
251 return 2; 304 return 2;
252 } 305 }
253 } 306 }
@@ -266,16 +319,22 @@ int keepercall_receive_batched( lua_State* L)
266 keeper_fifo* fifo; 319 keeper_fifo* fifo;
267 int const max_count = (int) luaL_optinteger( L, 4, min_count); 320 int const max_count = (int) luaL_optinteger( L, 4, min_count);
268 lua_settop( L, 2); // ud key 321 lua_settop( L, 2); // ud key
269 push_table( L, 1); // ud key fifos 322 lua_insert( L, 1); // key ud
270 lua_replace( L, 1); // fifos key 323 push_table( L, 2); // key ud fifos
271 lua_rawget( L, -2); // fifos fifo 324 lua_remove( L, 2); // key fifos
272 lua_remove( L, 1); // fifo 325 lua_pushvalue( L, 1); // key fifos key
273 fifo = prepare_fifo_access( L, 1); // fifo 326 lua_rawget( L, 2); // key fifos fifo
327 lua_remove( L, 2); // key fifo
328 fifo = prepare_fifo_access( L, 2); // key fifo
274 if( fifo && fifo->count >= min_count) 329 if( fifo && fifo->count >= min_count)
275 { 330 {
276 fifo_pop( L, fifo, __min( max_count, fifo->count)); // fifo ... 331 fifo_pop( L, fifo, __min( max_count, fifo->count)); // key ...
332 }
333 else
334 {
335 lua_settop( L, 0);
277 } 336 }
278 return lua_gettop( L) - 1; 337 return lua_gettop( L);
279 } 338 }
280 else 339 else
281 { 340 {
@@ -521,6 +580,7 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create)
521 } 580 }
522 // call close_keepers at the very last as we want to be sure no thread is GCing after. 581 // call close_keepers at the very last as we want to be sure no thread is GCing after.
523 // (and therefore may perform linda object dereferencing after keepers are gone) 582 // (and therefore may perform linda object dereferencing after keepers are gone)
583 // problem: maybe on some platforms atexit() is called after DLL/so are unloaded...
524 atexit( atexit_close_keepers); 584 atexit( atexit_close_keepers);
525 return NULL; // ok 585 return NULL; // ok
526} 586}