diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2012-06-12 07:47:33 +0200 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2012-06-12 07:47:33 +0200 |
commit | 2f1efc2d1f63adbd8099991ff9b0f0e35b52a26f (patch) | |
tree | 7e4df947ede97e509b33a68124c0319b304c8d1c /src/lanes.c | |
parent | ad54bd374ff86f2d523167fadfb07d36e223e966 (diff) | |
download | lanes-2f1efc2d1f63adbd8099991ff9b0f0e35b52a26f.tar.gz lanes-2f1efc2d1f63adbd8099991ff9b0f0e35b52a26f.tar.bz2 lanes-2f1efc2d1f63adbd8099991ff9b0f0e35b52a26f.zip |
* linda:receive() batched mode now accepts a max_count optional argument
Diffstat (limited to 'src/lanes.c')
-rw-r--r-- | src/lanes.c | 55 |
1 files changed, 36 insertions, 19 deletions
diff --git a/src/lanes.c b/src/lanes.c index d777be1..931af98 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -51,7 +51,7 @@ | |||
51 | * ... | 51 | * ... |
52 | */ | 52 | */ |
53 | 53 | ||
54 | char const* VERSION = "3.1.2"; | 54 | char const* VERSION = "3.1.3"; |
55 | 55 | ||
56 | /* | 56 | /* |
57 | =============================================================================== | 57 | =============================================================================== |
@@ -398,16 +398,16 @@ LUAG_FUNC( linda_send) | |||
398 | * Consumes a single value from the Linda, in any key. | 398 | * Consumes a single value from the Linda, in any key. |
399 | * Returns: received value (which is consumed from the slot), and the key which had it | 399 | * Returns: received value (which is consumed from the slot), and the key which had it |
400 | 400 | ||
401 | * [val1, ... valCOUNT]= linda_receive( linda_ud, [timeout_secs_num=-1], linda.batched, key_num|str|bool|lightuserdata, COUNT) | 401 | * [val1, ... valCOUNT]= linda_receive( linda_ud, [timeout_secs_num=-1], linda.batched, key_num|str|bool|lightuserdata, min_COUNT[, max_COUNT]) |
402 | * Consumes COUNT values from the linda, from a single key. | 402 | * Consumes between min_COUNT and max_COUNT values from the linda, from a single key. |
403 | * returns the COUNT consumed values, or nil if there weren't enough values to consume | 403 | * returns the actual consumed values, or nil if there weren't enough values to consume |
404 | * | 404 | * |
405 | */ | 405 | */ |
406 | #define BATCH_SENTINEL "270e6c9d-280f-4983-8fee-a7ecdda01475" | 406 | #define BATCH_SENTINEL "270e6c9d-280f-4983-8fee-a7ecdda01475" |
407 | LUAG_FUNC( linda_receive) | 407 | LUAG_FUNC( linda_receive) |
408 | { | 408 | { |
409 | struct s_Linda *linda = lua_toLinda( L, 1); | 409 | struct s_Linda *linda = lua_toLinda( L, 1); |
410 | int pushed, expected_pushed; | 410 | int pushed, expected_pushed_min, expected_pushed_max; |
411 | bool_t cancel = FALSE; | 411 | bool_t cancel = FALSE; |
412 | char *keeper_receive; | 412 | char *keeper_receive; |
413 | 413 | ||
@@ -426,27 +426,44 @@ LUAG_FUNC( linda_receive) | |||
426 | ++ key_i; | 426 | ++ key_i; |
427 | } | 427 | } |
428 | 428 | ||
429 | // make sure the keys are of a valid type | ||
430 | check_key_types( L, key_i, lua_gettop( L)); | ||
431 | |||
432 | // are we in batched mode? | 429 | // are we in batched mode? |
433 | lua_pushliteral( L, BATCH_SENTINEL); | ||
434 | if( lua_equal( L, key_i, -1)) | ||
435 | { | ||
436 | keeper_receive = "receive_batched"; | ||
437 | expected_pushed = (int)luaL_checkinteger( L, key_i + 2); | ||
438 | } | ||
439 | else | ||
440 | { | 430 | { |
441 | keeper_receive = "receive"; | 431 | int is_batched; |
442 | expected_pushed = 2; | 432 | lua_pushliteral( L, BATCH_SENTINEL); |
433 | is_batched = lua_equal( L, key_i, -1); | ||
434 | lua_pop( L, 1); | ||
435 | if( is_batched) | ||
436 | { | ||
437 | // no need to pass linda.batched in the keeper state | ||
438 | ++ key_i; | ||
439 | // make sure the keys are of a valid type | ||
440 | check_key_types( L, key_i, key_i); | ||
441 | // receive multiple values from a single slot | ||
442 | keeper_receive = "receive_batched"; | ||
443 | // we expect a user-defined amount of return value | ||
444 | expected_pushed_min = (int)luaL_checkinteger( L, key_i + 1); | ||
445 | expected_pushed_max = (int)luaL_optinteger( L, key_i + 2, expected_pushed_min); | ||
446 | if( expected_pushed_min > expected_pushed_max) | ||
447 | { | ||
448 | luaL_error( L, "batched min/max error"); | ||
449 | } | ||
450 | } | ||
451 | else | ||
452 | { | ||
453 | // make sure the keys are of a valid type | ||
454 | check_key_types( L, key_i, lua_gettop( L)); | ||
455 | // receive a single value, checking multiple slots | ||
456 | keeper_receive = "receive"; | ||
457 | // we expect a single (value, key) pair of returned values | ||
458 | expected_pushed_min = expected_pushed_max = 2; | ||
459 | } | ||
443 | } | 460 | } |
444 | lua_pop( L, 1); | ||
445 | 461 | ||
446 | { | 462 | { |
447 | struct s_Keeper *K = keeper_acquire( linda); | 463 | struct s_Keeper *K = keeper_acquire( linda); |
448 | for( ;;) | 464 | for( ;;) |
449 | { | 465 | { |
466 | // all arguments of receive() but the first are passed to the keeper's receive function | ||
450 | pushed = keeper_call( K->L, keeper_receive, L, linda, key_i); | 467 | pushed = keeper_call( K->L, keeper_receive, L, linda, key_i); |
451 | if( pushed < 0) | 468 | if( pushed < 0) |
452 | { | 469 | { |
@@ -454,7 +471,7 @@ LUAG_FUNC( linda_receive) | |||
454 | } | 471 | } |
455 | if( pushed > 0) | 472 | if( pushed > 0) |
456 | { | 473 | { |
457 | ASSERT_L( pushed == expected_pushed); | 474 | ASSERT_L( pushed >= expected_pushed_min && pushed <= expected_pushed_max); |
458 | // replace sentinels with real nils | 475 | // replace sentinels with real nils |
459 | keeper_toggle_nil_sentinels( L, lua_gettop( L) - pushed, 0); | 476 | keeper_toggle_nil_sentinels( L, lua_gettop( L) - pushed, 0); |
460 | // To be done from within the 'K' locking area | 477 | // To be done from within the 'K' locking area |