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:
Josef Söntgen 2012-10-24 19:00:54 +02:00
parent c74bdbf8d8
commit 0539c7180b

View File

@ -27,6 +27,7 @@
#include <pipe_io_channel.h>
#include <dir_file_system.h>
#include <user_info.h>
#include <io_receptor_registry.h>
static bool trace_syscalls = false;
@ -144,6 +145,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
if (io->write(_sysio, count) == false)
return false;
}
return true;
}
@ -327,37 +329,36 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
Shared_pointer<Io_channel> io = io_channel_by_fd(fd);
if (io->check_unblock(in_fds.watch_for_rd(i),
in_fds.watch_for_wr(i),
in_fds.watch_for_ex(i))) {
if (in_fds.watch_for_rd(i))
if (io->check_unblock(true, false, false)) {
_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)) {
_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)) {
unblock_ex++;
// io->clear_unblock(false, false, true);
}
}
}
if (unblock_rd || unblock_wr || unblock_ex) {
/**
* Merge the fd arrays in one output array
*/
for (size_t i = 0; i < unblock_rd; i++) {
_sysio->select_out.fds.array[i] = _rd_array[i];
_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;
}
/* exception fds are currently not considered */
_sysio->select_out.fds.num_ex = unblock_ex;
return true;
@ -403,6 +404,16 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
io->register_wake_up_notifier(&notifiers[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
*/
@ -442,6 +453,11 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
io->unregister_wake_up_notifier(&notifiers[i]);
}
/*
* Unregister receptor
*/
io_receptor_registry()->unregister_receptor(&receptor);
}
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) {
return Genode::env()->heap()->alloc(size); }