aboutsummaryrefslogtreecommitdiff
path: root/src/keeper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/keeper.c')
-rw-r--r--src/keeper.c96
1 files changed, 67 insertions, 29 deletions
diff --git a/src/keeper.c b/src/keeper.c
index 4c90069..6d5ecbf 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -95,7 +95,7 @@ static void fifo_new( lua_State* L)
95} 95}
96 96
97// in: expect fifo ... on top of the stack 97// in: expect fifo ... on top of the stack
98// out: nothing, removes all pushed values on the stack 98// out: nothing, removes all pushed values from the stack
99static void fifo_push( lua_State* L, keeper_fifo* fifo, int _count) 99static void fifo_push( lua_State* L, keeper_fifo* fifo, int _count)
100{ 100{
101 int idx = lua_gettop( L) - _count; 101 int idx = lua_gettop( L) - _count;
@@ -349,7 +349,7 @@ int keepercall_receive_batched( lua_State* L)
349} 349}
350 350
351// in: linda_ud key n 351// in: linda_ud key n
352// out: nothing 352// out: true or nil
353int keepercall_limit( lua_State* L) 353int keepercall_limit( lua_State* L)
354{ 354{
355 keeper_fifo* fifo; 355 keeper_fifo* fifo;
@@ -358,22 +358,37 @@ int keepercall_limit( lua_State* L)
358 lua_replace( L, 1); // fifos key n 358 lua_replace( L, 1); // fifos key n
359 lua_pop( L, 1); // fifos key 359 lua_pop( L, 1); // fifos key
360 lua_pushvalue( L, -1); // fifos key key 360 lua_pushvalue( L, -1); // fifos key key
361 lua_rawget( L, -3); // fifos key fifo 361 lua_rawget( L, -3); // fifos key fifo|nil
362 fifo = (keeper_fifo*) lua_touserdata( L, -1); 362 fifo = (keeper_fifo*) lua_touserdata( L, -1);
363 if( fifo == NULL) 363 if( fifo == NULL)
364 { 364 { // fifos key nil
365 lua_pop( L, 1); // fifos key 365 lua_pop( L, 1); // fifos key
366 fifo_new( L); // fifos key fifo 366 fifo_new( L); // fifos key fifo
367 fifo = (keeper_fifo*) lua_touserdata( L, -1); 367 fifo = (keeper_fifo*) lua_touserdata( L, -1);
368 lua_rawset( L, -3); // fifos 368 lua_rawset( L, -3); // fifos
369 } 369 }
370 // remove any clutter on the stack
371 lua_settop( L, 0);
372 // return true if we decide that blocked threads waiting to write on that key should be awakened
373 // this is the case if we detect the key was full but it is no longer the case
374 if(
375 ((fifo->limit >= 0) && (fifo->count >= fifo->limit)) // the key was full if limited and count exceeded the previous limit
376 && ((limit < 0) || (fifo->count < limit)) // the key is not full if unlimited or count is lower than the new limit
377 )
378 {
379 lua_pushboolean( L, 1);
380 }
381 // set the new limit
370 fifo->limit = limit; 382 fifo->limit = limit;
371 return 0; 383 // return 0 or 1 value
384 return lua_gettop( L);
372} 385}
373 386
374//in: linda_ud key [val] 387//in: linda_ud key [val]
388//out: true or nil
375int keepercall_set( lua_State* L) 389int keepercall_set( lua_State* L)
376{ 390{
391 bool_t should_wake_writers = FALSE;
377 STACK_GROW( L, 6); 392 STACK_GROW( L, 6);
378 // make sure we have a value on the stack 393 // make sure we have a value on the stack
379 if( lua_gettop( L) == 2) // ud key val? 394 if( lua_gettop( L) == 2) // ud key val?
@@ -391,16 +406,18 @@ int keepercall_set( lua_State* L)
391 lua_pushvalue( L, -2); // fifos key val key 406 lua_pushvalue( L, -2); // fifos key val key
392 lua_rawget( L, 1); // fifos key val fifo|nil 407 lua_rawget( L, 1); // fifos key val fifo|nil
393 fifo = (keeper_fifo*) lua_touserdata( L, -1); 408 fifo = (keeper_fifo*) lua_touserdata( L, -1);
394 if( fifo == NULL) // might be NULL if we set a nonexistent key to nil 409 if( fifo == NULL) // can be NULL if we store a value at a new key
395 { 410 { // fifos key val nil
396 lua_pop( L, 1); // fifos key val 411 lua_pop( L, 1); // fifos key val
397 fifo_new( L); // fifos key val fifo 412 fifo_new( L); // fifos key val fifo
398 lua_pushvalue( L, 2); // fifos key val fifo key 413 lua_pushvalue( L, 2); // fifos key val fifo key
399 lua_pushvalue( L, -2); // fifos key val fifo key fifo 414 lua_pushvalue( L, -2); // fifos key val fifo key fifo
400 lua_rawset( L, 1); // fifos key val fifo 415 lua_rawset( L, 1); // fifos key val fifo
401 } 416 }
402 else // the fifo exists, we just want to clear its contents 417 else // the fifo exists, we just want to update its contents
403 { 418 { // fifos key val fifo
419 // we create room if the fifo was full but it is no longer the case
420 should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit);
404 // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! 421 // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged!
405 lua_newtable( L); // fifos key val fifo {} 422 lua_newtable( L); // fifos key val fifo {}
406 lua_setuservalue( L, -2); // fifos key val fifo 423 lua_setuservalue( L, -2); // fifos key val fifo
@@ -411,22 +428,35 @@ int keepercall_set( lua_State* L)
411 lua_insert( L, -2); // fifos key fifo val 428 lua_insert( L, -2); // fifos key fifo val
412 fifo_push( L, fifo, 1); // fifos key fifo 429 fifo_push( L, fifo, 1); // fifos key fifo
413 } 430 }
414 else // val == nil // fifos key nil 431 else // val == nil: we clear the key contents
415 { 432 { // fifos key nil
416 keeper_fifo* fifo; 433 keeper_fifo* fifo;
417 lua_pop( L, 1); // fifos key 434 lua_pop( L, 1); // fifos key
418 lua_rawget( L, 1); // fifos fifo|nil 435 lua_pushvalue( L, -1); // fifos key key
436 lua_rawget( L, 1); // fifos key fifo|nil
419 // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged! 437 // empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged!
420 fifo = (keeper_fifo*) lua_touserdata( L, -1); 438 fifo = (keeper_fifo*) lua_touserdata( L, -1);
421 if( fifo != NULL) // might be NULL if we set a nonexistent key to nil 439 if( fifo != NULL) // might be NULL if we set a nonexistent key to nil
422 { 440 { // fifos key fifo
423 lua_newtable( L); // fifos fifo {} 441 if( fifo->limit < 0) // fifo limit value is the default (unlimited): we can totally remove it
424 lua_setuservalue( L, -2); // fifos fifo 442 {
425 fifo->first = 1; 443 lua_pop( L, 1); // fifos key
426 fifo->count = 0; 444 lua_pushnil( L); // fifos key nil
445 lua_rawset( L, -3); // fifos
446 }
447 else
448 {
449 // we create room if the fifo was full but it is no longer the case
450 should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit);
451 lua_remove( L, -2); // fifos fifo
452 lua_newtable( L); // fifos fifo {}
453 lua_setuservalue( L, -2); // fifos fifo
454 fifo->first = 1;
455 fifo->count = 0;
456 }
427 } 457 }
428 } 458 }
429 return 0; 459 return should_wake_writers ? (lua_pushboolean( L, 1), 1) : 0;
430} 460}
431 461
432// in: linda_ud key 462// in: linda_ud key
@@ -476,11 +506,18 @@ int keepercall_count( lua_State* L)
476 { 506 {
477 keeper_fifo* fifo; 507 keeper_fifo* fifo;
478 lua_replace( L, 1); // fifos key 508 lua_replace( L, 1); // fifos key
479 lua_rawget( L, -2); // fifos fifo 509 lua_rawget( L, -2); // fifos fifo|nil
480 fifo = prepare_fifo_access( L, -1); // fifos fifo 510 if( lua_isnil( L, -1)) // the key is unknown
481 lua_pushinteger( L, fifo->count); // fifos fifo count 511 { // fifos nil
482 lua_replace( L, -3); // count fifo 512 lua_remove( L, -2); // nil
483 lua_pop( L, 1); // count 513 }
514 else // the key is known
515 { // fifos fifo
516 fifo = prepare_fifo_access( L, -1); // fifos fifo
517 lua_pushinteger( L, fifo->count); // fifos fifo count
518 lua_replace( L, -3); // count fifo
519 lua_pop( L, 1); // count
520 }
484 } 521 }
485 break; 522 break;
486 523
@@ -494,21 +531,22 @@ int keepercall_count( lua_State* L)
494 { 531 {
495 keeper_fifo* fifo; 532 keeper_fifo* fifo;
496 lua_pushvalue( L, -1); // out fifos keys key 533 lua_pushvalue( L, -1); // out fifos keys key
497 lua_rawget( L, 2); // out fifos keys fifo 534 lua_rawget( L, 2); // out fifos keys fifo|nil
498 fifo = prepare_fifo_access( L, -1); // out fifos keys fifo 535 fifo = prepare_fifo_access( L, -1); // out fifos keys fifo|nil
499 lua_pop( L, 1); // out fifos keys 536 lua_pop( L, 1); // out fifos keys
500 if( fifo != NULL) 537 if( fifo != NULL) // the key is known
501 { 538 {
502 lua_pushinteger( L, fifo->count); // out fifos keys count 539 lua_pushinteger( L, fifo->count); // out fifos keys count
503 lua_rawset( L, 1); // out fifos keys 540 lua_rawset( L, 1); // out fifos keys
504 } 541 }
505 else 542 else // the key is unknown
506 { 543 {
507 lua_pop( L, 1); // out fifos keys 544 lua_pop( L, 1); // out fifos keys
508 } 545 }
509 } 546 }
510 lua_pop( L, 1); // out 547 lua_pop( L, 1); // out
511 } 548 }
549 ASSERT_L( lua_gettop( L) == 1);
512 return 1; 550 return 1;
513} 551}
514 552
@@ -681,7 +719,7 @@ void keeper_toggle_nil_sentinels( lua_State* L, int _val_i, int _nil_to_sentinel
681* 719*
682* Returns: number of return values (pushed to 'L') or -1 in case of error 720* Returns: number of return values (pushed to 'L') or -1 in case of error
683*/ 721*/
684int keeper_call( lua_State *K, keeper_api_t _func, lua_State *L, void *linda, uint_t starting_index) 722int keeper_call( lua_State* K, keeper_api_t func_, lua_State* L, void* linda, uint_t starting_index)
685{ 723{
686 int const args = starting_index ? (lua_gettop( L) - starting_index + 1) : 0; 724 int const args = starting_index ? (lua_gettop( L) - starting_index + 1) : 0;
687 int const Ktos = lua_gettop( K); 725 int const Ktos = lua_gettop( K);
@@ -689,7 +727,7 @@ int keeper_call( lua_State *K, keeper_api_t _func, lua_State *L, void *linda, ui
689 727
690 STACK_GROW( K, 2); 728 STACK_GROW( K, 2);
691 729
692 PUSH_KEEPER_FUNC( K, _func); 730 PUSH_KEEPER_FUNC( K, func_);
693 731
694 lua_pushlightuserdata( K, linda); 732 lua_pushlightuserdata( K, linda);
695 733