ts/async_wrapper: remove fd from reactor before dropping its handle
The I/O handle was dropped prior to removing it from the reactor,
which caused Poller::delete
to fail due to an invalid file
descriptor. This used to happen silently unless the same fd was
added again, e.g. by changing states in the pipeline as follow:
Null -> Playing -> Null -> Playing.
In which case Poller::add
failed due to an already existing file.
This commit makes sure the fd is removed from the reactor prior to
dropping the handle. In order to achieve this, a new task is spawned
on the Context
on which the I/O was originally registered, allowing
it to access the proper Reactor
. The I/O can then safely be dropped.
Because the I/O handle is moved to the spawned future, this solution
requires adding the Send + 'static
bounds to the I/O handle used
within the Async
wrapper. This appears not too restrictive for
existing implementations though. Other attempts were considered,
but they would cause deadlocks.
This new approach also solves a potential race condition where a
fd could be re-registered in a Reactor
before it was removed.
Fixes: #208 (closed)