diff --git a/repos/dde_linux/src/lib/vfs/lxip/vfs.cc b/repos/dde_linux/src/lib/vfs/lxip/vfs.cc index 24a66f095e..55e8f43c60 100644 --- a/repos/dde_linux/src/lib/vfs/lxip/vfs.cc +++ b/repos/dde_linux/src/lib/vfs/lxip/vfs.cc @@ -293,8 +293,7 @@ struct Vfs::Lxip_vfs_file_handle final : Vfs::Lxip_vfs_handle typedef Genode::Fifo_element Fifo_element; typedef Genode::Fifo 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(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; diff --git a/repos/gems/src/lib/vfs/audit/vfs_audit.cc b/repos/gems/src/lib/vfs/audit/vfs_audit.cc index 827e00b4b1..c417aef88d 100644 --- a/repos/gems/src/lib/vfs/audit/vfs_audit.cc +++ b/repos/gems/src/lib/vfs/audit/vfs_audit.cc @@ -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()).string()) { } diff --git a/repos/gems/src/lib/vfs/gpu/vfs.cc b/repos/gems/src/lib/vfs/gpu/vfs.cc index 73a561bd1d..6f04e4df84 100644 --- a/repos/gems/src/lib/vfs/gpu/vfs.cc +++ b/repos/gems/src/lib/vfs/gpu/vfs.cc @@ -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 _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; 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; diff --git a/repos/gems/src/lib/vfs/pipe/plugin.cc b/repos/gems/src/lib/vfs/pipe/plugin.cc index 86ce8c2cb0..3cc84857aa 100644 --- a/repos/gems/src/lib/vfs/pipe/plugin.cc +++ b/repos/gems/src/lib/vfs/pipe/plugin.cc @@ -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 _read_notify_handler { env.ep(), *this, &Pipe::notify_read }; - Genode::Io_signal_handler _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()) }; 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()); }); diff --git a/repos/libports/src/lib/libc/internal/kernel.h b/repos/libports/src/lib/libc/internal/kernel.h index 6583d0eb39..c00aab4fa1 100644 --- a/repos/libports/src/lib/libc/internal/kernel.h +++ b/repos/libports/src/lib/libc/internal/kernel.h @@ -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; } /********************************************** diff --git a/repos/libports/src/lib/libc/internal/vfs_plugin.h b/repos/libports/src/lib/libc/internal/vfs_plugin.h index 1775979fd2..554a0c2876 100644 --- a/repos/libports/src/lib/libc/internal/vfs_plugin.h +++ b/repos/libports/src/lib/libc/internal/vfs_plugin.h @@ -84,14 +84,14 @@ class Libc::Vfs_plugin final : public Plugin reference_handle(reference_handle) { } }; - Genode::Allocator &_alloc; - Vfs::File_system &_root_fs; - Constructible _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_registry; + Genode::Allocator &_alloc; + Vfs::File_system &_root_fs; + Constructible _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_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 ¤t_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 ¤t_real_time, + Xml_node config) : _alloc(alloc), _root_fs(env.vfs_env().root_dir()), diff --git a/repos/libports/src/lib/vfs/libusb/vfs_libusb.cc b/repos/libports/src/lib/vfs/libusb/vfs_libusb.cc index 822390ef19..f234bf7b88 100644 --- a/repos/libports/src/lib/vfs/libusb/vfs_libusb.cc +++ b/repos/libports/src/lib/vfs/libusb/vfs_libusb.cc @@ -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; } diff --git a/repos/libports/src/lib/vfs/lwip/vfs.cc b/repos/libports/src/lib/vfs/lwip/vfs.cc index 0a7731179c..b84bcf7e10 100644 --- a/repos/libports/src/lib/vfs/lwip/vfs.cc +++ b/repos/libports/src/lib/vfs/lwip/vfs.cc @@ -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_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_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(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(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; diff --git a/repos/libports/src/lib/vfs/oss/vfs_oss.cc b/repos/libports/src/lib/vfs/oss/vfs_oss.cc index d4059ca371..e6b7e336b1 100644 --- a/repos/libports/src/lib/vfs/oss/vfs_oss.cc +++ b/repos/libports/src/lib/vfs/oss/vfs_oss.cc @@ -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("") }, - _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 diff --git a/repos/os/include/vfs/dir_file_system.h b/repos/os/include/vfs/dir_file_system.h index eb203e8686..907547f5a0 100644 --- a/repos/os/include/vfs/dir_file_system.h +++ b/repos/os/include/vfs/dir_file_system.h @@ -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; diff --git a/repos/os/include/vfs/vfs_handle.h b/repos/os/include/vfs/vfs_handle.h index 7b6895dc47..6a82aaf1d9 100644 --- a/repos/os/include/vfs/vfs_handle.h +++ b/repos/os/include/vfs/vfs_handle.h @@ -17,7 +17,7 @@ #include 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 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. diff --git a/repos/os/src/lib/vfs/file_system_factory.cc b/repos/os/src/lib/vfs/file_system_factory.cc index 5cdf20e8e3..2d86396e94 100644 --- a/repos/os/src/lib/vfs/file_system_factory.cc +++ b/repos/os/src/lib/vfs/file_system_factory.cc @@ -33,7 +33,7 @@ namespace Vfs { - using Vfs::Io_response_handler; + using Vfs::Read_ready_response_handler; template struct Builtin_entry; struct External_entry; diff --git a/repos/os/src/lib/vfs/fs_file_system.h b/repos/os/src/lib/vfs/fs_file_system.h index 0383288622..34834c2f5b 100644 --- a/repos/os/src/lib/vfs/fs_file_system.h +++ b/repos/os/src/lib/vfs/fs_file_system.h @@ -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(id, [&] (Fs_vfs_watch_handle &handle) { handle.watch_response(); }); } else { - _handle_space.apply(id, handle_read); + _handle_space.apply(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 _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(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(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(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 diff --git a/repos/os/src/lib/vfs/tap/nic_file_system.h b/repos/os/src/lib/vfs/tap/nic_file_system.h index 164fc21e86..4babce42f0 100644 --- a/repos/os/src/lib/vfs/tap/nic_file_system.h +++ b/repos/os/src/lib/vfs/tap/nic_file_system.h @@ -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) { diff --git a/repos/os/src/lib/vfs/tap/uplink_file_system.h b/repos/os/src/lib/vfs/tap/uplink_file_system.h index 8654085d40..6aaf41da06 100644 --- a/repos/os/src/lib/vfs/tap/uplink_file_system.h +++ b/repos/os/src/lib/vfs/tap/uplink_file_system.h @@ -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) { diff --git a/repos/os/src/lib/vfs/terminal_file_system.h b/repos/os/src/lib/vfs/terminal_file_system.h index 49574873fa..15d2f86c6c 100644 --- a/repos/os/src/lib/vfs/terminal_file_system.h +++ b/repos/os/src/lib/vfs/terminal_file_system.h @@ -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(); diff --git a/repos/os/src/server/vfs/node.h b/repos/os/src/server/vfs/node.h index beff1ac002..cc8003fd5e 100644 --- a/repos/os/src/server/vfs/node.h +++ b/repos/os/src/server/vfs/node.h @@ -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 { } }; diff --git a/repos/os/src/server/vfs_block/component.cc b/repos/os/src/server/vfs_block/component.cc index 19b32f7e1b..47e598c75a 100644 --- a/repos/os/src/server/vfs_block/component.cc +++ b/repos/os/src/server/vfs_block/component.cc @@ -78,29 +78,13 @@ class Vfs_block::File Constructible _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, }; -struct Main : Rpc_object> +struct Main : Rpc_object>, + private Vfs::Env::User { Env &_env; @@ -324,7 +306,7 @@ struct Main : Rpc_object> 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 _block_ds { }; Constructible _block_file { }; @@ -339,6 +321,13 @@ struct Main : Rpc_object> _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> 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,