mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 13:47:56 +00:00
libc_fs: Handle Packet_alloc_failed exception
This commit is contained in:
parent
28c6763a7d
commit
2e6f281cf0
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user