mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-25 16:31:06 +00:00
libc: cancel select when POSIX signal occurs
With this patch, Vim running via the 'bash.run' script becomes able to adopt itself to changed window dimensions. Issue #3544
This commit is contained in:
parent
fafa409cf9
commit
636e0f6444
@ -65,7 +65,7 @@ namespace Libc {
|
|||||||
/**
|
/**
|
||||||
* Select support
|
* Select support
|
||||||
*/
|
*/
|
||||||
void init_select(Suspend &, Resume &, Select &);
|
void init_select(Suspend &, Resume &, Select &, Signal &);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Support for querying available RAM quota in sysctl functions
|
* Support for querying available RAM quota in sysctl functions
|
||||||
|
@ -347,7 +347,7 @@ Libc::Kernel::Kernel(Genode::Env &env, Genode::Allocator &heap)
|
|||||||
init_sleep(*this);
|
init_sleep(*this);
|
||||||
init_vfs_plugin(*this);
|
init_vfs_plugin(*this);
|
||||||
init_time(*this, _rtc_path, *this);
|
init_time(*this, _rtc_path, *this);
|
||||||
init_select(*this, *this, *this);
|
init_select(*this, *this, *this, _signal);
|
||||||
init_socket_fs(*this);
|
init_socket_fs(*this);
|
||||||
init_passwd(_passwd_config());
|
init_passwd(_passwd_config());
|
||||||
init_signal(_signal);
|
init_signal(_signal);
|
||||||
|
@ -36,9 +36,11 @@
|
|||||||
|
|
||||||
/* libc-internal includes */
|
/* libc-internal includes */
|
||||||
#include <internal/init.h>
|
#include <internal/init.h>
|
||||||
|
#include <internal/signal.h>
|
||||||
#include <internal/suspend.h>
|
#include <internal/suspend.h>
|
||||||
#include <internal/resume.h>
|
#include <internal/resume.h>
|
||||||
#include <internal/select.h>
|
#include <internal/select.h>
|
||||||
|
#include <internal/errno.h>
|
||||||
|
|
||||||
namespace Libc {
|
namespace Libc {
|
||||||
struct Select_cb;
|
struct Select_cb;
|
||||||
@ -48,16 +50,19 @@ namespace Libc {
|
|||||||
using namespace Libc;
|
using namespace Libc;
|
||||||
|
|
||||||
|
|
||||||
static Suspend *_suspend_ptr;
|
static Suspend *_suspend_ptr;
|
||||||
static Resume *_resume_ptr;
|
static Resume *_resume_ptr;
|
||||||
static Select *_select_ptr;
|
static Select *_select_ptr;
|
||||||
|
static Libc::Signal *_signal_ptr;
|
||||||
|
|
||||||
|
|
||||||
void Libc::init_select(Suspend &suspend, Resume &resume, Select &select)
|
void Libc::init_select(Suspend &suspend, Resume &resume, Select &select,
|
||||||
|
Signal &signal)
|
||||||
{
|
{
|
||||||
_suspend_ptr = &suspend;
|
_suspend_ptr = &suspend;
|
||||||
_resume_ptr = &resume;
|
_resume_ptr = &resume;
|
||||||
_select_ptr = &select;
|
_select_ptr = &select;
|
||||||
|
_signal_ptr = &signal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -312,18 +317,38 @@ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
|
|||||||
|
|
||||||
{
|
{
|
||||||
struct Missing_call_of_init_select : Exception { };
|
struct Missing_call_of_init_select : Exception { };
|
||||||
if (!_suspend_ptr)
|
if (!_suspend_ptr || !_signal_ptr)
|
||||||
throw Missing_call_of_init_select();
|
throw Missing_call_of_init_select();
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!timeout.expired() && select_cb->nready == 0)
|
unsigned const orig_signal_count = _signal_ptr->count();
|
||||||
|
|
||||||
|
auto signal_occurred_during_select = [&] ()
|
||||||
|
{
|
||||||
|
return _signal_ptr->count() != orig_signal_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
if (timeout.expired())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (select_cb->nready != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (signal_occurred_during_select())
|
||||||
|
break;
|
||||||
|
|
||||||
timeout.duration = _suspend_ptr->suspend(check, timeout.duration);
|
timeout.duration = _suspend_ptr->suspend(check, timeout.duration);
|
||||||
|
}
|
||||||
|
|
||||||
select_cb_list().remove(&(*select_cb));
|
select_cb_list().remove(&(*select_cb));
|
||||||
|
|
||||||
if (timeout.expired())
|
if (timeout.expired())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (signal_occurred_during_select())
|
||||||
|
return Errno(EINTR);
|
||||||
|
|
||||||
/* not timed out -> results have been stored in select_cb by select_notify() */
|
/* not timed out -> results have been stored in select_cb by select_notify() */
|
||||||
|
|
||||||
if (readfds) *readfds = select_cb->readfds;
|
if (readfds) *readfds = select_cb->readfds;
|
||||||
|
Loading…
Reference in New Issue
Block a user