fs_log: remove blocking call of get_acked_packet

This patch replaces formerly blocking packet-stream operations by
the explicit use of 'wait_and_dispatch_io_signal' for blocking.
It also removes a misleading comment that promised a fire-and-forget
behavior whereas the implementation relied on blocking I/O anyway.

Issue #4390
This commit is contained in:
Norman Feske 2022-01-27 15:13:55 +01:00
parent 480c0a7dee
commit 22cce07ec8
3 changed files with 28 additions and 12 deletions

View File

@ -13,7 +13,7 @@ When a default-policy node specifies a merge, all sessions are merged into
the file "/log". the file "/log".
:Example configuration: :Example configuration:
! <start name="log_file"> ! <start name="fs_log">
! <resource name="RAM" quantum="1M"/> ! <resource name="RAM" quantum="1M"/>
! <provides><service name="LOG"/></provides> ! <provides><service name="LOG"/></provides>
! <config> ! <config>

View File

@ -56,6 +56,12 @@ class Fs_log::Root_component :
File_system::Connection _fs File_system::Connection _fs
{ _env, _tx_alloc, "", "/", true, TX_BUF_SIZE }; { _env, _tx_alloc, "", "/", true, TX_BUF_SIZE };
/* enable reception of I/O signals from file-system session */
Genode::Io_signal_handler<Root_component> _fs_signal_handler {
_env.ep(), *this, &Root_component::_handle_fs_signal };
void _handle_fs_signal() { };
void _update_config() { _config_rom.update(); } void _update_config() { _config_rom.update(); }
Genode::Signal_handler<Root_component> _config_handler Genode::Signal_handler<Root_component> _config_handler
@ -148,7 +154,8 @@ class Fs_log::Root_component :
File_system::WRITE_ONLY, true)); File_system::WRITE_ONLY, true));
} }
return new (md_alloc()) Session_component(_fs, *handle, label_prefix); return new (md_alloc())
Session_component(_env.ep(), _fs, *handle, label_prefix);
} }
catch (Permission_denied) { catch (Permission_denied) {
errstr = "permission denied"; } errstr = "permission denied"; }
@ -181,6 +188,7 @@ class Fs_log::Root_component :
Genode::Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc), Genode::Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc),
_env(env) _env(env)
{ {
_fs.sigh(_fs_signal_handler);
_config_rom.sigh(_config_handler); _config_rom.sigh(_config_handler);
/* fill the ack queue with packets so sessions never need to alloc */ /* fill the ack queue with packets so sessions never need to alloc */

View File

@ -2,9 +2,6 @@
* \brief Log session that writes messages to a file system. * \brief Log session that writes messages to a file system.
* \author Emery Hemingway * \author Emery Hemingway
* \date 2015-05-16 * \date 2015-05-16
*
* Message writing is fire-and-forget to prevent
* logging from becoming I/O bound.
*/ */
/* /*
@ -38,17 +35,25 @@ class Fs_log::Session_component : public Genode::Rpc_object<Genode::Log_session>
char _label_buf[MAX_LABEL_LEN]; char _label_buf[MAX_LABEL_LEN];
Genode::size_t const _label_len; Genode::size_t const _label_len;
Genode::Entrypoint &_ep;
File_system::Session &_fs; File_system::Session &_fs;
File_system::File_handle const _handle; File_system::File_handle const _handle;
void _block_for_ack()
{
while (!_fs.tx()->ack_avail())
_ep.wait_and_dispatch_one_io_signal();
}
public: public:
Session_component(File_system::Session &fs, Session_component(Genode::Entrypoint &ep,
File_system::Session &fs,
File_system::File_handle handle, File_system::File_handle handle,
char const *label) char const *label)
: :
_label_len(Genode::strlen(label) ? Genode::strlen(label)+3 : 0), _label_len(Genode::strlen(label) ? Genode::strlen(label)+3 : 0),
_fs(fs), _handle(handle) _ep(ep), _fs(fs), _handle(handle)
{ {
if (_label_len) if (_label_len)
Genode::snprintf(_label_buf, MAX_LABEL_LEN, "[%s] ", label); Genode::snprintf(_label_buf, MAX_LABEL_LEN, "[%s] ", label);
@ -60,14 +65,13 @@ class Fs_log::Session_component : public Genode::Rpc_object<Genode::Log_session>
File_system::Session::Tx::Source &source = *_fs.tx(); File_system::Session::Tx::Source &source = *_fs.tx();
_block_for_ack();
File_system::Packet_descriptor packet = source.get_acked_packet(); File_system::Packet_descriptor packet = source.get_acked_packet();
if (packet.operation() == File_system::Packet_descriptor::SYNC) if (packet.operation() == File_system::Packet_descriptor::SYNC)
_fs.close(packet.handle()); _fs.close(packet.handle());
packet = File_system::Packet_descriptor(
packet, _handle, File_system::Packet_descriptor::SYNC, 0, 0);
source.submit_packet(packet); source.submit_packet(packet);
} }
@ -89,6 +93,8 @@ class Fs_log::Session_component : public Genode::Rpc_object<Genode::Log_session>
File_system::Session::Tx::Source &source = *_fs.tx(); File_system::Session::Tx::Source &source = *_fs.tx();
_block_for_ack();
File_system::Packet_descriptor packet = source.get_acked_packet(); File_system::Packet_descriptor packet = source.get_acked_packet();
if (packet.operation() == File_system::Packet_descriptor::SYNC) if (packet.operation() == File_system::Packet_descriptor::SYNC)
@ -107,10 +113,12 @@ class Fs_log::Session_component : public Genode::Rpc_object<Genode::Log_session>
packet.length(msg_len); packet.length(msg_len);
source.submit_packet(packet); source.submit_packet(packet);
_block_for_ack();
packet = File_system::Packet_descriptor( packet = File_system::Packet_descriptor(
source.get_acked_packet(), source.get_acked_packet(),
_handle, File_system::Packet_descriptor::WRITE, _handle, File_system::Packet_descriptor::WRITE,
msg_len, File_system::SEEK_TAIL); msg_len, File_system::SEEK_TAIL);
buf = source.packet_content(packet); buf = source.packet_content(packet);