mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-22 10:21:04 +00:00
vfs: process all acks in each iteration
This patch solves a corner case where one long-active job (e.g., read-ready request) stays at the beginning of the '_active_jobs' queue without an ack. In this case, the '_try_acknowledge_jobs' method would wrongly stop processing the subsequent acknowledgements. In practice, this can lead to a delayed sending of acknowledgements until new I/O or client requests occur. In particular, Vim in Sculpt's inspect window sometimes did not immediately respond to key presses during tab completion. Here, the read-ready request of the terminal prevented the acknowledgement for read of directory entry from being delivered until the next key was pressed. Fixes #3873
This commit is contained in:
parent
0605180a61
commit
17a6318ad6
@ -261,46 +261,36 @@ class Vfs_server::Session_component : private Session_resources,
|
|||||||
|
|
||||||
bool _try_acknowledge_jobs()
|
bool _try_acknowledge_jobs()
|
||||||
{
|
{
|
||||||
bool overall_progress = false;
|
bool progress = false;
|
||||||
|
|
||||||
for (;;) {
|
Node_queue requeued_nodes { };
|
||||||
if (!_stream.ready_to_ack())
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (_active_nodes.empty())
|
_active_nodes.dequeue_all([&] (Node &node) {
|
||||||
break;
|
|
||||||
|
|
||||||
bool progress_in_iteration = false;
|
if (!_stream.ready_to_ack()) {
|
||||||
|
requeued_nodes.enqueue(node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_active_nodes.dequeue([&] (Node &node) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Deliver only one acknowledgement per iteration to
|
|
||||||
* re-check the 'ready_to_ack' condition for each
|
|
||||||
* acknowledgement.
|
|
||||||
*/
|
|
||||||
if (node.acknowledgement_pending()) {
|
if (node.acknowledgement_pending()) {
|
||||||
_stream.acknowledge_packet(node.dequeue_acknowledgement());
|
_stream.acknowledge_packet(node.dequeue_acknowledgement());
|
||||||
progress_in_iteration = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there is still another acknowledgement pending, keep
|
* If there is still another acknowledgement pending,
|
||||||
* the node enqueud to process it in the next iteration.
|
* keep the node enqueud to process it in the next call of
|
||||||
* This can happen if there is a READ_READY acknowledgement
|
* '_try_acknowledge_jobs'. This can happen if there is a
|
||||||
* in addition to the acknowledgement of an operation.
|
* READ_READY acknowledgement in addition to the
|
||||||
|
* acknowledgement of an operation.
|
||||||
*/
|
*/
|
||||||
if (node.active())
|
if (node.active())
|
||||||
_active_nodes.enqueue(node);
|
requeued_nodes.enqueue(node);
|
||||||
});
|
});
|
||||||
|
|
||||||
overall_progress |= progress_in_iteration;
|
_active_nodes = requeued_nodes;
|
||||||
|
|
||||||
if (!progress_in_iteration)
|
return progress;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return overall_progress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user