Ref T10849. I'm going to wait for the release cut to pursue this since it's the kind of change that could cause weird stuff to happen, but it appears to work properly.
To execute a query with a timeout, we use the MySQLi "async" API, and just resolve the query synchronously inline. This lets us throw if too much time has passed.