diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7ea7394a3dfdcd5e7acc34e4175f66d61b3457a8..c5f32aed79e10bee038a8364bee04e0b7cde19cd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -116,6 +116,7 @@ set (server_sources coio_buf.cc pickle.c ipc.c + fiber_cond.c latch.c errinj.c fio.c @@ -136,6 +137,7 @@ set (server_sources lua/digest.c lua/init.c lua/fiber.c + lua/fiber_cond.c lua/trigger.c lua/ipc.c lua/msgpack.c diff --git a/src/box/vy_mem.h b/src/box/vy_mem.h index 3c193e48145b94ad8f9a022631c0a920e1c7f6e0..4de7df923ec56102867f1fafa50f63cc8bd54b0a 100644 --- a/src/box/vy_mem.h +++ b/src/box/vy_mem.h @@ -36,7 +36,7 @@ #include <small/rlist.h> -#include "ipc.h" +#include "fiber_cond.h" #include "iterator_type.h" #include "vy_stmt.h" /* for comparators */ #include "vy_stmt_iterator.h" /* struct vy_stmt_iterator */ diff --git a/src/box/vy_run.c b/src/box/vy_run.c index ceae5d6a0b97161ecffd681f10125040c16138c6..db3f6453b7ec7d14022965d0fa9904ced83ce7b6 100644 --- a/src/box/vy_run.c +++ b/src/box/vy_run.c @@ -33,8 +33,8 @@ #include <zstd.h> #include "fiber.h" +#include "fiber_cond.h" #include "fio.h" -#include "ipc.h" #include "cbus.h" #include "memory.h" diff --git a/src/box/vy_run.h b/src/box/vy_run.h index 6b7fdc2057e309a9fff60ddfdc0cb904b760cbee..3e8e216bcb0be7303d3af1a9c15ee2ae8c615e41 100644 --- a/src/box/vy_run.h +++ b/src/box/vy_run.h @@ -34,7 +34,7 @@ #include <stdint.h> #include <stdbool.h> -#include "ipc.h" +#include "fiber_cond.h" #include "iterator_type.h" #include "vy_stmt.h" /* for comparators */ #include "vy_stmt_iterator.h" /* struct vy_stmt_iterator */ diff --git a/src/cbus.h b/src/cbus.h index 9431946561130a3a3dd69c8ec6f2c9349cd9afc6..df24e5e928198545a316a6ebdb1e4811304ae95c 100644 --- a/src/cbus.h +++ b/src/cbus.h @@ -31,8 +31,8 @@ * SUCH DAMAGE. */ #include "fiber.h" +#include "fiber_cond.h" #include "rmean.h" -#include "ipc.h" #include "small/rlist.h" #include "salad/stailq.h" diff --git a/src/fiber_cond.c b/src/fiber_cond.c new file mode 100644 index 0000000000000000000000000000000000000000..d81120d2db2e4af54831b1d6866b4a706e1664d1 --- /dev/null +++ b/src/fiber_cond.c @@ -0,0 +1,87 @@ +/* + * Copyright 2010-2017, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "fiber_cond.h" + +#include <tarantool_ev.h> + +#include "fiber.h" + +void +ipc_cond_create(struct ipc_cond *c) +{ + rlist_create(&c->waiters); +} + +void +ipc_cond_destroy(struct ipc_cond *c) +{ + (void)c; + assert(rlist_empty(&c->waiters)); +} + +void +ipc_cond_signal(struct ipc_cond *e) +{ + if (! rlist_empty(&e->waiters)) { + struct fiber *f; + f = rlist_shift_entry(&e->waiters, struct fiber, state); + fiber_wakeup(f); + } +} + +void +ipc_cond_broadcast(struct ipc_cond *e) +{ + while (! rlist_empty(&e->waiters)) { + struct fiber *f; + f = rlist_shift_entry(&e->waiters, struct fiber, state); + fiber_wakeup(f); + } +} + +int +ipc_cond_wait_timeout(struct ipc_cond *c, double timeout) +{ + struct fiber *f = fiber(); + rlist_add_tail_entry(&c->waiters, f, state); + if (fiber_yield_timeout(timeout)) { + diag_set(TimedOut); + return -1; + } + return 0; +} + +int +ipc_cond_wait(struct ipc_cond *c) +{ + return ipc_cond_wait_timeout(c, TIMEOUT_INFINITY); +} diff --git a/src/fiber_cond.h b/src/fiber_cond.h new file mode 100644 index 0000000000000000000000000000000000000000..8b1fe5436b30f9f87df6f1a31ee5b12c99f4750b --- /dev/null +++ b/src/fiber_cond.h @@ -0,0 +1,79 @@ +#ifndef TARANTOOL_FIBER_COND_H_INCLUDED +#define TARANTOOL_FIBER_COND_H_INCLUDED 1 +/* + * Copyright 2010-2017, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <small/rlist.h> + +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + +struct ipc_cond { + struct rlist waiters; +}; + +/** + * Initialize a cond - semantics as in POSIX condition variable. + */ +void +ipc_cond_create(struct ipc_cond *c); + +/** + * Finalize a cond. UB if there are fibers waiting for a cond. + */ +void +ipc_cond_destroy(struct ipc_cond *c); + +/** + * Wake one fiber waiting for the cond. + * Does nothing if no one is waiting. + */ +void +ipc_cond_signal(struct ipc_cond *c); + +/** + * Wake all fibers waiting for the cond. + */ +void +ipc_cond_broadcast(struct ipc_cond *c); + +int +ipc_cond_wait_timeout(struct ipc_cond *c, double timeout); + +int +ipc_cond_wait(struct ipc_cond *c); + +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* TARANTOOL_FIBER_COND_H_INCLUDED */ diff --git a/src/httpc.h b/src/httpc.h index 7c769bca2fa52899861ea6ba8ba4931f657fda45..02ba40467c64fb7a1f4f7cb8275ee384c7588199 100644 --- a/src/httpc.h +++ b/src/httpc.h @@ -33,9 +33,10 @@ #include <small/ibuf.h> #include <small/region.h> #include <small/mempool.h> +#include <tarantool_ev.h> #include "diag.h" -#include "ipc.h" +#include "fiber_cond.h" /** {{{ Environment */ diff --git a/src/ipc.c b/src/ipc.c index 9530a6a0171abfdeb4db834aa29ccf45dc367e59..18b511eec8effec07008f077ad9bf9f2ef314ce4 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -483,47 +483,4 @@ ipc_channel_get_msg_timeout(struct ipc_channel *ch, } } -void -ipc_cond_create(struct ipc_cond *c) -{ - rlist_create(&c->waiters); -} - -void -ipc_cond_destroy(struct ipc_cond *c) -{ - (void)c; - assert(rlist_empty(&c->waiters)); -} - -void -ipc_cond_signal(struct ipc_cond *e) -{ - if (! rlist_empty(&e->waiters)) { - struct fiber *f; - f = rlist_shift_entry(&e->waiters, struct fiber, state); - fiber_wakeup(f); - } -} -void -ipc_cond_broadcast(struct ipc_cond *e) -{ - while (! rlist_empty(&e->waiters)) { - struct fiber *f; - f = rlist_shift_entry(&e->waiters, struct fiber, state); - fiber_wakeup(f); - } -} - -int -ipc_cond_wait_timeout(struct ipc_cond *c, ev_tstamp timeout) -{ - struct fiber *f = fiber(); - rlist_add_tail_entry(&c->waiters, f, state); - if (fiber_yield_timeout(timeout)) { - diag_set(TimedOut); - return -1; - } - return 0; -} diff --git a/src/ipc.h b/src/ipc.h index 6eb7095ffa023065a3fbcee49a162167729f56cd..e2b622a6fd71e92208611736981a30afea8e0d53 100644 --- a/src/ipc.h +++ b/src/ipc.h @@ -367,43 +367,6 @@ ipc_channel_is_closed(struct ipc_channel *ch) return ch->is_closed; } -struct ipc_cond { - struct rlist waiters; -}; - -/** - * Initialize a cond - semantics as in POSIX condition variable. - */ -void -ipc_cond_create(struct ipc_cond *c); - -/** - * Finalize a cond. UB if there are fibers waiting for a cond. - */ -void -ipc_cond_destroy(struct ipc_cond *c); - -/** - * Wake one fiber waiting for the cond. - * Does nothing if no one is waiting. - */ -void -ipc_cond_signal(struct ipc_cond *c); - -/** - * Wake all fibers waiting for the cond. - */ -void -ipc_cond_broadcast(struct ipc_cond *c); - -int -ipc_cond_wait_timeout(struct ipc_cond *c, ev_tstamp timeout); - -static inline int -ipc_cond_wait(struct ipc_cond *c) -{ - return ipc_cond_wait_timeout(c, TIMEOUT_INFINITY); -} #if defined(__cplusplus) } /* extern "C" */ diff --git a/src/lua/fiber_cond.c b/src/lua/fiber_cond.c new file mode 100644 index 0000000000000000000000000000000000000000..12dba65d68b722de8f5e44e581d97f08d2b10682 --- /dev/null +++ b/src/lua/fiber_cond.c @@ -0,0 +1,133 @@ +/* + * Copyright 2010-2017, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "lua/fiber_cond.h" + +#include "third_party/tarantool_ev.h" + +#include "lua/utils.h" +#include "fiber.h" + +#include <fiber_cond.h> + +static const char cond_typename[] = "fiber.cond"; + +static int +lbox_ipc_cond(struct lua_State *L) +{ + struct ipc_cond *e = lua_newuserdata(L, sizeof(*e)); + if (e == NULL) + luaL_error(L, "fiber.cond: not enough memory"); + ipc_cond_create(e); + luaL_getmetatable(L, cond_typename); + lua_setmetatable(L, -2); + return 1; +} + +static inline struct ipc_cond * +lbox_check_cond(struct lua_State *L, int index, const char *source) +{ + if (index > lua_gettop(L)) + luaL_error(L, "usage: %s", source); + return (struct ipc_cond *)luaL_checkudata(L, index, cond_typename); +} + +static int +lbox_ipc_cond_gc(struct lua_State *L) +{ + ipc_cond_destroy(lbox_check_cond(L, 1, "cond:destroy()")); + return 0; +} + +static int +lbox_ipc_cond_signal(struct lua_State *L) +{ + ipc_cond_signal(lbox_check_cond(L, 1, "cond:signal()")); + return 0; +} + +static int +lbox_ipc_cond_broadcast(struct lua_State *L) +{ + ipc_cond_broadcast(lbox_check_cond(L, 1, "cond:broadcast()")); + return 0; +} + +static int +lbox_ipc_cond_wait(struct lua_State *L) +{ + static const char usage[] = "cond:wait([timeout])"; + int rc; + struct ipc_cond *e = lbox_check_cond(L, 1, usage); + ev_tstamp timeout = TIMEOUT_INFINITY; + if (!lua_isnoneornil(L, 2)) { + if (!lua_isnumber(L, 2) || + (timeout = lua_tonumber(L, 2)) < .0) { + luaL_error(L, "usage: %s", usage); + } + } + rc = ipc_cond_wait_timeout(e, timeout); + if (rc != 0) + luaL_testcancel(L); + lua_pushboolean(L, rc == 0); + return 1; +} + +static int +lbox_ipc_cond_to_string(struct lua_State *L) +{ + struct ipc_cond *cond = lbox_check_cond(L, 1, ""); + (void)cond; + lua_pushstring(L, "cond"); + return 1; +} + +void +tarantool_lua_fiber_cond_init(struct lua_State *L) +{ + static const struct luaL_Reg cond_meta[] = { + {"__gc", lbox_ipc_cond_gc}, + {"__tostring", lbox_ipc_cond_to_string}, + {"signal", lbox_ipc_cond_signal}, + {"broadcast", lbox_ipc_cond_broadcast}, + {"wait", lbox_ipc_cond_wait}, + {NULL, NULL} + }; + luaL_register_type(L, cond_typename, cond_meta); + + static const struct luaL_Reg cond_lib[] = { + {"cond", lbox_ipc_cond}, + {NULL, NULL} + }; + + luaL_register_module(L, "fiber", cond_lib); + lua_pop(L, 1); +} diff --git a/src/lua/fiber_cond.h b/src/lua/fiber_cond.h new file mode 100644 index 0000000000000000000000000000000000000000..9834a82471ba5404ff47e11ea22d257835c6c78e --- /dev/null +++ b/src/lua/fiber_cond.h @@ -0,0 +1,45 @@ +#ifndef TARANTOOL_LUA_FIBER_COND_H_INCLUDED +#define TARANTOOL_LUA_FIBER_COND_H_INCLUDED 1 +/* + * Copyright 2010-2017, Tarantool AUTHORS, please see AUTHORS file. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(__cplusplus) +extern "C" { +#endif /* defined(__cplusplus) */ + +struct lua_State; +void tarantool_lua_fiber_cond_init(struct lua_State *L); + +#if defined(__cplusplus) +} /* extern "C" */ +#endif /* defined(__cplusplus) */ + +#endif /* TARANTOOL_LUA_FIBER_COND_H_INCLUDED */ diff --git a/src/lua/init.c b/src/lua/init.c index 4f6842a232af3124c991ee3419f7742d721f13f1..44dcdf6157fb1761a1f78baf047bbdbfc64da3cd 100644 --- a/src/lua/init.c +++ b/src/lua/init.c @@ -45,6 +45,7 @@ #include "version.h" #include "coio.h" #include "lua/fiber.h" +#include "lua/fiber_cond.h" #include "lua/ipc.h" #include "lua/errno.h" #include "lua/socket.h" @@ -380,6 +381,7 @@ tarantool_lua_init(const char *tarantool_bin, int argc, char **argv) tarantool_lua_utils_init(L); tarantool_lua_fiber_init(L); + tarantool_lua_fiber_cond_init(L); tarantool_lua_ipc_init(L); tarantool_lua_errno_init(L); tarantool_lua_fio_init(L); diff --git a/src/lua/ipc.c b/src/lua/ipc.c index 8fbe3d335b5a7222b48210eff59c7ad7bfdbfa30..d9b29ff388ae5adcf63d5a11dddb76a25ff31907 100644 --- a/src/lua/ipc.c +++ b/src/lua/ipc.c @@ -47,7 +47,6 @@ luaL_error(lua_State *L, const char *fmt, ...); #include <fiber.h> static const char channel_typename[] = "fiber.channel"; -static const char cond_typename[] = "fiber.cond"; /******************** channel ***************************/ @@ -272,76 +271,6 @@ lbox_ipc_channel_to_string(struct lua_State *L) return 1; } -static int -lbox_ipc_cond(struct lua_State *L) -{ - struct ipc_cond *e = lua_newuserdata(L, sizeof(*e)); - if (e == NULL) - luaL_error(L, "fiber.cond: not enough memory"); - ipc_cond_create(e); - luaL_getmetatable(L, cond_typename); - lua_setmetatable(L, -2); - return 1; -} - -static inline struct ipc_cond * -lbox_check_cond(struct lua_State *L, int index, const char *source) -{ - if (index > lua_gettop(L)) - luaL_error(L, "usage: %s", source); - return (struct ipc_cond *)luaL_checkudata(L, index, cond_typename); -} - -static int -lbox_ipc_cond_gc(struct lua_State *L) -{ - ipc_cond_destroy(lbox_check_cond(L, 1, "cond:destroy()")); - return 0; -} - -static int -lbox_ipc_cond_signal(struct lua_State *L) -{ - ipc_cond_signal(lbox_check_cond(L, 1, "cond:signal()")); - return 0; -} - -static int -lbox_ipc_cond_broadcast(struct lua_State *L) -{ - ipc_cond_broadcast(lbox_check_cond(L, 1, "cond:broadcast()")); - return 0; -} - -static int -lbox_ipc_cond_wait(struct lua_State *L) -{ - static const char usage[] = "cond:wait([timeout])"; - int rc; - struct ipc_cond *e = lbox_check_cond(L, 1, usage); - ev_tstamp timeout = TIMEOUT_INFINITY; - if (!lua_isnoneornil(L, 2)) { - if (!lua_isnumber(L, 2) || - (timeout = lua_tonumber(L, 2)) < .0) { - luaL_error(L, "usage: %s", usage); - } - } - rc = ipc_cond_wait_timeout(e, timeout); - if (rc != 0) - luaL_testcancel(L); - lua_pushboolean(L, rc == 0); - return 1; -} - -static int -lbox_ipc_cond_to_string(struct lua_State *L) -{ - struct ipc_cond *cond = lbox_check_cond(L, 1, ""); - (void)cond; - lua_pushstring(L, "cond"); - return 1; -} - void tarantool_lua_ipc_init(struct lua_State *L) { @@ -362,19 +291,8 @@ tarantool_lua_ipc_init(struct lua_State *L) }; luaL_register_type(L, channel_typename, channel_meta); - static const struct luaL_Reg cond_meta[] = { - {"__gc", lbox_ipc_cond_gc}, - {"__tostring", lbox_ipc_cond_to_string}, - {"signal", lbox_ipc_cond_signal}, - {"broadcast", lbox_ipc_cond_broadcast}, - {"wait", lbox_ipc_cond_wait}, - {NULL, NULL} - }; - luaL_register_type(L, cond_typename, cond_meta); - static const struct luaL_Reg ipc_lib[] = { {"channel", lbox_ipc_channel}, - {"cond", lbox_ipc_cond}, {NULL, NULL} }; diff --git a/test/app/fiber_cond.result b/test/app/fiber_cond.result new file mode 100644 index 0000000000000000000000000000000000000000..f592de6cc49aa8c1d4aa09f2cd86a080b566ccf9 --- /dev/null +++ b/test/app/fiber_cond.result @@ -0,0 +1,69 @@ +fiber = require('fiber') +--- +... +-- fiber.cond +c = fiber.cond() +--- +... +tostring(c) +--- +- cond +... +-- args validation +c.wait() +--- +- error: 'usage: cond:wait([timeout])' +... +c.wait('1') +--- +- error: 'bad argument #1 to ''?'' (fiber.cond expected, got string)' +... +c:wait('1') +--- +- false +... +c:wait(-1) +--- +- error: 'usage: cond:wait([timeout])' +... +-- timeout +c:wait(0.1) +--- +- false +... +-- wait success +fiber.create(function() fiber.sleep(.5); c:broadcast() end) and c:wait(.6) +--- +- true +... +-- signal +t = {} +--- +... +for i = 1,4 do fiber.create(function() c:wait(); table.insert(t, '#') end) end +--- +... +c:signal() +--- +... +fiber.sleep(0.1) +--- +... +t +--- +- - '#' +... +-- broadcast +c:broadcast() +--- +... +fiber.sleep(0.1) +--- +... +t +--- +- - '#' + - '#' + - '#' + - '#' +... diff --git a/test/app/fiber_cond.test.lua b/test/app/fiber_cond.test.lua new file mode 100644 index 0000000000000000000000000000000000000000..4ecb00f0bae9b1e4455e1cec54149f2039a85630 --- /dev/null +++ b/test/app/fiber_cond.test.lua @@ -0,0 +1,24 @@ +fiber = require('fiber') + +-- fiber.cond +c = fiber.cond() +tostring(c) +-- args validation +c.wait() +c.wait('1') +c:wait('1') +c:wait(-1) +-- timeout +c:wait(0.1) +-- wait success +fiber.create(function() fiber.sleep(.5); c:broadcast() end) and c:wait(.6) +-- signal +t = {} +for i = 1,4 do fiber.create(function() c:wait(); table.insert(t, '#') end) end +c:signal() +fiber.sleep(0.1) +t +-- broadcast +c:broadcast() +fiber.sleep(0.1) +t diff --git a/test/app/ipc.result b/test/app/ipc.result index a8161962bd6cc5466369588eb42cccea88080afc..bb6fc30eac63f1745f5469e6e75f0c8f8253e777 100644 --- a/test/app/ipc.result +++ b/test/app/ipc.result @@ -578,69 +578,3 @@ refs -- must be zero --- - 0 ... --- fiber.cond -c = fiber.cond() ---- -... -tostring(c) ---- -- cond -... --- args validation -c.wait() ---- -- error: 'usage: cond:wait([timeout])' -... -c.wait('1') ---- -- error: 'bad argument #1 to ''?'' (fiber.cond expected, got string)' -... -c:wait('1') ---- -- false -... -c:wait(-1) ---- -- error: 'usage: cond:wait([timeout])' -... --- timeout -c:wait(0.1) ---- -- false -... --- wait success -fiber.create(function() fiber.sleep(.5); c:broadcast() end) and c:wait(.6) ---- -- true -... --- signal -t = {} ---- -... -for i = 1,4 do fiber.create(function() c:wait(); table.insert(t, '#') end) end ---- -... -c:signal() ---- -... -fiber.sleep(0.1) ---- -... -t ---- -- - '#' -... --- broadcast -c:broadcast() ---- -... -fiber.sleep(0.1) ---- -... -t ---- -- - '#' - - '#' - - '#' - - '#' -... diff --git a/test/app/ipc.test.lua b/test/app/ipc.test.lua index ae0fd384d5f04dac30b2f7b7e7e5cb43b68a1d37..78e176c59bd6e1606917fa7499eb5f053ba3ccf9 100644 --- a/test/app/ipc.test.lua +++ b/test/app/ipc.test.lua @@ -210,26 +210,3 @@ refs ch:close() collectgarbage('collect') refs -- must be zero - --- fiber.cond -c = fiber.cond() -tostring(c) --- args validation -c.wait() -c.wait('1') -c:wait('1') -c:wait(-1) --- timeout -c:wait(0.1) --- wait success -fiber.create(function() fiber.sleep(.5); c:broadcast() end) and c:wait(.6) --- signal -t = {} -for i = 1,4 do fiber.create(function() c:wait(); table.insert(t, '#') end) end -c:signal() -fiber.sleep(0.1) -t --- broadcast -c:broadcast() -fiber.sleep(0.1) -t