genode/repos/os/include/vfs/simple_env.h
Norman Feske ff2176a586 vfs,libc: support write fds in select
By adding a 'write_ready' interface following the lines of the existing
'read_ready', VFS plugins become able to propagate the (de-)saturation
of I/O buffers to the VFS user. This information is important when using
a non-blocking file descriptor for writing into a TCP socket. Once the
application observes EAGAIN, it expects a subsequent 'select' call to
return as soon as new I/O buffer space becomes available.

Before this patch, the select call would always return under this
condition, causing an unnecessarily busy write loop.

Issue #4697
2023-01-24 12:07:28 +01:00

92 lines
2.2 KiB
C++

/*
* \brief Cross-plugin VFS environment
* \author Emery Hemingway
* \author Norman Feske
* \date 2018-04-04
*/
/*
* Copyright (C) 2018 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__VFS__SIMPLE_ENV_H_
#define _INCLUDE__VFS__SIMPLE_ENV_H_
#include <vfs/file_system_factory.h>
#include <vfs/dir_file_system.h>
#include <vfs/env.h>
namespace Vfs { struct Simple_env; }
class Vfs::Simple_env : public Vfs::Env, private Vfs::Env::Io, private Vfs::Env::User
{
private:
Genode::Env &_env;
Genode::Allocator &_alloc;
Vfs::Env::User &_user;
using Deferred_wakeups = Remote_io::Deferred_wakeups;
Deferred_wakeups _deferred_wakeups { };
Global_file_system_factory _fs_factory { _alloc };
Dir_file_system _root_dir;
public:
Simple_env(Genode::Env &env,
Genode::Allocator &alloc,
Genode::Xml_node config,
Vfs::Env::User &user)
:
_env(env), _alloc(alloc), _user(user), _root_dir(*this, config, _fs_factory)
{ }
Simple_env(Genode::Env &env, Genode::Allocator &alloc, Genode::Xml_node config)
:
Simple_env(env, alloc, config, *this)
{ }
void apply_config(Genode::Xml_node const &config)
{
_root_dir.apply_config(config);
}
Genode::Env &env() override { return _env; }
Genode::Allocator &alloc() override { return _alloc; }
Vfs::File_system &root_dir() override { return _root_dir; }
Deferred_wakeups &deferred_wakeups() override { return _deferred_wakeups; }
Vfs::Env::Io &io() override { return *this; }
Vfs::Env::User &user() override { return _user; }
/**
* Vfs::Env::Io interface
*/
void commit() override { _deferred_wakeups.trigger(); }
/**
* Vfs::Env::Io interface
*/
void commit_and_wait() override
{
_deferred_wakeups.trigger();
_env.ep().wait_and_dispatch_one_io_signal();
}
/**
* Vfs::Env::User interface
*
* Fallback implementation used if no 'user' is specified at
* construction time.
*/
void wakeup_vfs_user() override { };
};
#endif /* _INCLUDE__VFS__SIMPLE_ENV_H_ */