libc_fs: Handle Packet_alloc_failed exception

This commit is contained in:
Norman Feske 2013-12-05 16:10:00 +01:00 committed by Christian Helmuth
parent 28c6763a7d
commit 2e6f281cf0

View File

@ -563,71 +563,78 @@ class Plugin : public Libc::Plugin
ssize_t read(Libc::File_descriptor *fd, void *buf, ::size_t count) ssize_t read(Libc::File_descriptor *fd, void *buf, ::size_t count)
{ {
File_system::Session::Tx::Source &source = *file_system()->tx(); try {
File_system::Session::Tx::Source &source = *file_system()->tx();
size_t const max_packet_size = source.bulk_buffer_size() / 2; size_t const max_packet_size = source.bulk_buffer_size() / 2;
size_t remaining_count = count; size_t remaining_count = count;
if (context(fd)->seek_offset() == ~0) if (context(fd)->seek_offset() == ~0)
context(fd)->seek_offset(0); context(fd)->seek_offset(0);
while (remaining_count) { while (remaining_count) {
collect_acknowledgements(source); collect_acknowledgements(source);
size_t curr_packet_size = Genode::min(remaining_count, max_packet_size); size_t curr_packet_size = Genode::min(remaining_count, max_packet_size);
/* off_t const seek_offset = context(fd)->seek_offset();
* XXX handle 'Packet_alloc_failed' exception'
*/
File_system::Packet_descriptor
packet(source.alloc_packet(curr_packet_size),
static_cast<File_system::Packet_ref *>(context(fd)),
context(fd)->node_handle(),
File_system::Packet_descriptor::READ,
curr_packet_size,
context(fd)->seek_offset());
/* mark context as having an operation in flight */ File_system::Packet_descriptor
context(fd)->in_flight = true; packet(source.alloc_packet(curr_packet_size),
static_cast<File_system::Packet_ref *>(context(fd)),
context(fd)->node_handle(),
File_system::Packet_descriptor::READ,
curr_packet_size,
context(fd)->seek_offset());
/* pass packet to server side */ /* mark context as having an operation in flight */
source.submit_packet(packet); context(fd)->in_flight = true;
do { /* pass packet to server side */
packet = source.get_acked_packet(); source.submit_packet(packet);
static_cast<Plugin_context *>(packet.ref())->in_flight = false;
} while (context(fd)->in_flight);
context(fd)->in_flight = false; do {
packet = source.get_acked_packet();
static_cast<Plugin_context *>(packet.ref())->in_flight = false;
/* if (packet.operation() == File_system::Packet_descriptor::WRITE)
* XXX check if acked packet belongs to request, source.release_packet(packet);
* needed for thread safety
*/
size_t read_num_bytes = Genode::min(packet.length(), curr_packet_size); } while (context(fd)->in_flight);
/* copy-out payload into destination buffer */ /*
memcpy(buf, source.packet_content(packet), read_num_bytes); * XXX check if acked packet belongs to request,
* needed for thread safety
*/
source.release_packet(packet); size_t read_num_bytes = Genode::min(packet.length(), curr_packet_size);
/* prepare next iteration */ /* copy-out payload into destination buffer */
context(fd)->advance_seek_offset(read_num_bytes); memcpy(buf, source.packet_content(packet), read_num_bytes);
buf = (void *)((Genode::addr_t)buf + read_num_bytes);
remaining_count -= read_num_bytes;
/* source.release_packet(packet);
* If we received less bytes than requested, we reached the end
* of the file. /* prepare next iteration */
*/ context(fd)->advance_seek_offset(read_num_bytes);
if (read_num_bytes < curr_packet_size) buf = (void *)((Genode::addr_t)buf + read_num_bytes);
break; remaining_count -= read_num_bytes;
/*
* If we received less bytes than requested, we reached the end
* of the file.
*/
if (read_num_bytes < curr_packet_size)
break;
}
return count - remaining_count;
} catch (File_system::Session::Tx::Source::Packet_alloc_failed) {
PERR("Packet_alloc_failed during read (count=%zd)", count);
return -1;
} }
return count - remaining_count;
} }
ssize_t readlink(const char *path, char *buf, size_t bufsiz) ssize_t readlink(const char *path, char *buf, size_t bufsiz)