vfs: remove 'Io_response_handler' interface

The old 'Io_response_handler::io_progress_response' interface has been
replaced by the 'Vfs::Env::User::wakeup_vfs_user' (issue #4697). The
remaining 'read_ready_response' method is now hosted in the
appropriately named 'Read_ready_response_handler'.

Issue #4706
This commit is contained in:
Norman Feske 2022-12-20 15:02:22 +01:00 committed by Christian Helmuth
parent 74e6370187
commit 25e4bcefbf
18 changed files with 180 additions and 306 deletions

View File

@ -293,8 +293,7 @@ struct Vfs::Lxip_vfs_file_handle final : Vfs::Lxip_vfs_handle
typedef Genode::Fifo_element<Lxip_vfs_file_handle> Fifo_element;
typedef Genode::Fifo<Fifo_element> Fifo;
Fifo_element read_ready_elem { *this };
Fifo_element io_progress_elem { *this };
Fifo_element read_ready_elem { *this };
char content_buffer[Lxip::MAX_DATA_LEN];
@ -346,12 +345,6 @@ struct Vfs::Lxip_vfs_file_handle final : Vfs::Lxip_vfs_handle
virtual Sync_result sync() override {
return (file) ? file->sync() : Sync_result::SYNC_ERR_INVALID; }
void io_enqueue(Fifo &fifo)
{
if (!io_progress_elem.enqueued())
fifo.enqueue(io_progress_elem);
}
};
@ -379,26 +372,14 @@ struct Vfs::Lxip_vfs_dir_handle final : Vfs::Lxip_vfs_handle
};
/**
* Queues of open handles to poll
*/
static Vfs::Lxip_vfs_file_handle::Fifo *_io_progress_waiters_ptr;
static Vfs::Env::User *_vfs_user_ptr;
static Vfs::Lxip_vfs_file_handle::Fifo *_read_ready_waiters_ptr;
static void poll_all()
{
_io_progress_waiters_ptr->for_each(
[&] (Vfs::Lxip_vfs_file_handle::Fifo_element &elem) {
Vfs::Lxip_vfs_file_handle &handle = elem.object();
if (handle.file) {
if (handle.file->poll()) {
/* do not notify again until some I/O queues */
_io_progress_waiters_ptr->remove(elem);
handle.io_progress_response();
}
}
});
if (_vfs_user_ptr)
_vfs_user_ptr->wakeup_vfs_user();
_read_ready_waiters_ptr->for_each(
[&] (Vfs::Lxip_vfs_file_handle::Fifo_element &elem) {
@ -513,10 +494,9 @@ class Vfs::Lxip_data_file final : public Vfs::Lxip_file
msghdr msg = create_msghdr(nullptr, 0, len, &iov);
Lxip::ssize_t ret = _sock.ops->recvmsg(&_sock, &msg, len, MSG_DONTWAIT);
if (ret == -EAGAIN) {
handle.io_enqueue(*_io_progress_waiters_ptr);
if (ret == -EAGAIN)
throw Would_block();
}
return ret;
}
};
@ -743,7 +723,6 @@ class Vfs::Lxip_connect_file final : public Vfs::Lxip_file
case Lxip::Io_result::LINUX_EINPROGRESS:
_connecting = true;
_write_err = 0;
handle.io_enqueue(*_io_progress_waiters_ptr);
return len;
case Lxip::Io_result::LINUX_EALREADY:
@ -892,10 +871,9 @@ class Vfs::Lxip_remote_file final : public Vfs::Lxip_file
sizeof(handle.content_buffer), &iov);
int const res = _sock.ops->recvmsg(&_sock, &msg, 0, MSG_DONTWAIT|MSG_PEEK);
if (res == -EAGAIN) {
handle.io_enqueue(*_io_progress_waiters_ptr);
if (res == -EAGAIN)
throw Would_block();
}
if (res < 0) return -1;
}
break;
@ -974,7 +952,6 @@ class Vfs::Lxip_accept_file final : public Vfs::Lxip_file
return Genode::strlen(dst);
}
handle.io_enqueue(*_io_progress_waiters_ptr);
throw Would_block();
}
};
@ -1928,10 +1905,8 @@ class Vfs::Lxip_file_system : public Vfs::File_system,
Lxip_vfs_file_handle *file_handle =
dynamic_cast<Vfs::Lxip_vfs_file_handle*>(handle);
if (file_handle) {
_io_progress_waiters_ptr->remove(file_handle->io_progress_elem);
if (file_handle)
_read_ready_waiters_ptr->remove(file_handle->read_ready_elem);
}
Genode::destroy(handle->alloc(), handle);
}
@ -2044,6 +2019,7 @@ struct Lxip_factory : Vfs::File_system_factory
Vfs::File_system *create(Vfs::Env &env, Genode::Xml_node config) override
{
_vfs_user_ptr = &env.user();
static Init inst(env.env(), env.alloc());
return new (env.alloc()) Vfs::Lxip_file_system(env, config);
}
@ -2052,11 +2028,9 @@ struct Lxip_factory : Vfs::File_system_factory
extern "C" Vfs::File_system_factory *vfs_file_system_factory(void)
{
static Vfs::Lxip_vfs_file_handle::Fifo io_progress_waiters;
static Vfs::Lxip_vfs_file_handle::Fifo read_ready_waiters;
_io_progress_waiters_ptr = &io_progress_waiters;
_read_ready_waiters_ptr = &read_ready_waiters;
_read_ready_waiters_ptr = &read_ready_waiters;
static Lxip_factory factory;
return &factory;

View File

@ -94,17 +94,11 @@ class Vfs_audit::File_system : public Vfs::File_system
audit->seek(Vfs_handle::seek());
}
Handle(Vfs_audit::File_system &fs,
Genode::Allocator &alloc,
int flags,
char const *path)
: Vfs_handle(fs, fs, alloc, flags), path(path) { };
void handler(Io_response_handler *rh) override
{
Vfs_handle::handler(rh);
if (audit) audit->handler(rh);
}
Handle(Vfs_audit::File_system &fs, Genode::Allocator &alloc,
int flags, char const *path)
:
Vfs_handle(fs, fs, alloc, flags), path(path)
{ };
};
public:
@ -113,7 +107,7 @@ class Vfs_audit::File_system : public Vfs::File_system
:
_audit_log(env.env(), config.attribute_value("label", Genode::String<64>("audit")).string()),
_root_dir(env.root_dir()),
_audit_path(config.attribute_value(
_audit_path(config.attribute_value(
"path", Genode::String<Absolute_path::capacity()>()).string())
{ }

View File

@ -36,11 +36,11 @@ struct Vfs_gpu::File_system : Single_file_system
struct Gpu_vfs_handle : Single_vfs_handle
{
bool _complete { false };
Genode::Env &_env;
Gpu::Connection _gpu_session { _env };
Vfs::Env &_env;
Gpu::Connection _gpu_session { _env.env() };
Genode::Io_signal_handler<Gpu_vfs_handle> _completion_sigh {
_env.ep(), *this, &Gpu_vfs_handle::_handle_completion };
_env.env().ep(), *this, &Gpu_vfs_handle::_handle_completion };
using Id_space = Genode::Id_space<Gpu_vfs_handle>;
Id_space::Element const _elem;
@ -48,16 +48,17 @@ struct Vfs_gpu::File_system : Single_file_system
void _handle_completion()
{
_complete = true;
io_progress_response();
_env.user().wakeup_vfs_user();
}
Gpu_vfs_handle(Genode::Env &env,
Gpu_vfs_handle(Vfs::Env &env,
Directory_service &ds,
File_io_service &fs,
Genode::Allocator &alloc,
Id_space &space)
: Single_vfs_handle(ds, fs, alloc, 0),
_env(env), _elem(*this, space)
:
Single_vfs_handle(ds, fs, alloc, 0),
_env(env), _elem(*this, space)
{
_gpu_session.completion_sigh(_completion_sigh);
}
@ -110,7 +111,7 @@ struct Vfs_gpu::File_system : Single_file_system
try {
Gpu_vfs_handle *handle = new (alloc)
Gpu_vfs_handle(_env.env(), *this, *this, alloc, _handle_space);
Gpu_vfs_handle(_env, *this, *this, alloc, _handle_space);
_last_id = handle->id();
*out_handle = handle;

View File

@ -84,27 +84,28 @@ struct Vfs_pipe::Pipe_handle : Vfs::Vfs_handle, private Pipe_handle_registry_ele
struct Vfs_pipe::Pipe
{
Genode::Env &env;
Genode::Env &env;
Vfs::Env::User &vfs_user;
Genode::Allocator &alloc;
Pipe_space::Element space_elem;
Pipe_buffer buffer { };
Pipe_space::Element space_elem;
Pipe_buffer buffer { };
Pipe_handle_registry registry { };
Handle_fifo io_progress_waiters { };
Handle_fifo read_ready_waiters { };
unsigned num_writers = 0;
bool waiting_for_writers = true;
Genode::Io_signal_handler<Pipe> _read_notify_handler
{ env.ep(), *this, &Pipe::notify_read };
Genode::Io_signal_handler<Pipe> _write_notify_handler
{ env.ep(), *this, &Pipe::notify_write };
bool new_handle_active { true };
Pipe(Genode::Env &env, Genode::Allocator &alloc, Pipe_space &space)
Pipe(Genode::Env &env, Vfs::Env::User &vfs_user,
Genode::Allocator &alloc, Pipe_space &space)
:
env(env), alloc(alloc), space_elem(*this, space)
env(env), vfs_user(vfs_user), alloc(alloc), space_elem(*this, space)
{ }
~Pipe() = default;
@ -121,12 +122,6 @@ struct Vfs_pipe::Pipe
elem.object().read_ready_response(); });
}
void notify_write()
{
io_progress_waiters.dequeue_all([] (Handle_element &elem) {
elem.object().io_progress_response(); });
}
void submit_read_signal()
{
_read_notify_handler.local_submit();
@ -134,7 +129,7 @@ struct Vfs_pipe::Pipe
void submit_write_signal()
{
_write_notify_handler.local_submit();
vfs_user.wakeup_vfs_user();
}
/**
@ -161,8 +156,6 @@ struct Vfs_pipe::Pipe
*/
void remove(Pipe_handle &handle)
{
if (handle.io_progress_elem.enqueued())
io_progress_waiters.remove(handle.io_progress_elem);
if (handle.read_ready_elem.enqueued())
read_ready_waiters.remove(handle.read_ready_elem);
}
@ -183,7 +176,6 @@ struct Vfs_pipe::Pipe
Genode::warning("flushing non-empty buffer. capacity=", buffer.avail_capacity());
buffer.reset();
io_progress_waiters.dequeue_all([] (Handle_element &/*elem*/) { });
}
*handle = new (alloc)
Pipe_handle(fs, alloc, Directory_service::OPEN_MODE_WRONLY, registry, *this);
@ -205,12 +197,11 @@ struct Vfs_pipe::Pipe
return Open_result::OPEN_ERR_UNACCESSIBLE;
}
Write_result write(Pipe_handle &handle,
Write_result write(Pipe_handle &,
const char *buf, file_size count,
file_size &out_count)
{
file_size out = 0;
bool notify = buffer.empty();
if (buffer.avail_capacity() == 0) {
out_count = 0;
@ -223,11 +214,9 @@ struct Vfs_pipe::Pipe
}
out_count = out;
if (out < count)
io_progress_waiters.enqueue(handle.io_progress_elem);
if (notify)
submit_read_signal();
if (out > 0)
vfs_user.wakeup_vfs_user();
return Write_result::WRITE_OK;
}
@ -236,8 +225,6 @@ struct Vfs_pipe::Pipe
char *buf, file_size count,
file_size &out_count)
{
bool notify = buffer.avail_capacity() == 0;
file_size out = 0;
while (out < count && !buffer.empty()) {
*(buf++) = buffer.get();
@ -245,7 +232,8 @@ struct Vfs_pipe::Pipe
}
out_count = out;
if (!out) {
if (out == 0) {
/* Send only EOF when at least one writer opened the pipe */
if ((num_writers == 0) && !waiting_for_writers)
@ -255,8 +243,9 @@ struct Vfs_pipe::Pipe
return Read_result::READ_QUEUED;
}
if (notify)
submit_write_signal();
/* new pipe space may unblock the writer */
if (out > 0)
vfs_user.wakeup_vfs_user();
return Read_result::READ_OK;
}
@ -309,14 +298,15 @@ struct Vfs_pipe::New_pipe_handle : Vfs::Vfs_handle
{
Pipe &pipe;
New_pipe_handle(Vfs::File_system &fs,
Genode::Env &env,
New_pipe_handle(Vfs::File_system &fs,
Genode::Env &env,
Vfs::Env::User &vfs_user,
Genode::Allocator &alloc,
unsigned flags,
Pipe_space &pipe_space)
unsigned flags,
Pipe_space &pipe_space)
:
Vfs::Vfs_handle(fs, fs, alloc, flags),
pipe(*(new (alloc) Pipe(env, alloc, pipe_space)))
pipe(*(new (alloc) Pipe(env, vfs_user, alloc, pipe_space)))
{ }
~New_pipe_handle()
@ -677,7 +667,7 @@ class Vfs_pipe::Pipe_file_system : public Vfs_pipe::File_system
if ((OPEN_MODE_ACCMODE & mode) == OPEN_MODE_WRONLY)
return OPEN_ERR_NO_PERM;
*handle = new (alloc)
New_pipe_handle(*this, _env.env(), alloc, mode, _pipe_space);
New_pipe_handle(*this, _env.env(), _env.user(), alloc, mode, _pipe_space);
return OPEN_OK;
}
@ -823,7 +813,7 @@ class Vfs_pipe::Fifo_file_system : public Vfs_pipe::File_system
Path const path { fifo.attribute_value("name", String<MAX_PATH_LEN>()) };
Pipe &pipe = *new (env.alloc())
Pipe(env.env(), env.alloc(), _pipe_space);
Pipe(env.env(), env.user(), env.alloc(), _pipe_space);
new (env.alloc())
Fifo_item(_items, path, pipe.space_elem.id());
});

View File

@ -100,7 +100,7 @@ class Libc::Main_job : public Monitor::Job
* secondary stack for the application task. Context switching uses
* setjmp/longjmp.
*/
struct Libc::Kernel final : Vfs::Io_response_handler,
struct Libc::Kernel final : Vfs::Read_ready_response_handler,
Entrypoint::Io_progress_handler,
Reset_malloc_heap,
Resume,
@ -681,12 +681,11 @@ struct Libc::Kernel final : Vfs::Io_response_handler,
}
/****************************************
** Vfs::Io_response_handler interface **
****************************************/
/************************************************
** Vfs::Read_ready_response_handler interface **
************************************************/
void read_ready_response() override { _io_progressed = true; }
void io_progress_response() override { _io_progressed = true; }
/**********************************************

View File

@ -84,14 +84,14 @@ class Libc::Vfs_plugin final : public Plugin
reference_handle(reference_handle) { }
};
Genode::Allocator &_alloc;
Vfs::File_system &_root_fs;
Constructible<Genode::Directory> _root_dir { };
Vfs::Io_response_handler &_response_handler;
Update_mtime const _update_mtime;
Current_real_time &_current_real_time;
bool const _pipe_configured;
Registry<Mmap_entry> _mmap_registry;
Genode::Allocator &_alloc;
Vfs::File_system &_root_fs;
Constructible<Genode::Directory> _root_dir { };
Vfs::Read_ready_response_handler &_response_handler;
Update_mtime const _update_mtime;
Current_real_time &_current_real_time;
bool const _pipe_configured;
Registry<Mmap_entry> _mmap_registry;
/**
* Sync a handle
@ -150,13 +150,13 @@ class Libc::Vfs_plugin final : public Plugin
public:
Vfs_plugin(Libc::Env &env,
Vfs::Env &vfs_env,
Genode::Allocator &alloc,
Vfs::Io_response_handler &handler,
Update_mtime update_mtime,
Current_real_time &current_real_time,
Xml_node config)
Vfs_plugin(Libc::Env &env,
Vfs::Env &vfs_env,
Genode::Allocator &alloc,
Vfs::Read_ready_response_handler &handler,
Update_mtime update_mtime,
Current_real_time &current_real_time,
Xml_node config)
:
_alloc(alloc),
_root_fs(env.vfs_env().root_dir()),

View File

@ -37,6 +37,7 @@ class Libusb_file_system : public Vfs::Single_file_system
private:
Genode::Env &_env;
Vfs::Env::User &_vfs_user;
Genode::Allocator_avl _alloc_avl;
Usb::Connection _usb_connection;
@ -57,7 +58,7 @@ class Libusb_file_system : public Vfs::Single_file_system
void _handle_ack_avail()
{
io_progress_response();
_vfs_user.wakeup_vfs_user();
}
public:
@ -65,13 +66,15 @@ class Libusb_file_system : public Vfs::Single_file_system
Libusb_vfs_handle(Directory_service &ds,
File_io_service &fs,
Genode::Allocator &alloc,
Genode::Env &env)
: Single_vfs_handle(ds, fs, alloc, 0),
_env(env), _alloc_avl(&alloc),
_usb_connection(_env, &_alloc_avl,
"usb_device",
1024*1024,
_state_changed_handler)
Genode::Env &env,
Vfs::Env::User &vfs_user)
:
Single_vfs_handle(ds, fs, alloc, 0),
_env(env), _vfs_user(vfs_user), _alloc_avl(&alloc),
_usb_connection(_env, &_alloc_avl,
"usb_device",
1024*1024,
_state_changed_handler)
{
_usb_connection.tx_channel()->sigh_ack_avail(_ack_avail_handler);
libusb_genode_usb_connection(&_usb_connection);
@ -127,7 +130,7 @@ class Libusb_file_system : public Vfs::Single_file_system
return OPEN_ERR_UNACCESSIBLE;
*out_handle = new (alloc)
Libusb_vfs_handle(*this, *this, alloc, _env.env());
Libusb_vfs_handle(*this, *this, alloc, _env.env(), _env.user());
return OPEN_OK;
}

View File

@ -438,16 +438,6 @@ struct Lwip::Socket_dir : Lwip::Directory
read_ready_queue.dequeue_all([] (Lwip_file_handle::Fifo_element &elem) {
elem.object().read_ready_response(); });
}
/**
* Notify handles blocked by operations on this PCB / socket
*/
void process_io()
{
/* invoke all handles waiting for IO progress */
io_progress_queue.dequeue_all([] (Lwip_file_handle::Fifo_element &elem) {
elem.object().io_progress_response(); });
}
};
@ -551,6 +541,7 @@ class Lwip::Protocol_dir_impl final : public Protocol_dir
Genode::Allocator &_alloc;
Genode::Entrypoint &_ep;
Vfs::Env::User &_vfs_user;
Genode::List<SOCKET_DIR> _socket_dirs { };
@ -562,8 +553,8 @@ class Lwip::Protocol_dir_impl final : public Protocol_dir
friend class Tcp_socket_dir;
friend class Udp_socket_dir;
Protocol_dir_impl(Vfs::Env &vfs_env)
: _alloc(vfs_env.alloc()), _ep(vfs_env.env().ep()) { }
Protocol_dir_impl(Vfs::Env &env)
: _alloc(env.alloc()), _ep(env.env().ep()), _vfs_user(env.user()) { }
SOCKET_DIR *lookup(char const *name)
{
@ -684,7 +675,7 @@ class Lwip::Protocol_dir_impl final : public Protocol_dir
}
SOCKET_DIR *new_socket = new (alloc)
SOCKET_DIR(id, *this, alloc, _ep, pcb);
SOCKET_DIR(id, *this, alloc, _ep, _vfs_user, pcb);
_socket_dirs.insert(new_socket);
return *new_socket;
}
@ -738,11 +729,9 @@ class Lwip::Protocol_dir_impl final : public Protocol_dir
return Opendir_result::OPENDIR_ERR_LOOKUP_FAILED;
}
void notify()
void wakeup_vfs_user()
{
for (SOCKET_DIR *sd = _socket_dirs.first(); sd; sd = sd->next()) {
sd->process_io();
}
_vfs_user.wakeup_vfs_user();
}
};
@ -762,6 +751,8 @@ class Lwip::Udp_socket_dir final :
{
private:
Vfs::Env::User &_vfs_user;
/*
* Noncopyable
*/
@ -840,9 +831,12 @@ class Lwip::Udp_socket_dir final :
Udp_socket_dir(unsigned num, Udp_proto_dir &proto_dir,
Genode::Allocator &alloc,
Genode::Entrypoint &,
Vfs::Env::User &vfs_user,
udp_pcb *pcb)
: Socket_dir(num, alloc),
_proto_dir(proto_dir), _pcb(pcb ? pcb : udp_new())
:
Socket_dir(num, alloc),
_vfs_user(vfs_user),
_proto_dir(proto_dir), _pcb(pcb ? pcb : udp_new())
{
ip_addr_set_zero(&_to_addr);
@ -875,7 +869,7 @@ class Lwip::Udp_socket_dir final :
pbuf_free(buf);
}
process_io();
_vfs_user.wakeup_vfs_user();
process_read_ready();
}
@ -1110,6 +1104,7 @@ class Lwip::Tcp_socket_dir final :
Tcp_proto_dir &_proto_dir;
Genode::Entrypoint &_ep;
Vfs::Env::User &_vfs_user;
typedef Genode::List<Pcb_pending> Pcb_pending_list;
@ -1141,9 +1136,12 @@ class Lwip::Tcp_socket_dir final :
Tcp_socket_dir(unsigned num, Tcp_proto_dir &proto_dir,
Genode::Allocator &alloc,
Genode::Entrypoint &ep,
Vfs::Env::User &vfs_user,
tcp_pcb *pcb)
: Socket_dir(num, alloc), _proto_dir(proto_dir),
_ep(ep), _pcb(pcb ? pcb : tcp_new()), state(pcb ? READY : NEW)
:
Socket_dir(num, alloc), _proto_dir(proto_dir),
_ep(ep), _vfs_user(vfs_user),
_pcb(pcb ? pcb : tcp_new()), state(pcb ? READY : NEW)
{
/* 'this' will be the argument to LwIP callbacks */
tcp_arg(_pcb, this);
@ -1189,7 +1187,7 @@ class Lwip::Tcp_socket_dir final :
tcp_arg(newpcb, elem);
tcp_recv(newpcb, tcp_delayed_recv_callback);
process_io();
_vfs_user.wakeup_vfs_user();
process_read_ready();
return ERR_OK;
}
@ -1220,10 +1218,15 @@ class Lwip::Tcp_socket_dir final :
_pcb = NULL;
/* churn the application */
process_io();
wakeup_vfs_user();
process_read_ready();
}
void wakeup_vfs_user()
{
_vfs_user.wakeup_vfs_user();
}
/**
* Close the connection
*
@ -1627,7 +1630,7 @@ err_t tcp_connect_callback(void *arg, struct tcp_pcb *pcb, err_t)
Lwip::Tcp_socket_dir *socket_dir = static_cast<Lwip::Tcp_socket_dir *>(arg);
socket_dir->state = Lwip::Tcp_socket_dir::READY;
socket_dir->process_io();
socket_dir->wakeup_vfs_user();
socket_dir->process_read_ready();
return ERR_OK;
}
@ -1662,7 +1665,7 @@ err_t tcp_recv_callback(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t)
socket_dir->recv(p);
}
socket_dir->process_io();
socket_dir->wakeup_vfs_user();
socket_dir->process_read_ready();
return ERR_OK;
}
@ -1705,7 +1708,7 @@ err_t tcp_sent_callback(void *arg, struct tcp_pcb *pcb, u16_t)
}
Lwip::Tcp_socket_dir *socket_dir = static_cast<Lwip::Tcp_socket_dir *>(arg);
socket_dir->process_io();
socket_dir->wakeup_vfs_user();
return ERR_OK;
}
@ -1765,10 +1768,10 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory,
*/
struct Vfs_netif : Lwip::Nic_netif
{
Vfs::Env::User &_vfs_user;
Vfs::Env &_vfs_env;
Tcp_proto_dir tcp_dir;
Udp_proto_dir udp_dir;
Tcp_proto_dir tcp_dir { _vfs_env };
Udp_proto_dir udp_dir { _vfs_env };
Nameserver_registry nameserver_handles { };
@ -1780,8 +1783,7 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory,
:
Lwip::Nic_netif(vfs_env.env(), vfs_env.alloc(), config,
wakeup_scheduler),
_vfs_user(vfs_env.user()),
tcp_dir(vfs_env), udp_dir(vfs_env)
_vfs_env(vfs_env)
{ }
~Vfs_netif()
@ -1795,10 +1797,7 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory,
*/
void status_callback() override
{
tcp_dir.notify();
udp_dir.notify();
_vfs_user.wakeup_vfs_user();
_vfs_env.user().wakeup_vfs_user();
}
} _netif;

View File

@ -629,6 +629,7 @@ class Vfs::Oss_file_system::Data_file_system : public Single_file_system
Data_file_system &operator = (Data_file_system const &);
Genode::Entrypoint &_ep;
Vfs::Env::User &_vfs_user;
Audio &_audio;
struct Oss_vfs_handle : public Single_vfs_handle
@ -705,41 +706,29 @@ class Vfs::Oss_file_system::Data_file_system : public Single_file_system
void _handle_audio_out_progress()
{
if (_audio.handle_out_progress()) {
/* at least one stream packet is available */
_handle_registry.for_each([this] (Registered_handle &handle) {
if (handle.blocked) {
handle.blocked = false;
handle.io_progress_response();
}
});
}
if (_audio.handle_out_progress())
_vfs_user.wakeup_vfs_user();
}
void _handle_audio_in_progress()
{
if (_audio.handle_in_progress()) {
/* at least one stream packet is available */
_handle_registry.for_each([this] (Registered_handle &handle) {
if (handle.blocked) {
handle.blocked = false;
handle.io_progress_response();
}
});
}
if (_audio.handle_in_progress())
_vfs_user.wakeup_vfs_user();
}
public:
Data_file_system(Genode::Entrypoint &ep,
Vfs::Env::User &vfs_user,
Audio &audio,
Name const &name)
:
Single_file_system { Node_type::CONTINUOUS_FILE, name.string(),
Node_rwx::ro(), Genode::Xml_node("<data/>") },
_ep { ep },
_audio { audio }
_ep { ep },
_vfs_user { vfs_user },
_audio { audio }
{
_audio.out_progress_sigh(_audio_out_progress_sigh);
_audio.in_progress_sigh(_audio_in_progress_sigh);
@ -1008,7 +997,7 @@ struct Vfs::Oss_file_system::Local_factory : File_system_factory
_label { config.attribute_value("label", Label("")) },
_name { name(config) },
_env { env },
_data_fs { _env.env().ep(), _audio, name(config) }
_data_fs { _env.env().ep(), env.user(), _audio, name(config) }
{ }
Vfs::File_system *create(Vfs::Env&, Xml_node node) override

View File

@ -314,7 +314,7 @@ class Vfs::Dir_file_system : public File_system
vfs_handle.seek(index * sizeof(Dirent));
/* forward the response handler */
dir_vfs_handle->apply_handler([&] (Vfs::Io_response_handler &h) {
dir_vfs_handle->apply_handler([&] (Vfs::Read_ready_response_handler &h) {
vfs_handle.handler(&h); });
result = vfs_handle.fs().queue_read(&vfs_handle, sizeof(Dirent));
@ -998,7 +998,7 @@ class Vfs::Dir_file_system : public File_system
auto f = [&result, dir_vfs_handle] (Dir_vfs_handle::Subdir_handle_element &e) {
/* forward the response handler */
dir_vfs_handle->apply_handler([&] (Io_response_handler &h) {
dir_vfs_handle->apply_handler([&] (Read_ready_response_handler &h) {
e.vfs_handle.handler(&h); });
e.synced = false;

View File

@ -17,7 +17,7 @@
#include <vfs/directory_service.h>
namespace Vfs{
struct Io_response_handler;
struct Read_ready_response_handler;
struct Watch_response_handler;
class Vfs_handle;
class Vfs_watch_handle;
@ -33,17 +33,12 @@ namespace Vfs{
* These responses should be assumed to be called
* during I/O signal dispatch.
*/
struct Vfs::Io_response_handler : Genode::Interface
struct Vfs::Read_ready_response_handler : Genode::Interface
{
/**
* Respond to a resource becoming readable
*/
virtual void read_ready_response() = 0;
/**
* Respond to complete pending I/O
*/
virtual void io_progress_response() = 0;
};
@ -64,12 +59,13 @@ class Vfs::Vfs_handle
{
private:
Directory_service &_ds;
File_io_service &_fs;
Genode::Allocator &_alloc;
Io_response_handler *_handler = nullptr;
file_size _seek = 0;
int _status_flags;
Directory_service &_ds;
File_io_service &_fs;
Genode::Allocator &_alloc;
file_size _seek = 0;
int _status_flags;
Read_ready_response_handler *_handler_ptr = nullptr;
/*
* Noncopyable
@ -143,9 +139,9 @@ class Vfs::Vfs_handle
/**
* Set response handler, unset with nullptr
*/
virtual void handler(Io_response_handler *handler)
virtual void handler(Read_ready_response_handler *handler_ptr)
{
_handler = handler;
_handler_ptr = handler_ptr;
}
/**
@ -155,19 +151,13 @@ class Vfs::Vfs_handle
*/
template <typename FUNC>
void apply_handler(FUNC const &func) const {
if (_handler) func(*_handler); }
if (_handler_ptr) func(*_handler_ptr); }
/**
* Notify application through response handler
*/
void read_ready_response() {
if (_handler) _handler->read_ready_response(); }
/**
* Notify application through response handler
*/
void io_progress_response() {
if (_handler) _handler->io_progress_response(); }
if (_handler_ptr) _handler_ptr->read_ready_response(); }
/**
* Close handle at backing file-system.

View File

@ -33,7 +33,7 @@
namespace Vfs {
using Vfs::Io_response_handler;
using Vfs::Read_ready_response_handler;
template <typename> struct Builtin_entry;
struct External_entry;

View File

@ -136,12 +136,10 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
struct Fs_vfs_handle : Vfs_handle,
private ::File_system::Node,
private Handle_space::Element,
private Fs_vfs_handle_queue::Element,
private Handle_state
{
friend Genode::Id_space<::File_system::Node>;
friend Fs_vfs_handle_queue;
using Fs_vfs_handle_queue::Element::enqueued;
using Handle_state::queued_read_state;
using Handle_state::queued_read_packet;
@ -450,18 +448,11 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
{ }
};
Fs_vfs_handle_queue _congested_handles { };
Write_result _write(Fs_vfs_handle &handle, file_size const seek_offset,
const char *buf, file_size count, file_size &out_count)
{
/*
* TODO
* a sustained write loop will congest the packet buffer,
* perhaps acks should be processed before submission?
*
* _handle_ack();
*/
/* reclaim as much space in the packet stream as possible */
_handle_ack();
::File_system::Session::Tx::Source &source = *_fs.tx();
using ::File_system::Packet_descriptor;
@ -470,9 +461,6 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
count = min(max_packet_size, count);
if (!source.ready_to_submit()) {
if (!handle.enqueued())
_congested_handles.enqueue(handle);
_write_would_block = true;
return Write_result::WRITE_ERR_WOULD_BLOCK;
}
@ -489,9 +477,6 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
_submit_packet(packet_in);
}
catch (::File_system::Session::Tx::Source::Packet_alloc_failed) {
if (!handle.enqueued())
_congested_handles.enqueue(handle);
_write_would_block = true;
return Write_result::WRITE_ERR_WOULD_BLOCK;
}
@ -508,6 +493,8 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
::File_system::Session::Tx::Source &source = *_fs.tx();
using ::File_system::Packet_descriptor;
bool any_ack_handled = false;
while (source.ack_avail()) {
Packet_descriptor const packet = source.try_get_acked_packet();
@ -516,8 +503,8 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
Handle_space::Id const id(packet.handle());
auto handle_read = [&] (Fs_vfs_handle &handle) {
auto handle_fn = [&] (Fs_vfs_handle &handle)
{
if (!packet.succeeded())
Genode::error("packet operation=", (int)packet.operation(), " failed");
@ -530,29 +517,22 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
case Packet_descriptor::READ:
handle.queued_read_packet = packet;
handle.queued_read_state = Handle_state::Queued_state::ACK;
handle.io_progress_response();
break;
case Packet_descriptor::WRITE:
/*
* Notify anyone who might have failed on
* 'alloc_packet()'
*/
handle.io_progress_response();
source.release_packet(packet);
break;
case Packet_descriptor::SYNC:
handle.queued_sync_packet = packet;
handle.queued_sync_state = Handle_state::Queued_state::ACK;
handle.io_progress_response();
break;
case Packet_descriptor::CONTENT_CHANGED:
/* previously handled */
break;
case Packet_descriptor::WRITE_TIMESTAMP:
/* previously handled */
source.release_packet(packet);
break;
}
};
@ -562,34 +542,22 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
_watch_handle_space.apply<Fs_vfs_watch_handle>(id, [&] (Fs_vfs_watch_handle &handle) {
handle.watch_response(); });
} else {
_handle_space.apply<Fs_vfs_handle>(id, handle_read);
_handle_space.apply<Fs_vfs_handle>(id, handle_fn);
}
}
catch (Handle_space::Unknown_id) {
Genode::warning("ack for unknown File_system handle ", id); }
if (packet.operation() == Packet_descriptor::WRITE) {
source.release_packet(packet);
}
if (packet.operation() == Packet_descriptor::WRITE_TIMESTAMP) {
source.release_packet(packet);
}
if (packet.succeeded())
any_ack_handled = true;
}
}
void _handle_signal()
{
_handle_ack();
_congested_handles.dequeue_all([] (Fs_vfs_handle &handle) {
handle.io_progress_response(); });
_env.user().wakeup_vfs_user();
if (any_ack_handled)
_env.user().wakeup_vfs_user();
}
Genode::Io_signal_handler<Fs_file_system> _signal_handler {
_env.env().ep(), *this, &Fs_file_system::_handle_signal };
_env.env().ep(), *this, &Fs_file_system::_handle_ack };
static size_t buffer_size(Genode::Xml_node const &config)
{
@ -867,8 +835,6 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
void close(Vfs_handle *vfs_handle) override
{
Fs_vfs_handle *fs_handle = static_cast<Fs_vfs_handle *>(vfs_handle);
if (fs_handle->enqueued())
_congested_handles.remove(*fs_handle);
_fs.close(fs_handle->file_handle());
destroy(fs_handle->alloc(), fs_handle);
@ -935,10 +901,7 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
{
Fs_vfs_handle *handle = static_cast<Fs_vfs_handle *>(vfs_handle);
bool result = handle->queue_read(count);
if (!result && !handle->enqueued())
_congested_handles.enqueue(*handle);
return result;
return handle->queue_read(count);
}
Read_result complete_read(Vfs_handle *vfs_handle, char *dst, file_size count,
@ -948,10 +911,7 @@ class Vfs::Fs_file_system : public File_system, private Remote_io
Fs_vfs_handle *handle = static_cast<Fs_vfs_handle *>(vfs_handle);
Read_result result = handle->complete_read(dst, count, out_count);
if (result == READ_QUEUED && !handle->enqueued())
_congested_handles.enqueue(*handle);
return result;
return handle->complete_read(dst, count, out_count);
}
bool read_ready(Vfs_handle const &vfs_handle) const override

View File

@ -82,7 +82,7 @@ class Vfs::Nic_file_system::Nic_vfs_handle : public Single_vfs_handle
if (_blocked) {
_blocked = false;
io_progress_response();
_vfs_user.wakeup_vfs_user();
}
if (_notifying) {

View File

@ -59,7 +59,7 @@ class Vfs::Uplink_file_system::Uplink_vfs_handle : public Single_vfs_handle,
if (_blocked) {
_blocked = false;
io_progress_response();
_vfs_user.wakeup_vfs_user();
}
if (_notifying) {

View File

@ -119,7 +119,6 @@ class Vfs::Terminal_file_system::Data_file_system : public Single_file_system
bool const _raw;
bool notifying = false;
bool blocked = false;
Terminal_vfs_handle(Terminal::Connection &terminal,
Vfs::Env::User &vfs_user,
@ -157,10 +156,8 @@ class Vfs::Terminal_file_system::Data_file_system : public Single_file_system
_fetch_data_from_terminal(_terminal, _read_buffer,
_interrupt_handler, _raw);
if (_read_buffer.empty()) {
blocked = true;
if (_read_buffer.empty())
return READ_QUEUED;
}
unsigned consumed = 0;
for (; consumed < count && !_read_buffer.empty(); consumed++)
@ -206,11 +203,6 @@ class Vfs::Terminal_file_system::Data_file_system : public Single_file_system
_raw);
_handle_registry.for_each([] (Registered_handle &handle) {
if (handle.blocked) {
handle.blocked = false;
handle.io_progress_response();
}
if (handle.notifying) {
handle.notifying = false;
handle.read_ready_response();

View File

@ -228,7 +228,7 @@ class Vfs_server::Node : Node_space::Element, Node_queue::Element
* Super-class for nodes that process read/write packets
*/
class Vfs_server::Io_node : public Vfs_server::Node,
public Vfs::Io_response_handler
public Vfs::Read_ready_response_handler
{
private:
@ -498,11 +498,6 @@ class Vfs_server::Io_node : public Vfs_server::Node,
if (_read_ready_state == Read_ready_state::REQUESTED)
_read_ready_state = Read_ready_state::READY;
}
/**
* Called by the VFS plugin of this handle
*/
void io_progress_response() override { }
};

View File

@ -78,29 +78,13 @@ class Vfs_block::File
Constructible<Vfs_block::Job> _job { };
struct Io_response_handler : Vfs::Io_response_handler
{
Signal_context_capability sigh { };
void read_ready_response() override { }
void io_progress_response() override
{
if (sigh.valid()) {
Signal_transmitter(sigh).submit();
}
}
};
Io_response_handler _io_response_handler { };
Block::Session::Info _block_info { };
public:
File(Genode::Allocator &alloc,
Vfs::File_system &vfs,
Signal_context_capability sigh,
File_info const &info)
File(Genode::Allocator &alloc,
Vfs::File_system &vfs,
File_info const &info)
:
_vfs { vfs },
_vfs_handle { nullptr }
@ -137,9 +121,6 @@ class Vfs_block::File
.align_log2 = log2(info.block_size),
.writeable = info.writeable,
};
_io_response_handler.sigh = sigh;
_vfs_handle->handler(&_io_response_handler);
}
~File()
@ -313,7 +294,8 @@ struct Block_session_component : Rpc_object<Block::Session>,
};
struct Main : Rpc_object<Typed_root<Block::Session>>
struct Main : Rpc_object<Typed_root<Block::Session>>,
private Vfs::Env::User
{
Env &_env;
@ -324,7 +306,7 @@ struct Main : Rpc_object<Typed_root<Block::Session>>
Attached_rom_dataspace _config_rom { _env, "config" };
Vfs::Simple_env _vfs_env { _env, _heap,
_config_rom.xml().sub_node("vfs") };
_config_rom.xml().sub_node("vfs"), *this };
Constructible<Attached_ram_dataspace> _block_ds { };
Constructible<Vfs_block::File> _block_file { };
@ -339,6 +321,13 @@ struct Main : Rpc_object<Typed_root<Block::Session>>
_block_session->handle_request();
}
/*
* Vfs::Env::User interface
*/
void wakeup_vfs_user() override
{
_request_handler.local_submit();
}
/*
* Root interface
@ -378,8 +367,7 @@ struct Main : Rpc_object<Typed_root<Block::Session>>
try {
_block_ds.construct(_env.ram(), _env.rm(), tx_buf_size);
_block_file.construct(_heap, _vfs_env.root_dir(),
_request_handler, file_info);
_block_file.construct(_heap, _vfs_env.root_dir(), file_info);
_block_session.construct(_env.rm(), _env.ep(),
_block_ds->cap(),
_request_handler, *_block_file,