mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-21 10:01:57 +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
|
ldexp T
|
||||||
ldiv T
|
ldiv T
|
||||||
lfind T
|
lfind T
|
||||||
libc_select_notify V
|
|
||||||
link W
|
link W
|
||||||
listen T
|
listen T
|
||||||
llabs 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 */
|
/** Description for a task waiting in select */
|
||||||
struct Libc::Select_cb
|
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()
|
void Libc::Select_handler_base::dispatch_select()
|
||||||
{
|
{
|
||||||
|
Libc::select_notify_from_kernel();
|
||||||
|
|
||||||
Select_handler_cb &select_cb = *_select_cb;
|
Select_handler_cb &select_cb = *_select_cb;
|
||||||
|
|
||||||
if (select_cb->nready == 0) return;
|
if (select_cb->nready == 0) return;
|
||||||
|
@ -53,7 +53,7 @@ static void use_file_system()
|
|||||||
{
|
{
|
||||||
int result = 0;
|
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");
|
if (fd == -1) die("open");
|
||||||
|
|
||||||
printf("open returned fd %d\n", fd);
|
printf("open returned fd %d\n", fd);
|
||||||
@ -96,41 +96,6 @@ struct Log::Session_component : Genode::Rpc_object<Log_session>
|
|||||||
fd_set _exceptfds;
|
fd_set _exceptfds;
|
||||||
bool _in_read = false;
|
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)
|
void _select_ready(int nready, fd_set const &readfds, fd_set const &writefds, fd_set const &exceptfds)
|
||||||
{
|
{
|
||||||
Libc::with_libc([&] () {
|
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)
|
Session_component(Libc::Env &env) : _env(env)
|
||||||
{
|
{
|
||||||
Libc::with_libc([&] () {
|
Libc::with_libc([&] () {
|
||||||
@ -171,6 +185,8 @@ struct Log::Session_component : Genode::Rpc_object<Log_session>
|
|||||||
|
|
||||||
/* initially call read two times to ensure blocking */
|
/* initially call read two times to ensure blocking */
|
||||||
_read(); _read();
|
_read(); _read();
|
||||||
|
|
||||||
|
_select();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(String const &string_buf) override
|
void write(String const &string_buf) override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user