base: simplify handling of session-creation errors

This patch decouples the error handling of the quota transfers
and the actual session creation. In the previous version, an error in
the 'initiate_request' phase would leave the local scope via an
exception without disarming the transfer guard objects. This way,
the guard destructors would attempt the returning of session quota in
addition to the explicit call of '_revert_quota_and_destroy' as done in
the error handling of the 'initiate_request' operation.

In the presence of a session-creation error in the 'initiate_request'
phase, session quota would eventually be returned twice. This patch
removes the intertwined error handling of both phases in a way that the
guards of the first phase (quota transfer) are no longer present in the
second phase (initiate_request).
This commit is contained in:
Norman Feske 2017-06-20 11:12:31 +02:00
parent 5566aa0f94
commit f95bfddc09

View File

@ -225,24 +225,6 @@ Session_capability Child::session(Parent::Client::Id id,
Ram_transfer ram_donation_to_service(forward_ram_quota, ref_ram_account, service);
Cap_transfer cap_donation_to_service(cap_quota, ref_cap_account, service);
/* try to dispatch session request synchronously */
service.initiate_request(session);
if (session.phase == Session_state::SERVICE_DENIED) {
_revert_quota_and_destroy(session);
throw Service_denied();
}
if (session.phase == Session_state::INSUFFICIENT_RAM_QUOTA) {
_revert_quota_and_destroy(session);
throw Insufficient_ram_quota();
}
if (session.phase == Session_state::INSUFFICIENT_CAP_QUOTA) {
_revert_quota_and_destroy(session);
throw Insufficient_cap_quota();
}
/* finish transaction */
ram_donation_from_child.acknowledge();
cap_donation_from_child.acknowledge();
@ -261,6 +243,24 @@ Session_capability Child::session(Parent::Client::Id id,
throw Out_of_caps();
}
/* try to dispatch session request synchronously */
service.initiate_request(session);
if (session.phase == Session_state::SERVICE_DENIED) {
_revert_quota_and_destroy(session);
throw Service_denied();
}
if (session.phase == Session_state::INSUFFICIENT_RAM_QUOTA) {
_revert_quota_and_destroy(session);
throw Insufficient_ram_quota();
}
if (session.phase == Session_state::INSUFFICIENT_CAP_QUOTA) {
_revert_quota_and_destroy(session);
throw Insufficient_cap_quota();
}
/*
* Copy out the session cap before we are potentially kicking off the
* asynchonous request handling at the server to avoid doule-read