From fdc3d1dd2c3b120ff6426d074285908da7fb646d Mon Sep 17 00:00:00 2001 From: Konstantin Osipov <kostja@tarantool.org> Date: Thu, 17 Jul 2014 19:39:51 +0400 Subject: [PATCH] Implements gh-386; remove fiber.create(), fiber.resume(), fiber.detach() Make status() a method. Update the docs. --- doc/user/stored-procedures.xml | 108 ++-------- src/box/space.cc | 8 +- src/fiber.cc | 7 + src/fiber.h | 3 + src/lua/box_net_box.lua | 6 +- src/lua/fiber.cc | 322 ++---------------------------- src/trigger.h | 12 ++ test/app/init_script.result | 2 +- test/app/init_script.test.lua | 2 - test/box/box.net.box.result | 2 +- test/box/box.net.box.test.lua | 2 +- test/box/bsdsocket.result | 4 +- test/box/bsdsocket.test.lua | 4 +- test/box/configuration.test.py | 142 ------------- test/box/fiber.result | 354 +++++---------------------------- test/box/fiber.test.lua | 151 ++++---------- test/box/ipc.result | 14 +- test/box/ipc.test.lua | 14 +- test/box/lua/fiber.lua | 28 +-- test/box/print.result | 3 +- test/box/print.test.py | 2 +- test/box/session.result | 15 +- test/box/session.test.lua | 7 +- test/box/socket.result | 6 +- test/box/socket.test.py | 6 +- test/box/suite.ini | 2 +- test/box/transaction.result | 2 +- test/box/transaction.test.lua | 2 +- 28 files changed, 208 insertions(+), 1022 deletions(-) delete mode 100644 test/box/configuration.test.py diff --git a/doc/user/stored-procedures.xml b/doc/user/stored-procedures.xml index c50ad8fd4f..14d006ebc5 100644 --- a/doc/user/stored-procedures.xml +++ b/doc/user/stored-procedures.xml @@ -822,22 +822,10 @@ tarantool> box.space.tester:insert{20,msgpack.NULL,20} called the <emphasis>fiber function</emphasis>. A fiber has three possible states: running, suspended or dead. - When a fiber is created with <code>fiber.create()</code>, it is suspended. - When a fiber is started with <code>fiber.resume()</code>, it is running. - When a fiber yields control with <code>fiber.yield()</code>, it is suspended. + When a fiber is created with <code>fiber.create()</code>, it is running. + When a fiber yields control with <code>fiber.sleep()</code>, it is suspended. When a fiber ends (because the fiber function ends), it is dead. </para> - <para> - A fiber can also be attached or detached. - An attached fiber is a child of the creator, - and is running only if the creator has called - <code>fiber.resume()</code>. A detached fiber is a child of - the Tarantool internal <quote>sched</quote> fiber, and gets - scheduled only if there is a libev event associated - with it. - To detach, a running fiber should invoke <code>fiber.wrap()</code>. - A detached fiber loses connection with its parent forever. - </para> <para> All fibers are part of the fiber registry. This registry can be searched (<code>fiber.find()</code>) @@ -862,7 +850,7 @@ procedures. --> </para> <para> - The other potential problem comes from detached + The other potential problem comes from fibers which never get scheduled, because they are not subscribed to any events, or because no relevant events occur. Such morphing fibers can be killed with <code>fiber.cancel()</code> at any time, @@ -895,7 +883,7 @@ procedures. </term> <listitem> <para> - Returns: (type = userdata) <code>require('fiber')</code> + Returns: (type = userdata) <code>fiber</code> object for the currently scheduled fiber. </para> </listitem> @@ -910,104 +898,52 @@ procedures. Locate a fiber userdata object by id. </para> <para> - Returns: (type = userdata) require('fiber') object for the specified fiber. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <emphasis role="lua" xml:id="fiber.create">fiber.create(<replaceable>function-name</replaceable>) </emphasis> - </term> - <listitem> - <para> - Create a fiber. - </para> - <para> - Parameters: <code>function-name</code> = the function that the fiber is associated with. - </para> - <para> - Returns: (type = userdata) the require('fiber') object of the new fiber. - </para> - <para> - Possible errors: the function does not exist or if a recursion limit is hit. + Returns: (type = userdata) fiber object for the specified fiber. </para> </listitem> </varlistentry> <varlistentry> <term> - <emphasis role="lua" xml:id="fiber.resume">fiber.resume(<replaceable>fiber, ...</replaceable>) </emphasis> + <emphasis role="lua" xml:id="fiber.create">fiber.create(<replaceable>function, function-arguments</replaceable>)</emphasis> </term> <listitem> <para> - Resume a created - or suspended fiber. + Create and start a fiber. The fiber is + created and resumed immediately. </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <emphasis role="lua" xml:id="fiber.yield" xreflabel="fiber.yield">fiber.yield(<replaceable>yield-arguments</replaceable>) </emphasis> - </term> - <listitem> <para> - If the fiber is attached, yield control to the calling fiber if the fiber - is attached; otherwise, yield to sched. - </para> - <para> - Parameters: <code>yield-arguments</code>: - If the fiber is attached, arguments passed - to fiber.yield are passed on to the calling fiber. - If the fiber is detached, <code>fiber.yield()</code> - arguments passed to fiber.yield are returned after temporarily - yielding control back to the scheduler. - </para> - </listitem> - </varlistentry> - - <varlistentry> - <term> - <emphasis role="lua" xml:id="fiber.detach">fiber.detach()</emphasis> - </term> - <listitem> - <para> - Detach the current fiber. This is a cancellation point. This is a yield point. - It is usually more convenient to use <code>fiber.wrap()</code> to create - a fiber which is already detached when it is created. + Parameters: <code>function</code> = the function to be associated with the fiber, + <code>function-arguments</code> = what will be passed to the function. </para> </listitem> </varlistentry> <varlistentry> <term> - <emphasis role="lua" xml:id="fiber.wrap">fiber.wrap(<replaceable>function, function-arguments</replaceable>)</emphasis> + <emphasis role="lua" xml:id="fiber.sleep">fiber.sleep(<replaceable>time</replaceable>)</emphasis> </term> <listitem> <para> - This is a quick way to create and start a detached - fiber. The fiber is - created, detached, and resumed immediately. + Yield to the sched fiber and sleep for the specified number of seconds. + Only the current fiber can be made to sleep. </para> <para> - Parameters: <code>function</code> = the function to be associated with the fiber, - <code>function-arguments</code> = what will be passed to the function. + Parameters: <code>time</code> = number of seconds to sleep. </para> </listitem> </varlistentry> <varlistentry> <term> - <emphasis role="lua" xml:id="fiber.sleep">fiber.sleep(<replaceable>time</replaceable>)</emphasis> + <emphasis role="lua" xml:id="fiber.yield" xreflabel="fiber.yield">fiber.yield() </emphasis> </term> <listitem> <para> - Yield to the sched fiber and sleep for the specified number of seconds. - Only the current fiber can be made to sleep. + Yield control to the scheduler. Equivalent to <code>fiber.sleep(0)</code>. </para> <para> - Parameters: <code>time</code> = number of seconds to sleep. + Parameters: <code>none</code>. </para> </listitem> </varlistentry> @@ -1135,12 +1071,12 @@ Make a fiber, associate function_x with the fiber, and start function_x. It will immediately "detach" so it will be running independently of the caller. <programlisting> -<prompt>tarantool></prompt><userinput> fiber_of_x = fiber.wrap(function_x)</userinput> +<prompt>tarantool></prompt><userinput> fiber_of_x = fiber.create(function_x)</userinput> --- ...</programlisting> Get the id of the fiber (fid), to be used in later displays.<programlisting> -<prompt>tarantool></prompt><userinput> fid = fiber.wrap(function_x)</userinput> +<prompt>tarantool></prompt><userinput> fid = fiber.create(function_x)</userinput> --- ... </programlisting> @@ -1425,8 +1361,7 @@ end <para> Returns: (type = number) the unique identifier (ID) for the current session. The result can be 0 meaning - there is no session (for example because a function is - running in a detached fiber). + there is no session. </para> </listitem> </varlistentry> @@ -1896,8 +1831,7 @@ with an Artistic license. The expirationd.lua program is lengthy (about 500 lines), so here we will only highlight the matters that will be enhanced by studying the full source later. <programlisting> - task.worker_fiber = fiber.create(worker_loop) - task.worker_fiber:resume(task) + task.worker_fiber = fiber.create(worker_loop, task) log.info("expiration: task %q restarted", task.name) ... fiber.sleep(expirationd.constants.check_interval) diff --git a/src/box/space.cc b/src/box/space.cc index ebfc0681ce..1247052a84 100644 --- a/src/box/space.cc +++ b/src/box/space.cc @@ -119,13 +119,7 @@ space_delete(struct space *space) if (space->engine) delete space->engine; - struct trigger *trigger, *tmp; - rlist_foreach_entry_safe(trigger, &space->on_replace, link, tmp) { - trigger_clear(trigger); - if (trigger->destroy) - trigger->destroy(trigger); - - } + trigger_destroy(&space->on_replace); free(space); } diff --git a/src/fiber.cc b/src/fiber.cc index dd24d949ad..dfed60327a 100644 --- a/src/fiber.cc +++ b/src/fiber.cc @@ -36,6 +36,7 @@ #include "stat.h" #include "assoc.h" #include "memory.h" +#include "trigger.h" static struct cord main_cord; __thread struct cord *cord_ptr = NULL; @@ -201,6 +202,10 @@ fiber_yield(void) struct fiber *callee = *(--cord->sp); struct fiber *caller = cord->fiber; + /** By convention, these triggers must not throw. */ + if (! rlist_empty(&caller->on_yield)) + trigger_run(&caller->on_yield, NULL); + cord->fiber = callee; update_last_stack_frame(caller); @@ -441,6 +446,7 @@ fiber_new(const char *name, void (*f) (va_list)) rlist_add_entry(&cord->fibers, fiber, link); rlist_create(&fiber->state); + rlist_create(&fiber->on_yield); } fiber->f = f; @@ -472,6 +478,7 @@ fiber_destroy(struct fiber *f) if (strcmp(fiber_name(f), "sched") == 0) return; + trigger_destroy(&f->on_yield); rlist_del(&f->state); region_destroy(&f->gc); tarantool_coro_destroy(&f->coro); diff --git a/src/fiber.h b/src/fiber.h index 9797f859d5..0dd014c8d7 100644 --- a/src/fiber.h +++ b/src/fiber.h @@ -99,6 +99,9 @@ struct fiber { struct rlist link; struct rlist state; + /** Triggers invoked before this fiber yields. Must not throw. */ + struct rlist on_yield; + /* This struct is considered as non-POD when compiling by g++. * You can safetly ignore all offset_of-related warnings. * See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31488 diff --git a/src/lua/box_net_box.lua b/src/lua/box_net_box.lua index ae76dc81bb..517fe3fb07 100644 --- a/src/lua/box_net_box.lua +++ b/src/lua/box_net_box.lua @@ -353,9 +353,9 @@ local remote_methods = { self.timeouts = {} - fiber.wrap(function() self:_connect_worker() end) - fiber.wrap(function() self:_read_worker() end) - fiber.wrap(function() self:_write_worker() end) + fiber.create(function() self:_connect_worker() end) + fiber.create(function() self:_read_worker() end) + fiber.create(function() self:_write_worker() end) if self.opts.wait_connected == nil or self.opts.wait_connected then self:wait_connected() diff --git a/src/lua/fiber.cc b/src/lua/fiber.cc index 8300a12c2d..72a04d7fd9 100644 --- a/src/lua/fiber.cc +++ b/src/lua/fiber.cc @@ -45,23 +45,8 @@ extern "C" { /* {{{ box.fiber Lua library: access to Tarantool fibers * * Each fiber can be running, suspended or dead. - * A fiber is created (fiber.create()) suspended. - * It can be started with fiber.resume(), yield - * the control back with fiber.yield() end - * with return or just by reaching the end of the - * function. - * - * A fiber can also be attached or detached. - * An attached fiber is a child of the creator, - * and is running only if the creator has called - * fiber.resume(). A detached fiber is a child of - * Tarntool/Box internal 'sched' fiber, and gets - * scheduled only if there is a libev event associated - * with it. - * To detach itself, a running fiber must invoke - * fiber.detach(). - * A detached fiber loses connection with its parent - * forever. + * When a fiber is created (fiber.create()) it's + * running. * * All fibers are part of the fiber registry, fiber. * This registry can be searched either by @@ -85,7 +70,7 @@ extern "C" { * if it does a lot of computations and doesn't check * whether it's been cancelled (just don't do that). * - * The other potential problem comes from detached + * The other potential problem comes from * fibers which never get scheduled, because are subscribed * or get no events. Such morphing fibers can be killed * with fiber.cancel(), since fiber.cancel() @@ -94,7 +79,7 @@ extern "C" { static const char *fiberlib_name = "fiber"; -enum fiber_state { DONE, YIELD, DETACH }; +enum fiber_state { DONE, YIELD }; /** * @pre: stack top contains a table @@ -179,7 +164,7 @@ lbox_checkfiber(struct lua_State *L, int index) uint32_t fid = *(uint32_t *) luaL_checkudata(L, index, fiberlib_name); struct fiber *f = fiber_find(fid); if (f == NULL) - luaL_error(L, "fiber.resume(): the fiber is dead"); + luaL_error(L, "the fiber is dead"); return f; } @@ -222,46 +207,6 @@ box_lua_fiber_clear_coro(struct lua_State *L, struct fiber *f) lua_settable(L, LUA_REGISTRYINDEX); } -/** - * To yield control to the calling fiber - * we need to be able to find the caller of an - * attached fiber. Instead of passing the caller - * around on the child fiber stack, we create a - * weak table associated with child fiber - * lua_State, and save the caller in it. - * - * When the child fiber lua thread is garbage collected, - * the table is automatically cleared. - */ -static void -box_lua_fiber_push_caller(struct lua_State *child_L) -{ - luaL_getmetatable(child_L, fiberlib_name); - lua_getfield(child_L, -1, "callers"); - if (lua_isnil(child_L, -1)) { - lua_pop(child_L, 1); - lbox_create_weak_table(child_L, "callers"); - } - lua_pushthread(child_L); - lua_pushinteger(child_L, fiber()->fid); - lua_settable(child_L, -3); - /* Pop the fiberlib metatable and callers table. */ - lua_pop(child_L, 2); -} - -static struct fiber * -box_lua_fiber_get_caller(struct lua_State *L) -{ - luaL_getmetatable(L, fiberlib_name); - lua_getfield(L, -1, "callers"); - lua_pushthread(L); - lua_gettable(L, -2); - struct fiber *caller = fiber_find(lua_tointeger(L, -1)); - /* Pop the caller, the callers table, the fiberlib metatable. */ - lua_pop(L, 3); - return caller; -} - static int lbox_fiber_gc(struct lua_State *L) { @@ -365,124 +310,6 @@ lbox_fiber_info(struct lua_State *L) return 1; } -/** - * Detach the current fiber. - */ -static int -lbox_fiber_detach(struct lua_State *L) -{ - if (box_lua_fiber_get_coro(L, fiber()) == NULL) - luaL_error(L, "fiber.detach(): not attached"); - struct fiber *caller = box_lua_fiber_get_caller(L); - /* Clear the caller, to avoid a reference leak. */ - /* Request a detach. */ - lua_pushinteger(L, DETACH); - fiber_yield_to(caller); - return 0; -} - -static void -box_lua_fiber_run(va_list ap __attribute__((unused))) -{ - fiber_testcancel(); - fiber_setcancellable(false); - - struct lua_State *L = box_lua_fiber_get_coro(tarantool_L, fiber()); - /* - * Reference the coroutine to make sure it's not garbage - * collected when detached. - */ - lua_pushthread(L); - LuarefGuard coro_guard(L); - SessionGuard session_guard(-1, 0); - /* - * Lua coroutine.resume() returns true/false for - * completion status plus whatever the coroutine main - * function returns. Follow this style here. - */ - try { - lbox_call(L, lua_gettop(L) - 1, LUA_MULTRET); - /* push completion status */ - lua_pushboolean(L, true); - /* move 'true' to stack start */ - lua_insert(L, 1); - } catch (FiberCancelException *e) { - if (box_lua_fiber_get_coro(L, fiber())) { - struct fiber *caller = box_lua_fiber_get_caller(L); - fiber_wakeup(caller); - } - box_lua_fiber_clear_coro(tarantool_L, fiber()); - /* - * Note: FiberCancelException leaves garbage on - * coroutine stack. This is OK since it is only - * possible to cancel a fiber which is not - * scheduled, and cancel() is synchronous. - */ - - throw; - } catch (Exception *e) { - /* pop any possible garbage */ - lua_settop(L, 0); - /* completion status */ - lua_pushboolean(L, false); - /* error message */ - lua_pushstring(L, e->errmsg()); - - /* Always log the error. */ - e->log(); - } - /* - * L stack contains nothing but call results. - * If we're still attached, synchronously pass - * them to the caller, and then terminate. - */ - if (box_lua_fiber_get_coro(L, fiber())) { - struct fiber *caller = box_lua_fiber_get_caller(L); - lua_pushinteger(L, DONE); - fiber_yield_to(caller); - } -} - -/** @retval true if check failed, false otherwise */ -static bool -lbox_fiber_checkstack(struct lua_State *L) -{ - fiber_checkstack(); - struct fiber *f = fiber(); - const int MAX_STACK_DEPTH = 16; - int depth = 1; - while ((L = box_lua_fiber_get_coro(L, f)) != NULL) { - if (depth++ == MAX_STACK_DEPTH) - return true; - f = box_lua_fiber_get_caller(L); - } - return false; -} - - -static int -lbox_fiber_create(struct lua_State *L) -{ - if (lua_gettop(L) != 1 || !lua_isfunction(L, 1)) - luaL_error(L, "fiber.create(function): bad arguments"); - if (lbox_fiber_checkstack(L)) - luaL_error(L, "fiber.create(function): recursion limit" - " reached"); - - struct fiber *f = fiber_new("lua", box_lua_fiber_run); - /* Initially the fiber is cancellable */ - f->flags |= FIBER_USER_MODE | FIBER_CANCELLABLE; - - /* associate coro with fiber */ - lua_pushlightuserdata(L, f); - struct lua_State *child_L = lua_newthread(L); - lua_settable(L, LUA_REGISTRYINDEX); - /* Move the argument (function of the coro) to the new coro */ - lua_xmove(L, child_L, 1); - lbox_pushfiber(L, f); - return 1; -} - static int lbox_fiber_wakeup(struct lua_State *L) { @@ -491,65 +318,6 @@ lbox_fiber_wakeup(struct lua_State *L) return 0; } -static int -lbox_fiber_resume(struct lua_State *L) -{ - struct fiber *f = lbox_checkfiber(L, 1); - struct lua_State *child_L = box_lua_fiber_get_coro(L, f); - if (child_L == NULL) - luaL_error(L, "fiber.resume(): can't resume a " - "detached fiber"); - int nargs = lua_gettop(L) - 1; - if (nargs > 0) - lua_xmove(L, child_L, nargs); - /* dup 'out' for admin fibers */ - int fid = f->fid; - /* Silent compiler warnings in a release build. */ - (void) fid; - box_lua_fiber_push_caller(child_L); - /* - * We don't use fiber_call() since this breaks any sort - * of yield in the called fiber: for a yield to work, - * the callee got to be scheduled by 'sched'. - */ - fiber_yield_to(f); - /* - * The called fiber could have done 4 things: - * - yielded to us (then we should grab its return) - * - completed (grab return values, wake up the fiber, - * so that it can die) - * - detached (grab return values, wakeup the fiber so it - * can continue). - * - got cancelled (return) - */ - if (f->fid != fid) - luaL_error(L, "fiber.resume(): the child fiber got cancelled"); - /* Find out the state of the child fiber. */ - enum fiber_state child_state = (enum fiber_state) lua_tointeger(child_L, -1); - lua_pop(child_L, 1); - /* Get the results */ - nargs = lua_gettop(child_L); - lua_xmove(child_L, L, nargs); - if (child_state != YIELD) { - /* - * The fiber is dead or requested a detach. - * Garbage collect the associated coro. - */ - box_lua_fiber_clear_coro(L, f); - if (child_state == DETACH) { - /* - * Schedule the runaway child at least - * once. - */ - fiber_wakeup(f); - } else { - /* Synchronously reap a dead child. */ - fiber_call(f); - } - } - return nargs; -} - static void box_lua_fiber_run_detached(va_list ap) { @@ -571,10 +339,10 @@ box_lua_fiber_run_detached(va_list ap) * given the function and its arguments. */ static int -lbox_fiber_wrap(struct lua_State *L) +lbox_fiber_create(struct lua_State *L) { if (lua_gettop(L) < 1 || !lua_isfunction(L, 1)) - luaL_error(L, "fiber.wrap(function, ...): bad arguments"); + luaL_error(L, "fiber.create(function, ...): bad arguments"); fiber_checkstack(); struct fiber *f = fiber_new("lua", box_lua_fiber_run_detached); @@ -584,65 +352,11 @@ lbox_fiber_wrap(struct lua_State *L) int coro_ref = luaL_ref(L, LUA_REGISTRYINDEX); /* Move the arguments to the new coro */ lua_xmove(L, child_L, lua_gettop(L)); + lbox_pushfiber(L, f); fiber_call(f, coro_ref, child_L); - if (f->fid) - lbox_pushfiber(L, f); - else - lua_pushnil(L); return 1; } -/** - * Yield the current fiber. - * - * Yield control to the calling fiber -- if the fiber - * is attached, or to sched otherwise. - * If the fiber is attached, whatever arguments are passed - * to this call, are passed on to the calling fiber. - * If the fiber is detached, simply returns everything back. - */ -static int -lbox_fiber_yield(struct lua_State *L) -{ - /* - * Yield to the caller. The caller will take care of - * whatever arguments are taken. - */ - fiber_setcancellable(true); - struct lua_State *coro_L; - struct fiber *caller; - if ((coro_L = box_lua_fiber_get_coro(L, fiber())) && - (caller = box_lua_fiber_get_caller(coro_L))) { - lua_pushinteger(L, YIELD); - fiber_yield_to(caller); - } else { - fiber_wakeup(fiber()); - fiber_yield(); - fiber_testcancel(); - } - fiber_setcancellable(false); - /* - * Got resumed. Return whatever the caller has passed - * to us with fiber.resume(). - * As a side effect, the detached fiber which yields - * to sched always gets back whatever it yields. - */ - return lua_gettop(L); -} - -static bool -fiber_is_caller(struct lua_State *L, struct fiber *f) -{ - struct fiber *child = fiber(); - while ((L = box_lua_fiber_get_coro(L, child)) != NULL) { - struct fiber *caller = box_lua_fiber_get_caller(L); - if (caller == f) - return true; - child = caller; - } - return false; -} - /** * Get fiber status. * This follows the rules of Lua coroutine.status() function: @@ -673,9 +387,6 @@ lbox_fiber_status(struct lua_State *L) } else if (f == fiber()) { /* The fiber is the current running fiber. */ status = "running"; - } else if (fiber_is_caller(L, f)) { - /* The fiber is current fiber's caller. */ - status = "normal"; } else { /* None of the above: must be suspended. */ status = "suspended"; @@ -727,6 +438,15 @@ lbox_fiber_sleep(struct lua_State *L) return 0; } +static int +lbox_fiber_yield(struct lua_State * /* L */) +{ + fiber_setcancellable(true); + fiber_sleep(0); + fiber_setcancellable(false); + return 0; +} + static int lbox_fiber(struct lua_State *L) { @@ -798,7 +518,8 @@ static const struct luaL_reg lbox_fiber_meta [] = { {"name", lbox_fiber_name}, {"wakeup", lbox_fiber_wakeup}, {"cancel", lbox_fiber_cancel}, - {"resume", lbox_fiber_resume}, + {"status", lbox_fiber_status}, + {"testcancel", lbox_fiber_testcancel}, {"__gc", lbox_fiber_gc}, {NULL, NULL} }; @@ -806,18 +527,15 @@ static const struct luaL_reg lbox_fiber_meta [] = { static const struct luaL_reg fiberlib[] = { {"info", lbox_fiber_info}, {"sleep", lbox_fiber_sleep}, + {"yield", lbox_fiber_yield}, {"self", lbox_fiber}, {"id", lbox_fiber_id}, {"find", lbox_fiber_find}, {"cancel", lbox_fiber_cancel}, {"testcancel", lbox_fiber_testcancel}, {"create", lbox_fiber_create}, - {"resume", lbox_fiber_resume}, - {"wrap", lbox_fiber_wrap}, - {"yield", lbox_fiber_yield}, {"status", lbox_fiber_status}, {"name", lbox_fiber_name}, - {"detach", lbox_fiber_detach}, {"time", lbox_fiber_time}, {"time64", lbox_fiber_time64}, {NULL, NULL} diff --git a/src/trigger.h b/src/trigger.h index d230c3d88a..c64f05942e 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -92,4 +92,16 @@ trigger_clear(struct trigger *trigger) rlist_del_entry(trigger, link); } + +static inline void +trigger_destroy(struct rlist *list) +{ + struct trigger *trigger, *tmp; + rlist_foreach_entry_safe(trigger, list, link, tmp) { + trigger_clear(trigger); + if (trigger->destroy) + trigger->destroy(trigger); + } +} + #endif /* INCLUDES_TARANTOOL_TRIGGER_H */ diff --git a/test/app/init_script.result b/test/app/init_script.result index beb3341132..ce6ab4aa1b 100644 --- a/test/app/init_script.result +++ b/test/app/init_script.result @@ -28,7 +28,7 @@ box.cfg -- --- -[] +- [1, 2, 4, 8] ... -- diff --git a/test/app/init_script.test.lua b/test/app/init_script.test.lua index 41b523858a..4bc28a7a00 100755 --- a/test/app/init_script.test.lua +++ b/test/app/init_script.test.lua @@ -34,12 +34,10 @@ for k,v in pairs(t) do print(k, v) end -- Insert tests -- local function do_insert() - fiber.detach() space:insert{1, 2, 4, 8} end fiber1 = fiber.create(do_insert) -fiber.resume(fiber1) print[[ -- diff --git a/test/box/box.net.box.result b/test/box/box.net.box.result index d410e5032e..907414a7e5 100644 --- a/test/box/box.net.box.result +++ b/test/box/box.net.box.result @@ -302,7 +302,7 @@ cn:_select(space.id, 0, {}, { iterator = 'ALL' }) - [354, 1, 2, 4] ... -- -- error while waiting for response -type(fiber.wrap(function() fiber.sleep(.5) cn:_fatal('Test error') end)) +type(fiber.create(function() fiber.sleep(.5) cn:_fatal('Test error') end)) --- - userdata ... diff --git a/test/box/box.net.box.test.lua b/test/box/box.net.box.test.lua index 68e9356a6d..4911ce6a90 100644 --- a/test/box/box.net.box.test.lua +++ b/test/box/box.net.box.test.lua @@ -109,7 +109,7 @@ cn:_fatal 'Test error' cn:_select(space.id, 0, {}, { iterator = 'ALL' }) -- -- error while waiting for response -type(fiber.wrap(function() fiber.sleep(.5) cn:_fatal('Test error') end)) +type(fiber.create(function() fiber.sleep(.5) cn:_fatal('Test error') end)) function pause() fiber.sleep(10) return true end cn:call('pause') diff --git a/test/box/bsdsocket.result b/test/box/bsdsocket.result index 4c9fb2fdf4..2beae4da82 100644 --- a/test/box/bsdsocket.result +++ b/test/box/bsdsocket.result @@ -183,7 +183,7 @@ s:listen(128) sevres = {} --- ... -type(require('fiber').wrap(function() s:readable() do local sc = s:accept() table.insert(sevres, sc) sc:syswrite('ok') sc:close() end end)) +type(require('fiber').create(function() s:readable() do local sc = s:accept() table.insert(sevres, sc) sc:syswrite('ok') sc:close() end end)) --- - userdata ... @@ -832,7 +832,7 @@ sa:writable(0) ch = fiber.channel() --- ... -f = fiber.wrap(function() s:read(12) ch:put(true) end) +f = fiber.create(function() s:read(12) ch:put(true) end) --- ... fiber.sleep(.1) diff --git a/test/box/bsdsocket.test.lua b/test/box/bsdsocket.test.lua index 43a87179bb..394065bf9a 100644 --- a/test/box/bsdsocket.test.lua +++ b/test/box/bsdsocket.test.lua @@ -58,7 +58,7 @@ s:bind('127.0.0.1', 3457) s:error() s:listen(128) sevres = {} -type(require('fiber').wrap(function() s:readable() do local sc = s:accept() table.insert(sevres, sc) sc:syswrite('ok') sc:close() end end)) +type(require('fiber').create(function() s:readable() do local sc = s:accept() table.insert(sevres, sc) sc:syswrite('ok') sc:close() end end)) #sevres sc = socket('PF_INET', 'SOCK_STREAM', 'tcp') @@ -266,7 +266,7 @@ sa:readable(0) sa:writable(0) ch = fiber.channel() -f = fiber.wrap(function() s:read(12) ch:put(true) end) +f = fiber.create(function() s:read(12) ch:put(true) end) fiber.sleep(.1) s:close() ch:get(1) diff --git a/test/box/configuration.test.py b/test/box/configuration.test.py deleted file mode 100644 index d311508eb1..0000000000 --- a/test/box/configuration.test.py +++ /dev/null @@ -1,142 +0,0 @@ -import os -import sys -import shutil - -# mask BFD warnings: https://bugs.launchpad.net/tarantool/+bug/1018356 -sys.stdout.push_filter("unable to read unknown load command 0x2\d+", "") - -print """ -# Bug #876541: -# Test floating point values (wal_fsync_delay) with fractional part -# (https://bugs.launchpad.net/bugs/876541) -""" -# stop current server -server.stop() - -old_cfgfile = server.cfgfile_source -server.cfgfile_source = "box/tarantool_bug876541.cfg" -server.deploy() -# check values -admin("box.cfg.wal_fsync_delay") - -server.stop() -server.cfgfile_source = old_cfgfile -old_script = server.script -server.script = "box/lua/test_init.lua" -server.deploy() -sys.stdout.push_filter("admin: .*", "admin: <uri>") -sys.stdout.push_filter("listen: .*", "listen: <uri>") -admin("print_config()") -sys.stdout.pop_filter() -sys.stdout.pop_filter() - -print """ -# Test bug #977898 -""" -# Run a dummy insert to avoid race conditions under valgrind -admin("box.space.tweedledum:insert{4, 8, 16}") - -print """ -# Test insert from init.lua -""" -admin("box.space.tweedledum:get(1)") -admin("box.space.tweedledum:get(2)") -admin("box.space.tweedledum:get(4)") - -print """ -# Test bug #1002272 -""" -admin("floor(0.5)") -admin("floor(0.9)") -admin("floor(1.1)") -server.stop() -server.script = old_script - -# Test script_dir + require -old_script = server.script -server.script = "box/lua/require_init.lua" -server.lua_libs.append("box/lua/require_mod.lua") -server.deploy() -server.lua_libs.pop() -admin("mod.test(10, 15)") -server.stop() -server.script = old_script - - -print """ -# Bug#99 Salloc initialization is not checked on startup -# (https://github.com/tarantool/tarantool/issues/99) -""" -old_cfgfile = server.cfgfile_source -server.cfgfile_source="box/tarantool_bug_gh-99.cfg" -try: - server.deploy() -except OSError as e: - print e - print("ok") -server.stop() -server.cfgfile_source = old_cfgfile - -print """ -# Bug#100 Segmentation fault if rows_per_wal = 0 -# (https://github.com/tarantool/tarantool/issues/100) -""" -old_cfgfile = server.cfgfile_source -server.cfgfile_source = "box/tarantool_bug_gh100.cfg" -try: - server.deploy() -except OSError as e: - print e - print("ok") -server.stop() -server.cfgfile_source = old_cfgfile -print """# -# Check that --background doesn't work if there is no logger -# This is a test case for -# https://bugs.launchpad.net/tarantool/+bug/750658 -# "--background neither closes nor redirects stdin/stdout/stderr" -""" -old_cfgfile = server.cfgfile_source -server.cfgfile_source = "box/tarantool_bug750658.cfg" -try: - server.deploy() -except OSError as e: - print e - print("ok") - -server.stop() -server.cfgfile_source = old_cfgfile -print """ -# A test case for Bug#726778 "Gopt broke wal_dir and snap_dir: they are no -# longer relative to work_dir". -# https://bugs.launchpad.net/tarantool/+bug/726778 -# After addition of gopt(), we started to chdir() to the working -# directory after option parsing. -# Verify that this is not the case, and snap_dir and xlog_dir -# can be relative to work_dir. -""" -import shutil -vardir = server.vardir -shutil.rmtree(os.path.join(vardir, "bug726778"), True) -os.mkdir(os.path.join(vardir, "bug726778")) -os.mkdir(os.path.join(vardir, "bug726778/snapshots")) -os.mkdir(os.path.join(vardir, "bug726778/xlogs")) - -sys.stdout.push_filter("(/\S+)+/tarantool", "tarantool") -sys.stdout.push_filter(".*(P|p)lugin.*", "") -sys.stdout.push_filter(".*shared.*", "") -old_cfgfile = server.cfgfile_source -old_logfile = server.logfile -# make sure deploy() looks for start message in a correct -# place -server.logfile = os.path.join(vardir, "bug726778/tarantool.log") -server.cfgfile_source = "box/bug726778.cfg" -server.deploy() -sys.stdout.clear_all_filters() -server.stop() -shutil.rmtree(os.path.join(vardir, "bug726778")) -server.cfgfile_source = old_cfgfile -server.logfile = old_logfile - -# restore default server -server.deploy() diff --git a/test/box/fiber.result b/test/box/fiber.result index a6f61ceb1f..7d6971c765 100644 --- a/test/box/fiber.result +++ b/test/box/fiber.result @@ -215,7 +215,6 @@ space:truncate() -- test passing arguments in and out created fiber --# setopt delimiter ';' function y() - fiber.detach('started') space = box.space['tweedledum'] while true do space:replace{1953719668, os.time()} @@ -227,24 +226,17 @@ end; f = fiber.create(y); --- ... -fiber.resume(f); ---- -- started -... fiber.sleep(0.002); --- ... fiber.cancel(f); --- ... -fiber.resume(f); ---- -- error: 'fiber.resume(): the fiber is dead' -... +-- fiber garbage collection for k = 1, 1000, 1 do fiber.create( function() - fiber.detach() + fiber.sleep(0) end ) end; @@ -281,44 +273,40 @@ fiber.find('test') f = fiber.create(function() fiber.cancel(fiber.self()) end) --- ... -fiber.resume(f) ---- -- error: 'fiber.resume(): the child fiber got cancelled' -... f = nil --- ... -- https://github.com/tarantool/tarantool/issues/119 -ftest = function() fiber.sleep(0.01 * math.random() ) return true end +ftest = function() fiber.sleep(0.0001 * math.random() ) return true end --- ... --# setopt delimiter ';' +result = 0; +--- +... for i = 1, 10 do - result = {} + local res = {} for j = 1, 300 do - fiber.resume(fiber.create(function() - fiber.detach() - table.insert(result, ftest()) - end)) + fiber.create(function() table.insert(res, ftest()) end) end - while #result < 300 do fiber.sleep(0.01) end + while #res < 300 do fiber.sleep(0) end + result = result + #res end; --- ... --# setopt delimiter '' -#result +result --- -- 300 +- 3000 ... ---# setopt delimiter '' -- -- --- Test fiber.wrap() +-- Test fiber.create() -- -- This should try to infinitely create fibers, -- but hit the fiber stack size limit and fail -- with an error. -f = function() fiber.wrap(f) end +f = function() fiber.create(f) end --- ... f() @@ -327,7 +315,7 @@ f() -- -- Test argument passing -- -f = function(a, b) fiber.wrap(function(arg) result = arg end, a..b) end +f = function(a, b) fiber.create(function(arg) result = arg end, a..b) end --- ... f('hello ', 'world') @@ -347,9 +335,8 @@ result -- -- Test that the created fiber is detached -- -fiber.wrap(function() result = fiber.status() end) +local f = fiber.create(function() result = fiber.status() end) --- -- null ... result --- @@ -358,7 +345,7 @@ result -- A test case for Bug#933487 -- tarantool crashed during shutdown if non running LUA fiber -- was created -f = fiber.create(function () return true end) +f = fiber.create(function () fiber.sleep(1) return true end) --- ... box.snapshot() @@ -373,14 +360,10 @@ box.snapshot() --- - error: can't save snapshot, errno 17 (File exists) ... -fiber.resume(f) ---- -- true -- true -... -f = fiber.create(function () return true end) +f = fiber.create(function () fiber.sleep(1) end) --- ... +-- Test fiber.sleep() fiber.sleep(0) --- ... @@ -398,6 +381,7 @@ fiber.sleep(box, 0.001) --- - error: 'fiber.sleep(delay): bad arguments' ... +-- test fiber.self() fiber.cancel(fiber.self()) --- - error: 'fiber.cancel(): subject fiber does not permit cancel' @@ -431,105 +415,58 @@ f==g --- - true ... -function r() f = fiber.create(r) return (fiber.resume(f)) end ---- -... -r() ---- -- true -... +-- arguments to fiber.create f = fiber.create(print('hello')) --- -- error: '[string "f = fiber.create(print(''hello'')) "]:1: fiber.create(function): - bad arguments' -... -fiber.resume(f) ---- -- error: 'fiber.resume(): the fiber is dead' +- error: '[string "f = fiber.create(print(''hello'')) "]:1: fiber.create(function, + ...): bad arguments' ... -- test passing arguments in and out created fiber -function r(a, b) return a, b end +function r(a, b) res = { a, b } end --- ... f=fiber.create(r) --- ... -fiber.resume(f) ---- -- true -- null -- null -... -f=fiber.create(r) ---- -... -fiber.resume(f, 'hello') ---- -- true -- hello -- null -... -f=fiber.create(r) ---- -... -fiber.resume(f, 'hello', 'world') ---- -- true -- hello -- world -... -f=fiber.create(r) ---- -... -fiber.resume(f, 'hello', 'world', 'wide') ---- -- true -- hello -- world -... -function y(a, b) c=fiber.yield(a) return fiber.yield(b, c) end ---- -... -f=fiber.create(y) +while f:status() == 'running' do fiber.sleep(0) end --- ... -fiber.resume(f, 'hello', 'world') +res --- -- hello +- [] ... -fiber.resume(f, 'wide') +f=fiber.create(r, 'hello') --- -- world -- wide ... -fiber.resume(f) +while f:status() == 'running' do fiber.sleep(0) end --- -- true ... -function y() fiber.detach() while true do box.replace(0, 1953719668, os.time()) fiber.sleep(0.001) end end +res --- +- - hello ... -f = fiber.create(y) +f=fiber.create(r, 'hello, world') --- ... -fiber.resume(f) +while f:status() == 'running' do fiber.sleep(0) end --- ... -fiber.sleep(0.002) +res --- +- - hello, world ... -fiber.cancel(f) +f=fiber.create(r, 'hello', 'world', 'wide') --- -- error: 'fiber.resume(): the fiber is dead' ... -fiber.resume(f) +while f:status() == 'running' do fiber.sleep(0) end --- -- error: 'fiber.resume(): the fiber is dead' ... -f=nil +res --- +- - hello + - world ... -for k=1, 10000, 1 do fiber.create(function() fiber.detach() end) end +for k=1, 10000, 1 do fiber.create(function() fiber.sleep(0) end) end --- ... collectgarbage('collect') @@ -562,196 +499,19 @@ fiber.status(nil) --- - error: 'bad argument #1 to ''?'' (fiber expected, got nil)' ... --- A test case for Bug#911641 fiber.sleep() works incorrectly if --- a fiber is attached. -function r() return fiber.sleep(0.01) end ---- -... -f = fiber.create(r) ---- -... -fiber.resume(f) ---- -- true -... -fiber.resume(f) ---- -- error: 'fiber.resume(): the fiber is dead' -... ---# setopt delimiter ';' -function r() - fiber.yield(box.space.tweedledum:insert{0, 0, 1}) - fiber.yield(box.space.tweedledum:get{0}) - fiber.yield(box.space.tweedledum:truncate()) -end; ---- -... ---# setopt delimiter '' -f = fiber.create(r) ---- -... -fiber.resume(f) ---- -- [0, 0, 1] -... -fiber.resume(f) ---- -- [0, 0, 1] -... -fiber.resume(f) ---- -... -fiber.resume(f) ---- -- true -... -function r() return fiber.yield(fiber.create(r)) end ---- -... -f = r() ---- -... -f1 = fiber.resume(f) ---- -... -f2 = fiber.resume(f1) ---- -... -f3 = fiber.resume(f2) ---- -... -f4 = fiber.resume(f3) ---- -... -f5 = fiber.resume(f4) ---- -... -f6 = fiber.resume(f5) ---- -... -f7 = fiber.resume(f6) ---- -... -f8 = fiber.resume(f7) ---- -... -f9 = fiber.resume(f8) ---- -... -f10 = fiber.resume(f9) ---- -... -f11 = fiber.resume(f10) ---- -... -f12 = fiber.resume(f11) ---- -... -f13 = fiber.resume(f12) ---- -... -f14 = fiber.resume(f13) ---- -... -f15 = fiber.resume(f14) ---- -... -f16 = fiber.resume(f15) ---- -... -f17 = fiber.resume(f16) ---- -... -fiber.resume(f) ---- -- true -... -fiber.resume(f1) ---- -- true -... -fiber.resume(f2) ---- -- true -... -fiber.resume(f3) ---- -- true -... -fiber.resume(f4) ---- -- true -... -fiber.resume(f5) ---- -- true -... -fiber.resume(f6) ---- -- true -... -fiber.resume(f7) ---- -- true -... -fiber.resume(f8) ---- -- true -... -fiber.resume(f9) ---- -- true -... -fiber.resume(f10) ---- -- true -... -fiber.resume(f11) ---- -- true -... -fiber.resume(f12) ---- -- true -... -fiber.resume(f13) ---- -- true -... -fiber.resume(f14) ---- -- true -... -fiber.resume(f15) ---- -- true -... -fiber.resume(f16) ---- -- true -... -f17 = nil ---- -... -function r() fiber.detach() fiber.sleep(1000) end +-- test fiber.cancel +function r() fiber.sleep(1000) end --- ... f = fiber.create(r) --- ... -fiber.resume(f) ---- -... -fiber.resume(f) ---- -- error: 'fiber.resume(): can''t resume a detached fiber' -... fiber.cancel(f) --- ... -fiber.resume(f) +f:status() --- -- error: 'fiber.resume(): the fiber is dead' +- dead ... -- Test fiber.name() old_name = fiber.name() @@ -792,44 +552,36 @@ dofile("fiber.lua") -- print run fiber's test box_fiber_run_test() --- -- - 'tester: status(tester) = running' +- - 'A: odd 1' - 'tester: status(printer) = suspended' - 'count: 1' - - 'printer: tester status = normal' - - 'printer: printer status = running' - - 'A: odd 1' - 'status: suspended' - - 'count: 2' - 'B: odd 1' - 'C: event 2' + - 'count: 2' - 'status: suspended' - - 'count: 3' - 'A: odd 3' + - 'count: 3' - 'status: suspended' - - 'count: 4' - 'B: odd 3' - 'C: event 4' - 'D: event 4' - 'A: odd 5' + - 'count: 4' - 'status: suspended' - - 'count: 5' - 'B: odd 5' - - 'status: dead' ... +-- various... function testfun() while true do fiber.sleep(10) end end --- ... -f = fiber.wrap(testfun) +f = fiber.create(testfun) --- ... f:cancel() --- ... -f:resume() ---- -- error: 'fiber.resume(): the fiber is dead' -... -fib_id = fiber.wrap(testfun):id() +fib_id = fiber.create(testfun):id() --- ... fiber.find(fib_id):cancel() @@ -839,6 +591,6 @@ fiber.find(fib_id) --- - null ... -box.fiber = nil +fiber = nil --- ... diff --git a/test/box/fiber.test.lua b/test/box/fiber.test.lua index 87c8b1a03f..14078a4226 100644 --- a/test/box/fiber.test.lua +++ b/test/box/fiber.test.lua @@ -67,7 +67,6 @@ space:truncate() --# setopt delimiter ';' function y() - fiber.detach('started') space = box.space['tweedledum'] while true do space:replace{1953719668, os.time()} @@ -75,14 +74,13 @@ function y() end end; f = fiber.create(y); -fiber.resume(f); fiber.sleep(0.002); fiber.cancel(f); -fiber.resume(f); +-- fiber garbage collection for k = 1, 1000, 1 do fiber.create( function() - fiber.detach() + fiber.sleep(0) end ) end; @@ -98,39 +96,35 @@ fiber.find('test') -- https://github.com/tarantool/tarantool/issues/131 -- fiber.resume(fiber.cancel()) -- hang f = fiber.create(function() fiber.cancel(fiber.self()) end) -fiber.resume(f) f = nil -- https://github.com/tarantool/tarantool/issues/119 -ftest = function() fiber.sleep(0.01 * math.random() ) return true end +ftest = function() fiber.sleep(0.0001 * math.random() ) return true end --# setopt delimiter ';' +result = 0; for i = 1, 10 do - result = {} + local res = {} for j = 1, 300 do - fiber.resume(fiber.create(function() - fiber.detach() - table.insert(result, ftest()) - end)) + fiber.create(function() table.insert(res, ftest()) end) end - while #result < 300 do fiber.sleep(0.01) end + while #res < 300 do fiber.sleep(0) end + result = result + #res end; --# setopt delimiter '' -#result - ---# setopt delimiter '' +result -- -- --- Test fiber.wrap() +-- Test fiber.create() -- -- This should try to infinitely create fibers, -- but hit the fiber stack size limit and fail -- with an error. -f = function() fiber.wrap(f) end +f = function() fiber.create(f) end f() -- -- Test argument passing -- -f = function(a, b) fiber.wrap(function(arg) result = arg end, a..b) end +f = function(a, b) fiber.create(function(arg) result = arg end, a..b) end f('hello ', 'world') result f('bye ', 'world') @@ -138,23 +132,23 @@ result -- -- Test that the created fiber is detached -- -fiber.wrap(function() result = fiber.status() end) +local f = fiber.create(function() result = fiber.status() end) result -- A test case for Bug#933487 -- tarantool crashed during shutdown if non running LUA fiber -- was created -f = fiber.create(function () return true end) +f = fiber.create(function () fiber.sleep(1) return true end) box.snapshot() box.snapshot() box.snapshot() -fiber.resume(f) -f = fiber.create(function () return true end) - +f = fiber.create(function () fiber.sleep(1) end) +-- Test fiber.sleep() fiber.sleep(0) fiber.sleep(0.01) fiber.sleep(0.0001) fiber.sleep('hello') fiber.sleep(box, 0.001) +-- test fiber.self() fiber.cancel(fiber.self()) f = fiber.self() old_id = f:id() @@ -164,105 +158,37 @@ fiber.cancel(fiber.self()) fiber.self():id() - old_id < 5 g = fiber.self() f==g -function r() f = fiber.create(r) return (fiber.resume(f)) end -r() +-- arguments to fiber.create f = fiber.create(print('hello')) -fiber.resume(f) -- test passing arguments in and out created fiber -function r(a, b) return a, b end +function r(a, b) res = { a, b } end f=fiber.create(r) -fiber.resume(f) -f=fiber.create(r) -fiber.resume(f, 'hello') -f=fiber.create(r) -fiber.resume(f, 'hello', 'world') -f=fiber.create(r) -fiber.resume(f, 'hello', 'world', 'wide') -function y(a, b) c=fiber.yield(a) return fiber.yield(b, c) end -f=fiber.create(y) -fiber.resume(f, 'hello', 'world') -fiber.resume(f, 'wide') -fiber.resume(f) -function y() fiber.detach() while true do box.replace(0, 1953719668, os.time()) fiber.sleep(0.001) end end -f = fiber.create(y) -fiber.resume(f) -fiber.sleep(0.002) -fiber.cancel(f) -fiber.resume(f) -f=nil -for k=1, 10000, 1 do fiber.create(function() fiber.detach() end) end +while f:status() == 'running' do fiber.sleep(0) end +res +f=fiber.create(r, 'hello') +while f:status() == 'running' do fiber.sleep(0) end +res +f=fiber.create(r, 'hello, world') +while f:status() == 'running' do fiber.sleep(0) end +res +f=fiber.create(r, 'hello', 'world', 'wide') +while f:status() == 'running' do fiber.sleep(0) end +res +for k=1, 10000, 1 do fiber.create(function() fiber.sleep(0) end) end collectgarbage('collect') -- check that these newly created fibers are garbage collected fiber.find(9000) fiber.find(9010) fiber.find(9020) - -- test fiber.status functions: invalid arguments fiber.status(1) fiber.status('fafa-gaga') fiber.status(nil) - --- A test case for Bug#911641 fiber.sleep() works incorrectly if --- a fiber is attached. -function r() return fiber.sleep(0.01) end -f = fiber.create(r) -fiber.resume(f) -fiber.resume(f) ---# setopt delimiter ';' -function r() - fiber.yield(box.space.tweedledum:insert{0, 0, 1}) - fiber.yield(box.space.tweedledum:get{0}) - fiber.yield(box.space.tweedledum:truncate()) -end; ---# setopt delimiter '' +-- test fiber.cancel +function r() fiber.sleep(1000) end f = fiber.create(r) -fiber.resume(f) -fiber.resume(f) -fiber.resume(f) -fiber.resume(f) -function r() return fiber.yield(fiber.create(r)) end -f = r() -f1 = fiber.resume(f) -f2 = fiber.resume(f1) -f3 = fiber.resume(f2) -f4 = fiber.resume(f3) -f5 = fiber.resume(f4) -f6 = fiber.resume(f5) -f7 = fiber.resume(f6) -f8 = fiber.resume(f7) -f9 = fiber.resume(f8) -f10 = fiber.resume(f9) -f11 = fiber.resume(f10) -f12 = fiber.resume(f11) -f13 = fiber.resume(f12) -f14 = fiber.resume(f13) -f15 = fiber.resume(f14) -f16 = fiber.resume(f15) -f17 = fiber.resume(f16) -fiber.resume(f) -fiber.resume(f1) -fiber.resume(f2) -fiber.resume(f3) -fiber.resume(f4) -fiber.resume(f5) -fiber.resume(f6) -fiber.resume(f7) -fiber.resume(f8) -fiber.resume(f9) -fiber.resume(f10) -fiber.resume(f11) -fiber.resume(f12) -fiber.resume(f13) -fiber.resume(f14) -fiber.resume(f15) -fiber.resume(f16) -f17 = nil -function r() fiber.detach() fiber.sleep(1000) end -f = fiber.create(r) -fiber.resume(f) -fiber.resume(f) fiber.cancel(f) -fiber.resume(f) +f:status() -- Test fiber.name() old_name = fiber.name() fiber.name() == old_name @@ -279,12 +205,11 @@ space:drop() dofile("fiber.lua") -- print run fiber's test box_fiber_run_test() - +-- various... function testfun() while true do fiber.sleep(10) end end -f = fiber.wrap(testfun) +f = fiber.create(testfun) f:cancel() -f:resume() -fib_id = fiber.wrap(testfun):id() +fib_id = fiber.create(testfun):id() fiber.find(fib_id):cancel() fiber.find(fib_id) -box.fiber = nil +fiber = nil diff --git a/test/box/ipc.result b/test/box/ipc.result index ff17f0048e..9f98fbb22f 100644 --- a/test/box/ipc.result +++ b/test/box/ipc.result @@ -56,7 +56,7 @@ buffer = {} --- ... --# setopt delimiter ';' -tfbr = fiber.wrap( +tfbr = fiber.create( function() while true do table.insert(buffer, ch:get()) @@ -171,7 +171,7 @@ ch:is_empty() - true ... --# setopt delimiter ';' -tfbr = fiber.wrap( +tfbr = fiber.create( function() while true do local v = ch:get() @@ -181,7 +181,7 @@ tfbr = fiber.wrap( ); --- ... -tfbr2 = fiber.wrap( +tfbr2 = fiber.create( function() while true do local v = ch:get() @@ -300,7 +300,7 @@ ch:is_closed() passed = false --- ... -type(fiber.wrap(function() if ch:get() == nil then passed = true end end)) +type(fiber.create(function() if ch:get() == nil then passed = true end end)) --- - userdata ... @@ -341,7 +341,7 @@ ch:is_closed() passed = false --- ... -type(fiber.wrap(function() if ch:put(true) == false then passed = true end end)) +type(fiber.create(function() if ch:put(true) == false then passed = true end end)) --- - userdata ... @@ -383,7 +383,7 @@ for i = 1, 10 do table.insert(chs, fiber.channel()) end; --- ... for i = 1, 10 do - local no = i fiber.wrap( + local no = i fiber.create( function() fiber.self():name('pusher') while true do @@ -396,7 +396,7 @@ end; --- ... for i = 1, 10 do - local no = i fiber.wrap( + local no = i fiber.create( function() fiber.self():name('receiver') while true do diff --git a/test/box/ipc.test.lua b/test/box/ipc.test.lua index 4f53a2e697..fa2829234c 100644 --- a/test/box/ipc.test.lua +++ b/test/box/ipc.test.lua @@ -15,7 +15,7 @@ ch:is_full() ch:is_empty() buffer = {} --# setopt delimiter ';' -tfbr = fiber.wrap( +tfbr = fiber.create( function() while true do table.insert(buffer, ch:get()) @@ -48,7 +48,7 @@ ch:get() ch:is_full() ch:is_empty() --# setopt delimiter ';' -tfbr = fiber.wrap( +tfbr = fiber.create( function() while true do local v = ch:get() @@ -56,7 +56,7 @@ tfbr = fiber.wrap( end end ); -tfbr2 = fiber.wrap( +tfbr2 = fiber.create( function() while true do local v = ch:get() @@ -85,7 +85,7 @@ buffer ch = fiber.channel(1) ch:is_closed() passed = false -type(fiber.wrap(function() if ch:get() == nil then passed = true end end)) +type(fiber.create(function() if ch:get() == nil then passed = true end end)) ch:close() passed ch:get() @@ -97,7 +97,7 @@ ch = fiber.channel(1) ch:put(true) ch:is_closed() passed = false -type(fiber.wrap(function() if ch:put(true) == false then passed = true end end)) +type(fiber.create(function() if ch:put(true) == false then passed = true end end)) ch:close() passed ch:get() @@ -116,7 +116,7 @@ for i = 1, 10 do table.insert(chs, fiber.channel()) end; for i = 1, 10 do - local no = i fiber.wrap( + local no = i fiber.create( function() fiber.self():name('pusher') while true do @@ -128,7 +128,7 @@ for i = 1, 10 do end; for i = 1, 10 do - local no = i fiber.wrap( + local no = i fiber.create( function() fiber.self():name('receiver') while true do diff --git a/test/box/lua/fiber.lua b/test/box/lua/fiber.lua index adb53b8ef7..2bc8111f89 100644 --- a/test/box/lua/fiber.lua +++ b/test/box/lua/fiber.lua @@ -1,3 +1,4 @@ +local fiber = require('fiber') -- -------------------------------------------------------------------------- -- -- Local functions -- -------------------------------------------------------------------------- -- @@ -18,7 +19,7 @@ local result = {} -- odd printer local function odd(x) table.insert(result,'A: odd '..tostring(x)) - fiber.yield(x) + fiber.sleep(0.0) table.insert(result,'B: odd '..tostring(x)) end @@ -26,18 +27,16 @@ end local function even(x) table.insert(result,'C: event '..tostring(x)) if x == 2 then - return x + return end table.insert(result,'D: event '..tostring(x)) end -- printer task routine main function local function printer_task_routine(x) - table.insert(result, "printer: tester status = " .. fiber.status(tester_task)) - table.insert(result, "printer: printer status = " .. fiber.status(printer_task)) for i = 1, x do if i == 3 then - fiber.yield(-1) + fiber.sleep(0) end if i % 2 == 0 then even(i) @@ -48,21 +47,20 @@ local function printer_task_routine(x) end --- -------------------------------------------------------------------------- -- +------------------------------------------------------------------------ -- tester task routines --- -------------------------------------------------------------------------- -- +------------------------------------------------------------------------ -- tester task routine main function local function tester_task_routine() - printer_task = fiber.create(printer_task_routine) - table.insert(result, "tester: status(tester) = " .. fiber.status(tester_task)) - table.insert(result, "tester: status(printer) = " .. fiber.status(printer_task)) + printer_task = fiber.create(printer_task_routine, 5) + table.insert(result, "tester: status(printer) = " .. printer_task:status()) count = 1 - while fiber.status(printer_task) ~= "dead" do + while printer_task:status() ~= "dead" do table.insert(result, "count: " .. tostring(count)) - fiber.resume(printer_task, 5) - table.insert(result, "status: " .. fiber.status(printer_task)) + table.insert(result, "status: " .. printer_task:status()) count = count + 1 + fiber.sleep(0) end end @@ -75,6 +73,8 @@ end function box_fiber_run_test() -- run tester tester_task = fiber.create(tester_task_routine) - fiber.resume(tester_task) + while tester_task:status() ~= 'dead' do + fiber.sleep(0) + end return result end diff --git a/test/box/print.result b/test/box/print.result index e4cdb1491a..6ab6a18f26 100644 --- a/test/box/print.result +++ b/test/box/print.result @@ -4,9 +4,8 @@ print("Hello, world") io = require('io') --- ... -require('fiber').wrap(function() print('Ehllo, world') io.flush() end) +local f = require('fiber').create(function() print('Ehllo, world') io.flush() end) --- -- null ... require('fiber').sleep(0.1) --- diff --git a/test/box/print.test.py b/test/box/print.test.py index 9b0f56f0ec..5dfdd82e54 100644 --- a/test/box/print.test.py +++ b/test/box/print.test.py @@ -12,7 +12,7 @@ log = server.logfile f = open(log, "r") f.seek(0, 2) -admin("require('fiber').wrap(function() print('Ehllo, world') io.flush() end)") +admin("local f = require('fiber').create(function() print('Ehllo, world') io.flush() end)") admin("require('fiber').sleep(0.1)") line = f.readline() print("Check log line") diff --git a/test/box/session.result b/test/box/session.result index 841cc443fd..2c657ed58f 100644 --- a/test/box/session.result +++ b/test/box/session.result @@ -31,27 +31,16 @@ session.id() > 0 --- - true ... -f = fiber.create(function() fiber.detach() failed = session.id() == 0 end) +f = fiber.create(function() failed = session.id() == 0 end) --- ... -fiber.resume(f) +while f:status() ~= 'dead' do fiber.sleep(0) end --- ... failed --- - false ... -f1 = fiber.create(function() if session.id() == 0 then failed = true end end) ---- -... -fiber.resume(f1) ---- -- true -... -failed ---- -- false -... session.peer() == session.peer(session.id()) --- - true diff --git a/test/box/session.test.lua b/test/box/session.test.lua index 62a0435dc8..bbd09b4e04 100644 --- a/test/box/session.test.lua +++ b/test/box/session.test.lua @@ -11,11 +11,8 @@ session.exists(1234567890) -- check session.id() session.id() > 0 -f = fiber.create(function() fiber.detach() failed = session.id() == 0 end) -fiber.resume(f) -failed -f1 = fiber.create(function() if session.id() == 0 then failed = true end end) -fiber.resume(f1) +f = fiber.create(function() failed = session.id() == 0 end) +while f:status() ~= 'dead' do fiber.sleep(0) end failed session.peer() == session.peer(session.id()) diff --git a/test/box/socket.result b/test/box/socket.result index 56b3945ee1..01c87cd3c9 100644 --- a/test/box/socket.result +++ b/test/box/socket.result @@ -902,7 +902,7 @@ ping s:close() --- ... - replies = 0 packet = require('msgpack').encode({[0] = 64, [1] = 0}) packet = require('msgpack').encode(packet:len())..packet function bug1160869() local s = socket.tcp() s:connect('127.0.0.1', string.gsub(box.cfg.listen, '^.*:', '')) s:recv(128) require('fiber').wrap(function() while true do _, status = s:recv(18) if status == "eof" then error("unexpected eof") end replies = replies + 1 end end) return s:send(packet) end + replies = 0 packet = require('msgpack').encode({[0] = 64, [1] = 0}) packet = require('msgpack').encode(packet:len())..packet function bug1160869() local s = socket.tcp() s:connect('127.0.0.1', string.gsub(box.cfg.listen, '^.*:', '')) s:recv(128) require('fiber').create(function() while true do _, status = s:recv(18) if status == "eof" then error("unexpected eof") end replies = replies + 1 end end) return s:send(packet) end --- ... bug1160869() @@ -924,7 +924,7 @@ replies --- - 3 ... - s = nil syncno = 0 reps = 0 packet = require('msgpack').encode({[0] = 64, [1] = 0}) packet = require('msgpack').encode(packet:len())..packet function iostart() if s ~= nil then return end s = socket.tcp() s:connect('127.0.0.1', string.gsub(box.cfg.listen, '^.*:', '')) s:recv(128) require('fiber').wrap(function() while true do s:recv(18) if status == "eof" then error("unexpected eof") end reps = reps + 1 end end) end function iotest() iostart() syncno = syncno + 1 packet = require('msgpack').encode({[0] = 64, [1] = syncno}) packet = require('msgpack').encode(packet:len())..packet return s:send(packet) end + s = nil syncno = 0 reps = 0 packet = require('msgpack').encode({[0] = 64, [1] = 0}) packet = require('msgpack').encode(packet:len())..packet function iostart() if s ~= nil then return end s = socket.tcp() s:connect('127.0.0.1', string.gsub(box.cfg.listen, '^.*:', '')) s:recv(128) require('fiber').create(function() while true do s:recv(18) if status == "eof" then error("unexpected eof") end reps = reps + 1 end end) end function iotest() iostart() syncno = syncno + 1 packet = require('msgpack').encode({[0] = 64, [1] = syncno}) packet = require('msgpack').encode(packet:len())..packet return s:send(packet) end --- ... iotest() @@ -949,7 +949,7 @@ reps test_listen_done = false --- ... - function server() ms = socket.tcp() ms:bind('127.0.0.1', 8181) ms:listen() test_listen_done = true while true do local s = ms:accept( .5 ) if s ~= 'timeout' then print("accepted connection ", s) s:send('Hello world') s:shutdown(socket.SHUT_RDWR) end end end fbr = require('fiber').wrap(server) + function server() ms = socket.tcp() ms:bind('127.0.0.1', 8181) ms:listen() test_listen_done = true while true do local s = ms:accept( .5 ) if s ~= 'timeout' then print("accepted connection ", s) s:send('Hello world') s:shutdown(socket.SHUT_RDWR) end end end fbr = require('fiber').create(server) --- ... wait_cout = 100 while not test_listen_done and wait_cout > 0 do require('fiber').sleep(0.001) wait_cout = wait_cout - 1 end diff --git a/test/box/socket.test.py b/test/box/socket.test.py index f9b2b4b043..2085b4b1c4 100644 --- a/test/box/socket.test.py +++ b/test/box/socket.test.py @@ -518,7 +518,7 @@ function bug1160869() local s = socket.tcp() s:connect('127.0.0.1', string.gsub(box.cfg.listen, '^.*:', '')) s:recv(128) - require('fiber').wrap(function() + require('fiber').create(function() while true do _, status = s:recv(18) if status == "eof" then @@ -551,7 +551,7 @@ function iostart() s = socket.tcp() s:connect('127.0.0.1', string.gsub(box.cfg.listen, '^.*:', '')) s:recv(128) - require('fiber').wrap(function() + require('fiber').create(function() while true do s:recv(18) if status == "eof" then @@ -598,7 +598,7 @@ function server() end end -fbr = require('fiber').wrap(server) +fbr = require('fiber').create(server) """ admin("test_listen_done = false") admin(test.replace('\n', ' ')) diff --git a/test/box/suite.ini b/test/box/suite.ini index c4ed54055d..adc25b973e 100644 --- a/test/box/suite.ini +++ b/test/box/suite.ini @@ -2,7 +2,7 @@ core = tarantool description = tarantool/box, minimal configuration script = box.lua -disabled = configuration.test.py reconfigure.test.py +disabled = valgrind_disabled = admin_coredump.test.lua release_disabled = errinj.test.lua errinj_index.test.lua lua_libs = lua/fiber.lua lua/fifo.lua diff --git a/test/box/transaction.result b/test/box/transaction.result index c2f2e28ac6..1cf1fa1d15 100644 --- a/test/box/transaction.result +++ b/test/box/transaction.result @@ -45,7 +45,7 @@ function sloppy() end; --- ... -f = fiber.wrap(sloppy); +f = fiber.create(sloppy); --- ... -- when the sloppy fiber ends, its session has an active transction diff --git a/test/box/transaction.test.lua b/test/box/transaction.test.lua index 981430f48d..07260e2f8c 100644 --- a/test/box/transaction.test.lua +++ b/test/box/transaction.test.lua @@ -21,7 +21,7 @@ fiber = require('fiber'); function sloppy() box.begin() end; -f = fiber.wrap(sloppy); +f = fiber.create(sloppy); -- when the sloppy fiber ends, its session has an active transction -- ensure it's rolled back automatically fiber.sleep(0); -- GitLab