Skip to content

drivers: stop the ttl fiber in rw mode as well - #265

Open
maksimuimin wants to merge 1 commit into
tarantool:masterfrom
maksimuimin:fix-ttl-fiber-stop
Open

maksimuimin wants to merge 1 commit into
tarantool:masterfrom
maksimuimin:fix-ttl-fiber-stop

Conversation

@maksimuimin

Copy link
Copy Markdown

Closes #262

Problem

fifottl/limfifottl stop the ttl fiber through an unbuffered fiber.channel() that the fiber reads only in the box.info.ro branch. So while the instance is rw:

  • tube.raw:stop() blocks the caller forever;
  • tube:drop() never stops the fiber (fifottl has no drop()), leaking one fiber per dropped tube;
  • utubettl (buffered channel) returns from stop(), but the fiber keeps running and crashes on the dropped space.

Repro and details in #262.

Fix

The fiber now works while it is the fiber registered in self.fiber:

  • stop() deregisters the fiber, wakes it up and joins it, so it is guaranteed to be gone when stop()/drop() return, in rw and ro mode alike;
  • the iteration re-checks the registration before its long cond:wait(), so a stop request that arrives mid-iteration is not lost;
  • start() uses fiber.new() so the fiber cannot observe itself as unregistered before self.fiber is assigned;
  • fifottl got a drop() that stops the fiber before dropping the space;
  • limfifottl forwards start()/stop()/drop() to the parent object, otherwise self.fiber = nil in the wrapper would shadow the parent's registration and the fiber would never stop;
  • sync_chan is removed, the ro branch waits on the same cond with a 100 ms timeout as before.

New test t/260-ttl-fiber-stop.t covers stop/start/drop for all three drivers. Full suite passes locally (Tarantool 3.8, memtx and vinyl).

fifottl and limfifottl used an unbuffered channel to stop the ttl
fiber, but the fiber read it only in ro mode. So stop() blocked
forever in rw mode and drop() did not stop the fiber at all, leaking
one fiber per dropped tube. utubettl used a buffered channel: stop()
returned, but the fiber kept running and crashed on the dropped space.

Now the fiber works while it is the fiber registered in the tube:
stop() deregisters it, wakes it up and joins it, and fifottl got a
drop() which stops the fiber before dropping the space. limfifottl
forwards start()/stop()/drop() to the parent driver so that the
registration lives in a single object.

Closes tarantool#262

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fifottl/limfifottl: stop() blocks forever while RW, drop() leaks the TTL fiber

1 participant