Remove exceptions from Pd_session interface

This patch replaces exceptions of the PD session RPC interface with
result types.
The change of the quota-transfer RPC functions required the adaptation
of base/quota_transfer.h and base/child.h.
The 'alloc_signal_source' method has been renamed to 'signal_source'
to avoid an exceedingly long name of the corresponding result type.
The Pd_session::map function takes a 'Virt_range' instead of basic-type
arguments.
The 'Signal_source_capability' alias for 'Capability<Signal_source>' has
been removed.

Issue #5245
This commit is contained in:
Norman Feske
2024-06-13 16:35:00 +02:00
parent 08066269ba
commit 0d7d60a1f4
24 changed files with 302 additions and 256 deletions

View File

@ -198,24 +198,30 @@ class Core::Pd_session_component : public Session_object<Pd_session>
bool assign_pci(addr_t, uint16_t) override;
void map(addr_t, addr_t) override;
Map_result map(Pd_session::Virt_range) override;
/****************
** Signalling **
****************/
Signal_source_capability alloc_signal_source() override
Signal_source_result signal_source() override
{
_consume_cap(SIG_SOURCE_CAP);
try { _consume_cap(SIG_SOURCE_CAP); }
catch (Out_of_caps) {
return Signal_source_error::OUT_OF_CAPS; }
Signal_source_result result = Capability<Signal_source>();
try { return _signal_broker.alloc_signal_source(); }
catch (Allocator::Out_of_memory) {
_released_cap_silent();
throw Out_of_ram();
}
catch (Out_of_ram) { result = Signal_source_error::OUT_OF_RAM; }
catch (Out_of_caps) { result = Signal_source_error::OUT_OF_CAPS; }
_released_cap_silent();
return result;
}
void free_signal_source(Signal_source_capability sig_rec_cap) override
void free_signal_source(Capability<Signal_source> sig_rec_cap) override
{
if (sig_rec_cap.valid()) {
_signal_broker.free_signal_source(sig_rec_cap);
@ -224,7 +230,7 @@ class Core::Pd_session_component : public Session_object<Pd_session>
}
Alloc_context_result
alloc_context(Signal_source_capability sig_rec_cap, Imprint imprint) override
alloc_context(Capability<Signal_source> sig_rec_cap, Imprint imprint) override
{
try {
Cap_quota_guard::Reservation cap_costs(_cap_quota_guard(), Cap_quota{1});
@ -257,14 +263,19 @@ class Core::Pd_session_component : public Session_object<Pd_session>
** RPC capability allocation **
*******************************/
Native_capability alloc_rpc_cap(Native_capability ep) override
Alloc_rpc_cap_result alloc_rpc_cap(Native_capability ep) override
{
/* may throw 'Out_of_caps' */
_consume_cap(RPC_CAP);
try { _consume_cap(RPC_CAP); }
catch (Out_of_caps) {
return Alloc_rpc_cap_error::OUT_OF_CAPS; }
/* may throw 'Out_of_ram' */
try { return _rpc_cap_factory.alloc(ep); }
catch (...) { _released_cap_silent(); throw; }
try {
return _rpc_cap_factory.alloc(ep); }
catch (...) {
_released_cap_silent();
return Alloc_rpc_cap_error::OUT_OF_RAM; }
}
void free_rpc_cap(Native_capability cap) override
@ -292,10 +303,10 @@ class Core::Pd_session_component : public Session_object<Pd_session>
** Capability and RAM trading and accounting **
***********************************************/
void ref_account(Capability<Pd_session>) override;
Ref_account_result ref_account(Capability<Pd_session>) override;
void transfer_quota(Capability<Pd_session>, Cap_quota) override;
void transfer_quota(Capability<Pd_session>, Ram_quota) override;
Transfer_cap_quota_result transfer_quota(Capability<Pd_session>, Cap_quota) override;
Transfer_ram_quota_result transfer_quota(Capability<Pd_session>, Ram_quota) override;
Cap_quota cap_quota() const override
{

View File

@ -16,7 +16,6 @@
/* core includes */
#include <signal_source_component.h>
#include <signal_source/capability.h>
#include <signal_context_slab.h>
#include <signal_delivery_proxy.h>
@ -27,12 +26,12 @@ class Core::Signal_broker
{
private:
Allocator &_md_alloc;
Rpc_entrypoint &_source_ep;
Rpc_entrypoint &_context_ep;
Signal_source_component _source;
Signal_source_capability _source_cap;
Signal_context_slab _contexts_slab { _md_alloc };
Allocator &_md_alloc;
Rpc_entrypoint &_source_ep;
Rpc_entrypoint &_context_ep;
Signal_source_component _source;
Capability<Signal_source> _source_cap;
Signal_context_slab _contexts_slab { _md_alloc };
Signal_delivery_proxy_component _delivery_proxy { _source_ep };
public:
@ -60,12 +59,12 @@ class Core::Signal_broker
free_context(r->cap());
}
Signal_source_capability alloc_signal_source() { return _source_cap; }
Capability<Signal_source> alloc_signal_source() { return _source_cap; }
void free_signal_source(Signal_source_capability) { }
void free_signal_source(Capability<Signal_source>) { }
Signal_context_capability
alloc_context(Signal_source_capability, unsigned long imprint)
alloc_context(Capability<Signal_source>, unsigned long imprint)
{
/*
* XXX For now, we ignore the signal-source argument as we

View File

@ -99,78 +99,88 @@ size_t Pd_session_component::dataspace_size(Ram_dataspace_capability ds_cap) con
}
void Pd_session_component::ref_account(Capability<Pd_session> pd_cap)
Pd_session::Ref_account_result Pd_session_component::ref_account(Capability<Pd_session> pd_cap)
{
/* the reference account can be defined only once */
if (_cap_account.constructed())
return;
return Ref_account_result::OK;
if (this->cap() == pd_cap)
return;
return Ref_account_result::OK;
Ref_account_result result = Ref_account_result::INVALID_SESSION;
_ep.apply(pd_cap, [&] (Pd_session_component *pd) {
if (!pd || !pd->_ram_account.constructed()) {
error("invalid PD session specified as ref account");
throw Invalid_session();
}
if (!pd || !pd->_ram_account.constructed())
return;
_cap_account.construct(_cap_quota_guard(), _label, *pd->_cap_account);
_ram_account.construct(_ram_quota_guard(), _label, *pd->_ram_account);
result = Ref_account_result::OK;
});
return result;
}
void Pd_session_component::transfer_quota(Capability<Pd_session> pd_cap,
Cap_quota amount)
Pd_session::Transfer_cap_quota_result
Pd_session_component::transfer_quota(Capability<Pd_session> pd_cap, Cap_quota amount)
{
if (!_cap_account.constructed())
throw Undefined_ref_account();
return Transfer_cap_quota_result::NO_REF_ACCOUNT;
if (this->cap() == pd_cap)
return;
return Transfer_cap_quota_result::OK;
Transfer_cap_quota_result result = Transfer_cap_quota_result::INVALID_SESSION;
_ep.apply(pd_cap, [&] (Pd_session_component *pd) {
if (!pd || !pd->_cap_account.constructed())
throw Invalid_session();
return;
try {
_cap_account->transfer_quota(*pd->_cap_account, amount);
diag("transferred ", amount, " caps "
"to '", pd->_cap_account->label(), "' (", _cap_account, ")");
result = Transfer_cap_quota_result::OK;
}
catch (Account<Cap_quota>::Unrelated_account) {
warning("attempt to transfer cap quota to unrelated PD session");
throw Invalid_session(); }
catch (Account<Cap_quota>::Unrelated_account) { }
catch (Account<Cap_quota>::Limit_exceeded) {
throw Out_of_caps(); }
result = Transfer_cap_quota_result::OUT_OF_CAPS;
}
});
return result;
}
void Pd_session_component::transfer_quota(Capability<Pd_session> pd_cap,
Ram_quota amount)
Pd_session::Transfer_ram_quota_result
Pd_session_component::transfer_quota(Capability<Pd_session> pd_cap, Ram_quota amount)
{
if (!_ram_account.constructed())
throw Undefined_ref_account();
return Transfer_ram_quota_result::NO_REF_ACCOUNT;
if (this->cap() == pd_cap)
return;
return Transfer_ram_quota_result::OK;
Transfer_ram_quota_result result = Transfer_ram_quota_result::INVALID_SESSION;
_ep.apply(pd_cap, [&] (Pd_session_component *pd) {
if (!pd || !pd->_ram_account.constructed())
throw Invalid_session();
return;
try {
_ram_account->transfer_quota(*pd->_ram_account, amount); }
catch (Account<Ram_quota>::Unrelated_account) {
warning("attempt to transfer RAM quota to unrelated PD session");
throw Invalid_session(); }
_ram_account->transfer_quota(*pd->_ram_account, amount);
result = Transfer_ram_quota_result::OK;
}
catch (Account<Ram_quota>::Unrelated_account) { }
catch (Account<Ram_quota>::Limit_exceeded) {
throw Out_of_ram(); }
result = Transfer_ram_quota_result::OUT_OF_RAM;
}
});
return result;
}

View File

@ -18,9 +18,14 @@
using namespace Core;
bool Pd_session_component::assign_pci(addr_t, uint16_t) { return true; }
void Pd_session_component::map(addr_t, addr_t) { }
Pd_session::Map_result Pd_session_component::map(Pd_session::Virt_range)
{
return Map_result::OK;
}
class System_control_dummy : public System_control