base: setup parent upgrade mechanism eagerly

Fix #2447
This commit is contained in:
Stefan Kalkowski
2017-06-13 13:18:11 +02:00
committed by Christian Helmuth
parent 06b25a9082
commit 6f8dc9054a
10 changed files with 59 additions and 116 deletions

View File

@ -274,6 +274,12 @@ namespace {
Genode::call_global_static_constructors();
Genode::init_signal_transmitter(env);
/*
* Now, as signaling is available, initialize the asynchronous
* parent resource mechanism
*/
init_parent_resource_requests(env);
Component::construct(env);
}
};

View File

@ -34,47 +34,12 @@ namespace Genode {
}
static Genode::Signal_receiver *resource_sig_rec()
void Genode::init_parent_resource_requests(Genode::Env & env)
{
static Genode::Signal_receiver sig_rec;
return &sig_rec;
}
Genode::Signal_context_capability
Genode::Expanding_parent_client::_fallback_sig_cap()
{
static Signal_context _sig_ctx;
static Signal_context_capability _sig_cap;
/* create signal-context capability only once */
if (!_sig_cap.valid()) {
/*
* Because the 'manage' function consumes meta data of the signal
* session, calling it may result in an 'Out_of_ram' or 'Out_of_caps' error.
* The 'manage' function handles this error by upgrading the session quota
* accordingly. However, this upgrade, in turn, may result in the
* depletion of the process' RAM quota. In this case, the process would
* issue a resource request to the parent. But in order to do so, the
* fallback signal handler has to be constructed. To solve this
* hen-and-egg problem, we allocate a so-called emergency RAM reserve
* immediately at the startup of the process as part of the
* 'Platform_env'. When initializing the fallback signal handler, these
* resources get released in order to ensure an eventual upgrade of the
* signal session to succeed.
*
* The corner case is tested by 'os/src/test/resource_request'.
*/
_emergency_ram_reserve.release();
_sig_cap = resource_sig_rec()->manage(&_sig_ctx);
}
return _sig_cap;
}
void Genode::Expanding_parent_client::_wait_for_resource_response()
{
resource_sig_rec()->wait_for_signal();
/**
* Catch up asynchronous resource request and notification
* mechanism construction of the expanding parent environment
*/
using Parent = Expanding_parent_client;
static_cast<Parent*>(&env.parent())->init_fallback_signal_handling();
}

View File

@ -59,7 +59,7 @@ void Genode::Platform_env::reinit(Native_capability::Raw raw)
* Re-initialize 'Platform_env' members
*/
Expanding_parent_client * const p = &_parent_client;
construct_at<Expanding_parent_client>(p, parent_cap(), *this);
construct_at<Expanding_parent_client>(p, parent_cap());
construct_at<Resources>(&_resources, _parent_client);
/*