mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-12 05:41:36 +00:00
Cached_fs_rom: fix congestion error
When the cached_fs_rom saturates the packet stream of its File_system session it will call the session request handler recursively as pending transfers are completed. This is bad because the content of the XML node currently being processed will change. The session request handler can no longer be called directly, but the "schedule" method will submit a signal to the request handler, and requests will be processed after the current operation has completed.
This commit is contained in:
parent
ac0562ec18
commit
7e08bba25c
@ -310,18 +310,6 @@ struct Cached_fs_rom::Main final : Genode::Session_request_handler
|
||||
Io_signal_handler<Main> packet_handler {
|
||||
env.ep(), *this, &Main::handle_packets };
|
||||
|
||||
/**
|
||||
* Signal handler to disable blocking behavior in 'Expanding_parent_client'
|
||||
*/
|
||||
Signal_handler<Main> resource_handler {
|
||||
env.ep(), *this, &Main::handle_resources };
|
||||
|
||||
/**
|
||||
* Process requests again if parent gives us an upgrade
|
||||
*/
|
||||
void handle_resources() {
|
||||
session_requests.process(); }
|
||||
|
||||
/**
|
||||
* Return true when a cache element is freed
|
||||
*/
|
||||
@ -489,7 +477,7 @@ struct Cached_fs_rom::Main final : Genode::Session_request_handler
|
||||
{
|
||||
rom.process_packet(pkt);
|
||||
if (rom.completed())
|
||||
session_requests.process();
|
||||
session_requests.schedule();
|
||||
stray_pkt = false;
|
||||
});
|
||||
|
||||
@ -500,12 +488,13 @@ struct Cached_fs_rom::Main final : Genode::Session_request_handler
|
||||
|
||||
Main(Genode::Env &env) : env(env)
|
||||
{
|
||||
env.parent().resource_avail_sigh(resource_handler);
|
||||
/* process the requests when more resources are made available */
|
||||
env.parent().resource_avail_sigh(session_requests);
|
||||
|
||||
fs.sigh_ack_avail(packet_handler);
|
||||
|
||||
/* process any requests that have already queued */
|
||||
session_requests.process();
|
||||
session_requests.schedule();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -35,7 +35,7 @@ struct Genode::Session_request_handler : Interface
|
||||
};
|
||||
|
||||
|
||||
class Genode::Session_requests_rom
|
||||
class Genode::Session_requests_rom : public Signal_handler<Session_requests_rom>
|
||||
{
|
||||
private:
|
||||
|
||||
@ -44,21 +44,7 @@ class Genode::Session_requests_rom
|
||||
|
||||
Attached_rom_dataspace _parent_rom;
|
||||
|
||||
Signal_handler<Session_requests_rom> _handler;
|
||||
|
||||
public:
|
||||
|
||||
Session_requests_rom(Genode::Env &env,
|
||||
Session_request_handler &requests_handler)
|
||||
: _parent(env.parent()),
|
||||
_requests_handler(requests_handler),
|
||||
_parent_rom(env, "session_requests"),
|
||||
_handler(env.ep(), *this, &Session_requests_rom::process)
|
||||
{
|
||||
_parent_rom.sigh(_handler);
|
||||
}
|
||||
|
||||
void process()
|
||||
void _process()
|
||||
{
|
||||
_parent_rom.update();
|
||||
Xml_node requests = _parent_rom.xml();
|
||||
@ -69,10 +55,18 @@ class Genode::Session_requests_rom
|
||||
request.attribute_value("id", ~0UL) };
|
||||
|
||||
typedef Session_state::Name Name;
|
||||
Name const name = request.attribute_value("service", Name());
|
||||
|
||||
typedef Session_state::Args Args;
|
||||
Args const args = request.sub_node("args").decoded_content<Args>();
|
||||
|
||||
Name name { };
|
||||
Args args { };
|
||||
|
||||
try {
|
||||
name = request.attribute_value("service", Name());
|
||||
args = request.sub_node("args").decoded_content<Args>();
|
||||
} catch (...) {
|
||||
Genode::error("failed to parse request ", request);
|
||||
return;
|
||||
}
|
||||
|
||||
try { _requests_handler.handle_session_create(name, id, args); }
|
||||
catch (Service_denied) {
|
||||
@ -94,7 +88,12 @@ class Genode::Session_requests_rom
|
||||
request.attribute_value("id", ~0UL) };
|
||||
|
||||
typedef Session_state::Args Args;
|
||||
Args const args = request.sub_node("args").decoded_content<Args>();
|
||||
Args args { };
|
||||
try { args = request.sub_node("args").decoded_content<Args>(); }
|
||||
catch (...) {
|
||||
Genode::error("failed to parse request ", request);
|
||||
return;
|
||||
}
|
||||
|
||||
_requests_handler.handle_session_upgrade(id, args);
|
||||
};
|
||||
@ -115,6 +114,24 @@ class Genode::Session_requests_rom
|
||||
/* create new sessions */
|
||||
requests.for_each_sub_node("create", create_fn);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Session_requests_rom(Genode::Env &env,
|
||||
Session_request_handler &requests_handler)
|
||||
: Signal_handler<Session_requests_rom>(env.ep(), *this, &Session_requests_rom::_process),
|
||||
_parent(env.parent()),
|
||||
_requests_handler(requests_handler),
|
||||
_parent_rom(env, "session_requests")
|
||||
{
|
||||
_parent_rom.sigh(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post a signal to this requests handler
|
||||
*/
|
||||
void schedule() {
|
||||
Signal_transmitter(*this).submit(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user