fiber: destroy fiber.storage created by iproto
Fiber.storage was not deleted when created in a fiber started from the thread pool used by IProto requests. The problem was that fiber.storage was created and deleted in Lua land only, assuming that only Lua-born fibers could have it. But in fact any fiber can create a Lua storage. Including the ones used to serve IProto requests. Not deletion of the storage led to a possibility of meeting a non-empty fiber.storage in the beginning of an iproto request, and to not deletion of the memory caught by the storage until its explicit nullification. Now the storage destructor works for any fiber, which managed to create the storage. The destructor unrefs and nullifies the storage. For destructor purposes the fiber.on_stop triggers were reworked. Now they can be called multiple times during fiber's lifetime. After every request done by that fiber. Closes #4662 Closes #3462 @TarantoolBot document Title: Clarify fiber.storage lifetime Fiber.storage is a Lua table created when it is first accessed. On the site it is said that it is deleted when fiber is canceled via fiber:cancel(). But it is not the full truth. Fiber.storage is destroyed when the fiber is finished. Regardless of how is it finished - via :cancel(), or the fiber's function did 'return', it does not matter. Moreover, from that moment the storage is cleaned up even for pooled fibers used to serve IProto requests. Pooled fibers never really die, but nonetheless their storage is cleaned up after each request. That makes possible to use fiber.storage as a full featured request-local storage. Fiber.storage may be created for a fiber no matter how the fiber itself was created - from C, from Lua. For example, a fiber could be created in C using fiber_new(), then it could insert into a space, which had Lua on_replace triggers, and one of the triggers could create fiber.storage. That storage will be deleted when the fiber is stopped. Another place where fiber.storage may be created - for replication applier fiber. Applier has a fiber from which it applies transactions from a remote instance. In case the applier fiber somehow creates a fiber.storage (for example, from a space trigger again), the storage won't be deleted until the applier fiber is stopped. (cherry picked from commit 7692e08f)
Showing
- src/box/iproto.cc 5 additions, 2 deletionssrc/box/iproto.cc
- src/lib/core/fiber.c 21 additions, 3 deletionssrc/lib/core/fiber.c
- src/lib/core/fiber.h 13 additions, 1 deletionsrc/lib/core/fiber.h
- src/lib/core/fiber_pool.c 10 additions, 0 deletionssrc/lib/core/fiber_pool.c
- src/lua/fiber.c 29 additions, 5 deletionssrc/lua/fiber.c
- test/app/gh-4662-fiber-storage-leak.result 88 additions, 0 deletionstest/app/gh-4662-fiber-storage-leak.result
- test/app/gh-4662-fiber-storage-leak.test.lua 43 additions, 0 deletionstest/app/gh-4662-fiber-storage-leak.test.lua
Loading
Please register or sign in to comment