mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
libc: update status for component select handlers
In case of contexts blocked in select() the monitor updates the file-descriptor status, but if the entrypoint is just blocked for the select handler, the status must be updated explicitly on dispatch_select().
This commit is contained in:
parent
bbb017dc24
commit
26011a7151
@ -418,7 +418,6 @@ lcong48 T
|
||||
ldexp T
|
||||
ldiv T
|
||||
lfind T
|
||||
libc_select_notify V
|
||||
link W
|
||||
listen T
|
||||
llabs T
|
||||
|
@ -63,9 +63,6 @@ void Libc::init_select(Select &select, Signal &signal, Monitor &monitor)
|
||||
}
|
||||
|
||||
|
||||
void (*libc_select_notify)() __attribute__((weak));
|
||||
|
||||
|
||||
/** Description for a task waiting in select */
|
||||
struct Libc::Select_cb
|
||||
{
|
||||
@ -416,6 +413,8 @@ int Libc::Select_handler_base::select(int nfds, fd_set &readfds,
|
||||
|
||||
void Libc::Select_handler_base::dispatch_select()
|
||||
{
|
||||
Libc::select_notify_from_kernel();
|
||||
|
||||
Select_handler_cb &select_cb = *_select_cb;
|
||||
|
||||
if (select_cb->nready == 0) return;
|
||||
|
@ -53,7 +53,7 @@ static void use_file_system()
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
int const fd = open("/tmp/blub", O_RDWR | O_NONBLOCK | O_CREAT | O_APPEND);
|
||||
int const fd = open("/tmp/blub", O_RDWR /*| O_NONBLOCK*/ | O_CREAT | O_APPEND);
|
||||
if (fd == -1) die("open");
|
||||
|
||||
printf("open returned fd %d\n", fd);
|
||||
@ -96,41 +96,6 @@ struct Log::Session_component : Genode::Rpc_object<Log_session>
|
||||
fd_set _exceptfds;
|
||||
bool _in_read = false;
|
||||
|
||||
void _select()
|
||||
{
|
||||
int nready = 0;
|
||||
do {
|
||||
fd_set readfds = _readfds;
|
||||
fd_set writefds = _writefds;
|
||||
fd_set exceptfds = _exceptfds;
|
||||
|
||||
nready = _select_handler.select(_fd + 1, readfds, writefds, exceptfds);
|
||||
if (nready)
|
||||
_select_ready(nready, readfds, writefds, exceptfds);
|
||||
} while (nready);
|
||||
}
|
||||
|
||||
Libc::Select_handler<Session_component> _select_handler {
|
||||
*this, &Session_component::_select_ready };
|
||||
|
||||
void _read()
|
||||
{
|
||||
_in_read = true;
|
||||
|
||||
/* never mind the potentially nested with_libc */
|
||||
Libc::with_libc([&] () {
|
||||
int const result = read(_fd, _buf, sizeof(_buf)-1);
|
||||
if (result <= 0) {
|
||||
Genode::warning("read returned ", result, " in select handler");
|
||||
return;
|
||||
}
|
||||
_buf[result] = 0;
|
||||
Genode::log("read from file \"", Genode::Cstring(_buf), "\"");
|
||||
});
|
||||
|
||||
_in_read = false;
|
||||
}
|
||||
|
||||
void _select_ready(int nready, fd_set const &readfds, fd_set const &writefds, fd_set const &exceptfds)
|
||||
{
|
||||
Libc::with_libc([&] () {
|
||||
@ -154,6 +119,55 @@ struct Log::Session_component : Genode::Rpc_object<Log_session>
|
||||
});
|
||||
}
|
||||
|
||||
void _select()
|
||||
{
|
||||
/*
|
||||
* This function activates the select handler. Ready file FDs must be
|
||||
* handled immediately on return from select() as these events will not
|
||||
* unblock the entrypoint later on.
|
||||
*/
|
||||
int nready = 0;
|
||||
do {
|
||||
fd_set readfds = _readfds;
|
||||
fd_set writefds = _writefds;
|
||||
fd_set exceptfds = _exceptfds;
|
||||
|
||||
nready = _select_handler.select(_fd + 1, readfds, writefds, exceptfds);
|
||||
if (nready)
|
||||
_select_ready(nready, readfds, writefds, exceptfds);
|
||||
} while (nready);
|
||||
}
|
||||
|
||||
Libc::Select_handler<Session_component> _select_handler {
|
||||
*this, &Session_component::_handle_select };
|
||||
|
||||
void _handle_select(int nready, fd_set const &readfds, fd_set const &writefds, fd_set const &exceptfds)
|
||||
{
|
||||
/* handle all ready fds */
|
||||
_select_ready(nready, readfds, writefds, exceptfds);
|
||||
|
||||
/* reactivate select handler */
|
||||
_select();
|
||||
}
|
||||
|
||||
void _read()
|
||||
{
|
||||
_in_read = true;
|
||||
|
||||
/* never mind the potentially nested with_libc */
|
||||
Libc::with_libc([&] () {
|
||||
int const result = read(_fd, _buf, sizeof(_buf)-1);
|
||||
if (result <= 0) {
|
||||
Genode::warning("read returned ", result, " in select handler");
|
||||
return;
|
||||
}
|
||||
_buf[result] = 0;
|
||||
Genode::log("read from file \"", Genode::Cstring(_buf), "\"");
|
||||
});
|
||||
|
||||
_in_read = false;
|
||||
}
|
||||
|
||||
Session_component(Libc::Env &env) : _env(env)
|
||||
{
|
||||
Libc::with_libc([&] () {
|
||||
@ -171,6 +185,8 @@ struct Log::Session_component : Genode::Rpc_object<Log_session>
|
||||
|
||||
/* initially call read two times to ensure blocking */
|
||||
_read(); _read();
|
||||
|
||||
_select();
|
||||
}
|
||||
|
||||
void write(String const &string_buf) override
|
||||
|
Loading…
x
Reference in New Issue
Block a user