libc_fs: handle 'Packet_alloc_failed' exception

With this patch, when a 'Packet_alloc_failed' exception occurs in the
'write()' function, the function waits for a packet acknowledgement and
the release of the packet and then tries the packet allocation again.

Fixes #348.
This commit is contained in:
Christian Prochaska 2012-09-06 15:40:58 +02:00 committed by Norman Feske
parent 6994f6a8c5
commit 3cfc691c77

View File

@ -684,30 +684,33 @@ class Plugin : public Libc::Plugin
size_t curr_packet_size = Genode::min(remaining_count, max_packet_size); size_t curr_packet_size = Genode::min(remaining_count, max_packet_size);
/* try {
* XXX handle 'Packet_alloc_failed' exception' File_system::Packet_descriptor
*/ packet(source.alloc_packet(curr_packet_size),
File_system::Packet_descriptor static_cast<File_system::Packet_ref *>(context(fd)),
packet(source.alloc_packet(curr_packet_size), context(fd)->node_handle(),
static_cast<File_system::Packet_ref *>(context(fd)), File_system::Packet_descriptor::WRITE,
context(fd)->node_handle(), curr_packet_size,
File_system::Packet_descriptor::WRITE, context(fd)->seek_offset());
curr_packet_size,
context(fd)->seek_offset());
/* mark context as having an operation in flight */ /* mark context as having an operation in flight */
context(fd)->in_flight = true; context(fd)->in_flight = true;
/* copy-in payload into packet */ /* copy-in payload into packet */
memcpy(source.packet_content(packet), buf, curr_packet_size); memcpy(source.packet_content(packet), buf, curr_packet_size);
/* pass packet to server side */ /* pass packet to server side */
source.submit_packet(packet); source.submit_packet(packet);
/* prepare next iteration */ /* prepare next iteration */
context(fd)->advance_seek_offset(curr_packet_size); context(fd)->advance_seek_offset(curr_packet_size);
buf = (void *)((Genode::addr_t)buf + curr_packet_size); buf = (void *)((Genode::addr_t)buf + curr_packet_size);
remaining_count -= curr_packet_size; remaining_count -= curr_packet_size;
} catch (File_system::Session::Tx::Source::Packet_alloc_failed) {
do {
wait_for_acknowledgement(source);
} while (context(fd)->in_flight);
}
} }
PDBG("write returns %zd", count); PDBG("write returns %zd", count);