mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-02 08:42:52 +00:00
Noux: add Io_receptor to SYSCALL_SELECT + bugfix
The Io_receptor is now used to unblock certain I/O channels from lwip's callback-function. There was also a bug in which all ready-to-ready fds were overriden by the ready-to-write ones.
This commit is contained in:
parent
c74bdbf8d8
commit
0539c7180b
@ -27,6 +27,7 @@
|
|||||||
#include <pipe_io_channel.h>
|
#include <pipe_io_channel.h>
|
||||||
#include <dir_file_system.h>
|
#include <dir_file_system.h>
|
||||||
#include <user_info.h>
|
#include <user_info.h>
|
||||||
|
#include <io_receptor_registry.h>
|
||||||
|
|
||||||
|
|
||||||
static bool trace_syscalls = false;
|
static bool trace_syscalls = false;
|
||||||
@ -144,6 +145,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
|||||||
if (io->write(_sysio, count) == false)
|
if (io->write(_sysio, count) == false)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,37 +329,36 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
|||||||
|
|
||||||
Shared_pointer<Io_channel> io = io_channel_by_fd(fd);
|
Shared_pointer<Io_channel> io = io_channel_by_fd(fd);
|
||||||
|
|
||||||
if (io->check_unblock(in_fds.watch_for_rd(i),
|
if (in_fds.watch_for_rd(i))
|
||||||
in_fds.watch_for_wr(i),
|
|
||||||
in_fds.watch_for_ex(i))) {
|
|
||||||
|
|
||||||
if (io->check_unblock(true, false, false)) {
|
if (io->check_unblock(true, false, false)) {
|
||||||
_rd_array[unblock_rd++] = fd;
|
_rd_array[unblock_rd++] = fd;
|
||||||
// io->clear_unblock(true, false, false);
|
|
||||||
}
|
}
|
||||||
|
if (in_fds.watch_for_wr(i))
|
||||||
if (io->check_unblock(false, true, false)) {
|
if (io->check_unblock(false, true, false)) {
|
||||||
_wr_array[unblock_wr++] = fd;
|
_wr_array[unblock_wr++] = fd;
|
||||||
// io->clear_unblock(false, true, false);
|
|
||||||
}
|
}
|
||||||
|
if (in_fds.watch_for_ex(i))
|
||||||
if (io->check_unblock(false, false, true)) {
|
if (io->check_unblock(false, false, true)) {
|
||||||
unblock_ex++;
|
unblock_ex++;
|
||||||
// io->clear_unblock(false, false, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unblock_rd || unblock_wr || unblock_ex) {
|
if (unblock_rd || unblock_wr || unblock_ex) {
|
||||||
|
/**
|
||||||
|
* Merge the fd arrays in one output array
|
||||||
|
*/
|
||||||
for (size_t i = 0; i < unblock_rd; i++) {
|
for (size_t i = 0; i < unblock_rd; i++) {
|
||||||
_sysio->select_out.fds.array[i] = _rd_array[i];
|
_sysio->select_out.fds.array[i] = _rd_array[i];
|
||||||
_sysio->select_out.fds.num_rd = unblock_rd;
|
_sysio->select_out.fds.num_rd = unblock_rd;
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < unblock_wr; i++) {
|
|
||||||
_sysio->select_out.fds.array[i] = _wr_array[i];
|
/* XXX could use a pointer to select_out.fds.array instead */
|
||||||
|
for (size_t j = unblock_rd, i = 0; i < unblock_wr; i++, j++) {
|
||||||
|
_sysio->select_out.fds.array[j] = _wr_array[i];
|
||||||
_sysio->select_out.fds.num_wr = unblock_wr;
|
_sysio->select_out.fds.num_wr = unblock_wr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* exception fds are currently not considered */
|
||||||
_sysio->select_out.fds.num_ex = unblock_ex;
|
_sysio->select_out.fds.num_ex = unblock_ex;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -403,6 +404,16 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
|||||||
io->register_wake_up_notifier(¬ifiers[i]);
|
io->register_wake_up_notifier(¬ifiers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register ourself at the Io_receptor_registry
|
||||||
|
*
|
||||||
|
* Each entry in the registry will be unblocked if an external
|
||||||
|
* event has happend, e.g. network I/O.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Io_receptor receptor(&_blocker);
|
||||||
|
io_receptor_registry()->register_receptor(&receptor);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Block at barrier except when reaching the timeout
|
* Block at barrier except when reaching the timeout
|
||||||
*/
|
*/
|
||||||
@ -442,6 +453,11 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
|||||||
io->unregister_wake_up_notifier(¬ifiers[i]);
|
io->unregister_wake_up_notifier(¬ifiers[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unregister receptor
|
||||||
|
*/
|
||||||
|
io_receptor_registry()->unregister_receptor(&receptor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -781,6 +797,13 @@ Noux::User_info* Noux::user_info()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Noux::Io_receptor_registry * Noux::io_receptor_registry()
|
||||||
|
{
|
||||||
|
static Noux::Io_receptor_registry _inst;
|
||||||
|
return &_inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void *operator new (Genode::size_t size) {
|
void *operator new (Genode::size_t size) {
|
||||||
return Genode::env()->heap()->alloc(size); }
|
return Genode::env()->heap()->alloc(size); }
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user