From f95bfddc09113a83d8b1f1c2faecaa41d957079f Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Tue, 20 Jun 2017 11:12:31 +0200 Subject: [PATCH] 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). --- repos/base/src/lib/base/child.cc | 36 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/repos/base/src/lib/base/child.cc b/repos/base/src/lib/base/child.cc index 38cac8c134..c5e209dab1 100644 --- a/repos/base/src/lib/base/child.cc +++ b/repos/base/src/lib/base/child.cc @@ -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